您的位置:首页 > 其它

昨天看书的心得

2005-03-30 08:55 260 查看
昨天做图像算法,总觉得YIQ色彩和RGB之间通过相互转换就能得到颜色的灰度值。

如果得到一个RGB的灰度值,就能进行灰度变换。图像增强基本都是基于灰度做出来的。

 void RGB2YIQ(REAL *y, REAL *i, REAL*q, BYTE r, BYTE g, BYTE b);

 void YIQ2RGB(BYTE *r, BYTE *g, BYTE *b, REAL y, REAL i, REAL q);

REAL RGB2YIQMat[3][3] =

        {{ 0.30f,  0.59f,  0.11f},

         { 0.60f, -0.28f, -0.32f},

         { 0.21f, -0.52f,  0.31f}};

REAL YIQ2RGBMat[3][3] = 

        {{ 1.0000f,  0.9483f,  0.6240f},

         { 1.0000f, -0.2761f, -0.6398f},

         { 1.0000f, -1.1055f,  1.7299f}};

/*Converts r, g, b, into y, i, q*/

void CImpactPlus::RGB2YIQ(REAL *y, REAL *i, REAL*q, BYTE r, BYTE g, BYTE b)

{

    REAL rT, gT, bT;

    rT = r / 255.0f; gT = g / 255.0f; bT = b / 255.0f;

    *y = RGB2YIQMat[0][0] * rT + RGB2YIQMat[0][1] * gT + RGB2YIQMat[0][2] * bT; 

    *i = RGB2YIQMat[1][0] * rT + RGB2YIQMat[1][1] * gT + RGB2YIQMat[1][2] * bT; 

    *q = RGB2YIQMat[2][0] * rT + RGB2YIQMat[2][1] * gT + RGB2YIQMat[2][2] * bT;

    *i = (*i + 0.6f) / 1.2f;

    *q = (*q + 0.52f) / 1.04f;

    if (*y < 0.0) *y = 0.0f;

    if (*y > 1.0) *y = 1.0f;

    if (*i < 0.0) *i = 0.0f;

    if (*i > 1.0) *i = 1.0f;

    if (*q < 0.0) *q = 0.0f;

    if (*q > 1.0) *q = 1.0f;

}

/*Converts y, i, q, into r, g, b*/

void CImpactPlus::YIQ2RGB(BYTE *r, BYTE *g, BYTE *b, REAL y, REAL i, REAL q)

{

    REAL rT, gT, bT;

    i = i * 1.2f - 0.6f;

    q = q * 1.04f - 0.52f;

    rT = YIQ2RGBMat[0][0] * y + YIQ2RGBMat[0][1] * i + YIQ2RGBMat[0][2] * q; 

    gT = YIQ2RGBMat[1][0] * y + YIQ2RGBMat[1][1] * i + YIQ2RGBMat[1][2] * q; 

    bT = YIQ2RGBMat[2][0] * y + YIQ2RGBMat[2][1] * i + YIQ2RGBMat[2][2] * q;

    if (rT < 0.0f) rT = 0.0f;

    if (rT > 1.0f) rT = 1.0f;

    if (gT < 0.0f) gT = 0.0f;

    if (gT > 1.0f) gT = 1.0f;

    if (bT < 0.0f) bT = 0.0f;

    if (bT > 1.0f) bT = 1.0f;

    *r = max(0, min(255, (BYTE)(rT * 255.0f)));

    *g = max(0, min(255, (BYTE)(gT * 255.0f)));

    *b = max(0, min(255, (BYTE)(bT * 255.0f)));

}

在数字图像处理的书中,经常有这样的程序:

  PixelValue = (BYTE)(0.299*(float)lpDIBBits[p+2] + 0.587*(float)lpDIBBits[p+1]+0.114*(float)lpDIBBits[p]+0.1;

这行程序的意思是:得到当前像素的YIQ之Y值。

而lpDIBBits[p+2]就是红色成分, lpDIBBits[p+1]是绿色成分, lpDIBBits[p]是蓝色成分。

唯一不明白的是他为什么要加0.1?

下面是我依照他的原理来实现图像的线性灰度变换。

Status CImpactPlus::LinerTrans(Bitmap* pBitmap, float fa, float fb)

{

 Status s;

 TestGdiPointer(_T("HistogramEqual"), pBitmap);

 

 
 INT nWidth = pBitmap->GetWidth();

 INT nHeight = pBitmap->GetHeight();
 BitmapData bitmapData;

 Rect rt(0, 0, nWidth, nHeight);

 if(StatusBad(s = pBitmap->LockBits(&rt,

  ImageLockModeRead | ImageLockModeWrite,

  PixelFormat32bppARGB, &bitmapData)))

 

 return SGTRACE_ERR(_T("LockBits"), s);

 ARGB* pixels = (ARGB*)bitmapData.Scan0;

 

 float fy, fi, fq;

 fy = fi = fq = 0.0f;

 BYTE a, r, g, b;

 for(int row=rt.Y; row<rt.Height; row++)

 {

  for(int col=rt.X; col<rt.Width; col++)

  {

   ARGB c = pixels[row * bitmapData.Stride / 4 + col];

   Color color(c);

   a = color.GetA();

   r = color.GetR();

   g = color.GetG();

   b = color.GetB();

   

   RGB2YIQ(&fy, &fi, &fq, r, g, b);

   float fTemp = fa * fy + fb;

   YIQ2RGB(&r, &g, &b, fTemp, fi, fq);

   

   pixels[row * bitmapData.Stride / 4 + col] = color.MakeARGB(a,r,g,b);

  }

 }

 if(StatusBad(s = pBitmap->UnlockBits(&bitmapData)))

  return SGTRACE_ERR(_T("UnlockBits"), s);

 return Ok;

}

这样方法简单明快,即使是很复杂的算法,实现起来也很清晰。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: