图像的灰度与二值化

it2022-05-16  74

    图像的灰度化与二值化是图像处理中最常见的处理方法,也是很多图像处理方法的基础,如图像灰度统计、图像识别等。

    图像的灰度化与二值化方法较多,处理过程也比较简单。但切不可因其简单而忽视效率。如常用的图像灰度计算公式:gray = red * 0.299 + green * 0.587 + blue * 0.114,如果在程序代码中直接套用了这个公式,因浮点数的缘故导致代码执行效率较低,如改为定点整数运算,可使执行效率大大提高。

    下面是图像的灰度与二值化代码:

//  定义ARGB像素结构 typedef union {     ARGB Color;      struct     {         BYTE Blue;         BYTE Green;         BYTE Red;         BYTE Alpha;     }; }ARGBQuad, *PARGBQuad; // --------------------------------------------------------------------------- //  图像数据data灰度化 VOID Gray(BitmapData *data) {     PARGBQuad p = (PARGBQuad)data->Scan0;     INT offset = data->Stride - data->Width *  sizeof(ARGBQuad);      for (UINT y =  0; y < data->Height; y ++, (BYTE*)p += offset)     {          for (UINT x =  0; x < data->Width; x ++, p ++)             p->Blue = p->Green = p->Red =                 (UINT)(p->Blue *  29 + p->Green *  150 + p->Red *  77 +  128) >>  8;     } } // --------------------------------------------------------------------------- //  图像数据data灰度同时二值化,threshold阀值 VOID GrayAnd2Values(BitmapData *data, BYTE threshold) {     PARGBQuad p = (PARGBQuad)data->Scan0;     INT offset = data->Stride - data->Width *  sizeof(ARGBQuad);      for (UINT y =  0; y < data->Height; y ++, (BYTE*)p += offset)     {          for (UINT x =  0; x < data->Width; x ++, p ++)         {              if (((p->Blue *  29 + p->Green *  150 + p->Red *  77 +  128) >>  8) < threshold)                 p->Color &=  0xff000000;              else                 p->Color |=  0x00ffffff;         }     } } // ---------------------------------------------------------------------------

    因本文使用的是32位图像数据,所以图像的二值化没有采用通常的赋值操作p->Blue = p->Green = p->Red = 0(或者255),而是采用了位运算。

    下面是使用BCB2007和GDI+图像数据实现图像灰度和二值化的例子代码:

//  锁定GDI+位位图扫描线到data FORCEINLINE VOID LockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data) {     Gdiplus::Rect r( 00, bmp->GetWidth(), bmp->GetHeight());     bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite,         PixelFormat32bppARGB, data); } // --------------------------------------------------------------------------- //  GDI+位图扫描线解锁 FORCEINLINE VOID UnlockBitmap(Gdiplus::Bitmap *bmp, BitmapData *data) {     bmp->UnlockBits(data); } // --------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) {     Gdiplus::Bitmap *bmp =   new Gdiplus::Bitmap(L " d:\\source1.jpg ");     Gdiplus::Graphics *g =  new Gdiplus::Graphics(Canvas->Handle);     g->DrawImage(bmp,  00);     BitmapData data;     LockBitmap(bmp, &data); //     Gray(&data);     GrayAnd2Values(&data,  128);     UnlockBitmap(bmp, &data);     g->DrawImage(bmp, data.Width,  0);     delete g;     delete bmp; } // ---------------------------------------------------------------------------

    如有错误或者建议,请来信指导:maozefa@hotmail.com

 

转载于:https://www.cnblogs.com/maozefa/archive/2011/12/09/2281656.html


最新回复(0)