1、图像灰度化处理的实现delphi 图像处理学习 2008-07-22 18:43 阅读 153 评论 0 字号: 大 中 小 一、 图像的灰度化处理的基本原理将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。彩色图像中的每个像素的颜色有 R、G、B三个分量决定,而每个分量有 255 中值可取,这样一个像素点可以有1600 多万(255*255*255)的颜色的变化范围。而灰度图像是 R、G、B 三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各 种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。灰度图像的描述与彩色图像一样仍然反映了
2、整幅图像的整体和局部的色度和亮度等级的分布和特征。图像的灰度化处理可用两种方法来实现。第一种方法使求出每个像素点的 R、G、B 三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。第二种方法是根据 YUV 的颜色空间中,Y 的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和 YUV 颜色空间的变 化关系可建立亮度 Y 与R、G、B 三个颜色分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。二、 用 Delphi 进行图像灰度化的实现:procedure TForm1.BitBtn1Click(Sender: TObject);varp:PByte
3、Array;/PByteArray的定义格式/PByteArray = TByteArray;/TByteArray = array032767 of Byte;ChangedBmp : Tbitmap;gray,x,y:integer;TestBMP : Tbitmap; / 处理过程中位图beginTestBMP:=Tbitmap.Create;ChangedBmp:=Tbitmap.Create;TestBMP.Assign(image1.Picture);for y := 0 to TestBMP.Height - 1 dobegin/获取每一行象素信息p := TestBMP.sca
4、nliney;for x := 0 to TestBMP.Width - 1 dobegin/这里采用 YUV 与 RGB 颜色空间变换的方法,即 Y0.3R+0.59G+0.11BGray := Round(p3 * x + 2 * 0.3 + p3 * x + 1 * 0.59+ p3 * x * 0.11);/由于是 24位真彩色,故一个像素点为三个字节p3 * x + 2 := byte(Gray);p3 * x + 1 := byte(Gray);p3 * x := byte(Gray);/Gray 的值必须在 0255 之间end;ChangedBmp.Assign(TestBMP
5、);PaintBox1.Canvas.CopyMode:=srccopy;PaintBox1.Canvas.Draw(0,0,ChangedBmp);/用 PaintBox 控件重新绘制图像;end;三、注意事项:程序申请了TestBMP、WillbeChangedBmp ,所以在程序初始化的时候,要注意创建:TestBMP:=Tbitmap.Create;ChangedBmp:=Tbitmap.Create;程序结束后注意要把 TestBMP.Destory 和 ChangedBmp.Destory;四、程序效果:值得一提的是,如果用 QQ截图,效果就有很大差别,不知道为什么.下面是 QQ截
6、图的效果图像的二值化的基本原理delphi 图像处理学习 2008-07-22 21:01 阅读 28 评论 0 字号: 大 中 小 图像的二值化处理就是讲图像上的点的灰度置为 0 或 255,也就是讲整个图像呈现出明显的黑白效果。即将 256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为 0 或255 的点的位置
7、有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255 表示,否则这些像素点被排除在物体区域以外,灰度值为 0,表示背景或者例外的物体区域。如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。2、
8、图像的二值化的程序实现通过 Delphi 刻度控件调整阀值,实现动态控制,程序如下:vprocedure TForm1.Button1Click(Sender: TObject);var p:PByteArray;/PByteArray的定义格式/PByteArray = TByteArray;/TByteArray = array032767 of Byte;ChangedBmp : Tbitmap;gray,x,y:integer;TestBMP : Tbitmap; / 处理过程中位图beginTestBMP:=TBitmap.Create; changedbmp:=tbitmap.Cr
9、eate;testbmp.Assign(image1.Picture);for y:=0 to testbmp.Height-1 dobeginp:=testbmp.ScanLiney;for x:=0 to testbmp.Width-1 dobegin /首先将图像灰度化gray:=round(px*3+2*0.3+px*3+1*0.59+px*3*0.11);if gray TrackBar1.Position then /按阀值进行二值化beginpx*3:=255; px*3+1:=255; px*3+2:=255;endelsebeginpx*3:=0;px*3+1:=0;px*3
10、+2:=0;end;end;end;ChangedBmp.Assign(TestBMP);PaintBox1.Canvas.CopyMode:=srccopy;PaintBox1.Canvas.Draw(0,0,ChangedBmp);end;效果:256 色和24 位真彩BMP 图像灰度化2009 年05 月 10日 星期日 下午 09:59/* 函数名称: Convert256toGray(LPSTR lpDIB,LPSTR lpDIBBits,long lWidth,long lHeight)* 参数: LPSTR lpDIB 指向 dib的指针LPSTR lpDIBBits 指向 di
11、b数据的指针long lWidth 图像宽度long lHeight 图像高度* 返回值: bool * 功能: 将 256 色位图转化为灰度图*/bool Convert256toGray(LPSTR lpDIB,LPSTR lpDIBBits,long lWidth,long lHeight) BYTE * lpSrc; / 指向 DIB象素的指针 LONG lLineBytes; / 图像每行的字节数LPBITMAPINFO lpbmi; / 指向 BITMAPINFO 结构的指针(Win3.0) LPBITMAPCOREINFO lpbmc; / 指向 BITMAPCOREINFO 结
12、构的指针 lpbmi = (LPBITMAPINFO)lpDIB; / 获取指向 BITMAPINFO 结构的指针(Win3.0) lpbmc = (LPBITMAPCOREINFO)lpDIB; / 获取指向BITMAPCOREINFO 结构的指针BYTE bMap256; / 灰度映射表/ 计算灰度映射表(保存各个颜色的灰度值),并更新 DIB 调色板int i,j;for (i = 0; i bmiColorsi.rgbRed +0.587 * lpbmi-bmiColorsi.rgbGreen +0.114 * lpbmi-bmiColorsi.rgbBlue +0.5); */bMa
13、pi = (BYTE)(306 * lpbmi-bmiColorsi.rgbRed +601 * lpbmi-bmiColorsi.rgbGreen +117 * lpbmi-bmiColorsi.rgbBlue + 512) 10 ); /修改后的优化算法/ 更新 DIB调色板红色分量lpbmi-bmiColorsi.rgbRed = i; / 更新 DIB调色板绿色分量lpbmi-bmiColorsi.rgbGreen = i; / 更新 DIB调色板蓝色分量lpbmi-bmiColorsi.rgbBlue = i;/ 更新 DIB调色板保留位lpbmi-bmiColorsi.rgbRes
14、erved = 0;/ 计算图像每行的字节数lLineBytes = WIDTHBYTES(lWidth * 8);/ 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)/逐行扫描for(i = 0; i biSize;int dwData = lpDIBHdr-biSizeImage;int dwGrayData = dwData/3;int dwGrayPal = 256 * sizeof(RGBQUAD);dwData=(lpDIBHdr-biHeight) * (lpDIBHdr-biWidth); int sizeTotal=dwInfo+dwGrayPal+dwData; /灰度
15、图,颜色表长度为 255HGLOBAL hGray=(HGLOBAL):GlobalAlloc(GMEM_MOVEABLE |GMEM_ZEROINIT, sizeTotal);if (hGray=0)return false; /内存分配失败则返回 falselpGray = (LPSTR) :GlobalLock(hGray);/ 创建灰度图的颜色表 计算每个像素点的灰度值,即求平均即可RGBQUAD* lpGrayRgbQuag=(RGBQUAD*)(lpGray+lpDIBHdr-biSize);char * lpBits = lpDIB + lpDIBHdr-biSize ;int
16、rowLenSr=WIDTHBYTES(24*lpDIBHdr-biWidth);int rowLenDes=WIDTHBYTES(8*lpDIBHdr-biWidth);BYTE * lpGrayBits = (BYTE*)(lpGrayRgbQuag)+dwGrayPal;int aver=0;int i,j,k;if(24=lpDIBHdr-biBitCount) for(i=0;irgbBlue=i;lpGrayRgbQuag-rgbGreen=i;lpGrayRgbQuag-rgbRed=i;lpGrayRgbQuag-rgbReserved=0;lpGrayRgbQuag+;for
17、 (i=0;ibiHeight;i+)for (j=0; jbiWidth; j+)k=i*rowLenSr+3*j;/*lpGrayBitsi*rowLenDes+j=(BYTE)(0.114*lpBitsk+0.587*lpBitsk+1+0.299*lpBitsk+2 + 0.5);*/lpGrayBitsi*rowLenDes+j=(BYTE) ( 117 * lpBitsk+ 601* lpBitsk+1+ 306* lpBitsk+2 + 512 ) 10 ); /修改后的优化算法/修正需要补零的像素行for (j=lpDIBHdr-biWidth;jbiSizeImage=siz
18、eTotal;lpGrayHdr-biBitCount=8;lpGrayHdr-biClrUsed=256;:GlobalUnlock( hGray );return (HGLOBAL) hGray;彩色图像灰度化 在 RGB 模型中,如果 R=G=B 时,则彩色表示一种灰度颜色,其中 R=G=B 的值叫灰度值,因此,灰度图像每个像素只需一个字节存放灰度值(又称强度值、亮度值),灰度范围为0-255。一般有以下四种方法对彩色图像进行灰度化:1.分量法将彩色图像中的三分量的亮度作为三个灰度图像的灰度值,可根据应用需要选取一种灰度图像。f1(i,j)=R(i,j) f2(i,j)=G(i,j) f
19、3(i,j)=B(i,j)其中 fk(i,j)(k=1,2,3)为转换后的 灰度图像在(i,j )处的灰度值。如图 4-1 的彩色图像转为 4-2 三种灰度图。图 4-1 彩色图像 (a)R 分量灰度图 (b)G 分量灰度图 (c)B 分量灰度图图 4-2 彩色图的三分量灰度图2.最大值法将彩色图像中的三分量亮度的最大值作为灰度图的灰度值。f(i,j)=max(R(i,j),G(i,j),B(i,j)3.平均值法将彩色图像中的三分量亮度求平均得到一个灰度图。f(i,j)=(R(i,j)+G(i,j)+B(i,j) /34.加权平均法根据重要性及其它指标,将三个分量以不同的权值进行加权平均。由于
20、人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对 RGB 三分量进行加权平均能得到较合理的灰度图像。f(i,j)=0.11R(i,j)+0.59G(i,j)+0.3B(i,j)如何用 C 语言对彩色图像进行二值化?想先是一副彩色图像变成灰度图像,再设定阈值对其进行二值#include #include #include #pragma pack(1)#define R 30#define G 59#define B 11#define ONE 255 #define ZERO 0 typedef unsigned short WORD;typedef unsigned long DWORD
21、;typedef long LONG;typedef unsigned char BYTE;typedef struct tagBITMAPFILEHEADER / bmfh WORD bfType; / 位图文件的 类型,必须为 BMDWORD bfSize; / 位图文件的大小,以字节为单位WORD bfReserved1; / 位图文件保留字,必须为 0WORD bfReserved2; / 位图文件保留字,必须为 0DWORD bfOffBits; / 位图数据的 起始位置,以相对于位图文件头的偏移量表示,以字节为单位 BITMAPFILEHEADER; typedef struct
22、tagBITMAPINFOHEADER / bmih DWORD biSize; / 本结构所占 用字节数LONG biWidth; / 位图的宽度,以像素为单位LONG biHeight; / 位图的高度,以像素为单位WORD biPlanes; / 目标设备的 级别,必须为 1WORD biBitCount;/ 每个像素所需的位数,必须是 1(双色),4(16 色) ,8(256 色)或 24(真彩色)之一DWORD biCompression; / 位图压缩类型,必须是 0(不压缩),1(BI_RL E8 压缩类型)或2(BI_RLE4 压缩类型)之一DWORD biSizeImage;
23、 / 位图的大小,以字节为单位LONG biXPelsPerMeter; / 位图水平分辨率,每米像素数LONG biYPelsPerMeter; / 位图垂直分辨率,每米像素数DWORD biClrUsed;/ 位图实际使用的颜色表中的颜色数DWORD biClrImportant;/ 位图显示过程中重要的颜色数 BITMAPINFOHEADER; typedef struct tagPOINTBYTE b;BYTE g;BYTE r; POINT;int quit();int quit()puts(“Files format wrong“);exit(0);void main (int argc,char *argv) FILE *fi,*fo;/I/O file char fin80,fon80;/I/O file name BYTE buff,o=0;BITMAPFILEHEADER bf;BITMAPINFOHEADER bi;POINT *p;int i,j,t; if(argcr*R+(*(p+i)+j)-g*G+(*(p+i)+j)-b*B)/100;buff=(buff=t?ONE:ZERO)fwrite(fclose(fo);