木感想

常常思索 没有结果 来来去去 依稀记得

导航

昨天看书的心得

昨天做图像算法,总觉得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;
}

这样方法简单明快,即使是很复杂的算法,实现起来也很清晰。



posted on 2005-03-30 08:55  跌跌撞撞  阅读(878)  评论(1)    收藏  举报