图像灰度化处理的实现.docx
《图像灰度化处理的实现.docx》由会员分享,可在线阅读,更多相关《图像灰度化处理的实现.docx(17页珍藏版)》请在冰豆网上搜索。
图像灰度化处理的实现
图像灰度化处理的实现
delphi图像处理学习 2008-07-2218:
43 阅读153 评论0
字号:
大大 中中 小小
一、图像的灰度化处理的基本原理
将彩色图像转化成为灰度图像的过程成为图像的灰度化处理。
彩色图像中的每个像素的颜色有R、G、B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围。
而灰度图像是R、G、B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些。
灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征。
图像的灰度化处理可用两种方法来实现。
第一种方法使求出每个像素点的R、G、B三个分量的平均值,然后将这个平均值赋予给这个像素的三个分量。
第二种方法是根据YUV的颜色空间中,Y的分量的物理意义是点的亮度,由该值反映亮度等级,根据RGB和YUV颜色空间的变化关系可建立亮度Y与R、G、B三个颜色分量的对应:
Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值。
二、用Delphi进行图像灰度化的实现:
procedureTForm1.BitBtn1Click(Sender:
TObject);
var
p:
PByteArray;
//PByteArray的定义格式
//PByteArray=^TByteArray;
//TByteArray=array[0..32767]ofByte;
ChangedBmp:
Tbitmap;
gray,x,y:
integer;
TestBMP:
Tbitmap; //处理过程中位图
begin
TestBMP:
=Tbitmap.Create;
ChangedBmp:
=Tbitmap.Create;
TestBMP.Assign(image1.Picture);
fory:
=0toTestBMP.Height-1do
begin
//获取每一行象素信息
p:
=TestBMP.scanline[y];
forx:
=0toTestBMP.Width-1do
begin
//这里采用YUV与RGB颜色空间变换的方法,即Y=0.3R+0.59G+0.11B
Gray:
=Round(p[3*x+2]*0.3+p[3*x+1]*0.59
+p[3*x]*0.11);
//由于是24位真彩色,故一个像素点为三个字节
p[3*x+2]:
=byte(Gray);
p[3*x+1]:
=byte(Gray);
p[3*x]:
=byte(Gray);
//Gray的值必须在0~255之间
end;
ChangedBmp.Assign(TestBMP);
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截图的效果
图像的二值化的基本原理
delphi图像处理学习 2008-07-2221:
01 阅读28 评论0
字号:
大大 中中 小小
图像的二值化处理就是讲图像上的点的灰度置为0或255,也就是讲整个图像呈现出明显的黑白效果。
即将256个亮度等级的灰度图像通过适当的阀值选取而获得仍然可以反映图像整体和局部特征的二值化图像。
在数字图像处理中,二值图像占有非常重要的地位,特别是在实用的图像处理中,以二值图像处理实现而构成的系统是很多的,要进行二值图像的处理与分析,首先要把灰度图像二值化,得到二值化图像,这样子有利于再对图像做进一步处理时,图像的集合性质只与像素值为0或255的点的位置有关,不再涉及像素的多级值,使处理变得简单,而且数据的处理和压缩量小。
为了得到理想的二值图像,一般采用封闭、连通的边界定义不交叠的区域。
所有灰度大于或等于阀值的像素被判定为属于特定物体,其灰度值为255表示,否则这些像素点被排除在物体区域以外,灰度值为0,表示背景或者例外的物体区域。
如果某特定物体在内部有均匀一致的灰度值,并且其处在一个具有其他等级灰度值的均匀背景下,使用阀值法就可以得到比较的分割效果。
如果物体同背景的差别表现不在灰度值上(比如纹理不同),可以将这个差别特征转换为灰度的差别,然后利用阀值选取技术来分割该图像。
动态调节阀值实现图像的二值化可动态观察其分割图像的具体结果。
2、图像的二值化的程序实现
通过Delphi刻度控件调整阀值,实现动态控制,程序如下:
vprocedureTForm1.Button1Click(Sender:
TObject);
var
p:
PByteArray;
//PByteArray的定义格式
//PByteArray=^TByteArray;
//TByteArray=array[0..32767]ofByte;
ChangedBmp:
Tbitmap;
gray,x,y:
integer;
TestBMP:
Tbitmap; //处理过程中位图
begin
TestBMP:
=TBitmap.Create;changedbmp:
=tbitmap.Create;
testbmp.Assign(image1.Picture);
fory:
=0totestbmp.Height-1do
begin
p:
=testbmp.ScanLine[y];
forx:
=0totestbmp.Width-1do
begin //首先将图像灰度化
gray:
=round(p[x*3+2]*0.3+p[x*3+1]*0.59+p[x*3]*0.11);
ifgray>TrackBar1.Positionthen//按阀值进行二值化
begin
p[x*3]:
=255;p[x*3+1]:
=255;p[x*3+2]:
=255;
end
else
begin
p[x*3]:
=0;p[x*3+1]:
=0;p[x*3+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(LPSTRlpDIB,LPSTRlpDIBBits,
long lWidth,long lHeight)
*参数:
LPSTRlpDIB 指向dib的指针
LPSTRlpDIBBits 指向dib数据的指针
long lWidth 图像宽度
long lHeight 图像高度
*返回值:
bool
*功能:
将256色位图转化为灰度图
*
*******************************************************
********/
boolConvert256toGray(LPSTRlpDIB,LPSTRlpDIBBits,
long lWidth,long lHeight)
{
BYTE*lpSrc;//指向DIB象素的指针
LONGlLineBytes; //图像每行的字节数
LPBITMAPINFOlpbmi; //指向BITMAPINFO结构的指针(Win3.0
)
LPBITMAPCOREINFOlpbmc; //指向BITMAPCOREINFO结构的指
针
lpbmi=(LPBITMAPINFO)lpDIB;//获取指向BITMAPINFO结构的指
针(Win3.0)
lpbmc=(LPBITMAPCOREINFO)lpDIB;//获取指向
BITMAPCOREINFO结构的指针
BYTEbMap[256]; //灰度映射表
//计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
inti,j;
for(i=0;i<256;i++)
{
//计算该颜色对应的灰度值
/*
bMap[i]=(BYTE)(0.299*lpbmi->bmiColors[i].rgbRed+
0.587*lpbmi->bmiColors[i].rgbGreen+
0.114*lpbmi->bmiColors[i].rgbBlue+
0.5);
*/
bMap[i]=(BYTE)((306*lpbmi->bmiColors[i].rgbRed+
601*lpbmi->bmiColors[i].rgbGreen+
117*lpbmi->bmiColors[i].rgbBlue+512)
>>10); //修改后的优化算法
//更新DIB调色板红色分量
lpbmi->bmiColors[i].rgbRed=i;
//更新DIB调色板绿色分量
lpbmi->bmiColors[i].rgbGreen=i;
//更新DIB调色板蓝色分量
lpbmi->bmiColors[i].rgbBlue=i;
//更新DIB调色板保留位
lpbmi->bmiColors[i].rgbReserved=0;
}
//计算图像每行的字节数
lLineBytes=WIDTHBYTES(lWidth*8);
//更换每个象素的颜色索引(即按照灰度映射表换成灰度值)
//逐行扫描
for(i=0;i{
//逐列扫描
for(j=0;j{
//指向DIB第i行,第j个象素的指针
lpSrc=(unsignedchar*)lpDIBBits
+lLineBytes*(lHeight-1-i)+j;
//变换
*lpSrc=bMap[*lpSrc];
}
}
returntrue;
}
/*******************************************************
******************
*函数名称:
Gray24Bits(LPSTRlpDIB)
*函数类型:
HGLOBAL
*参数:
LPSTRlpDIB 指向dib的指针
*函数功能:
灰度化24位真彩图像
*******************************************************
******************/
HGLOBALGray24Bits(LPSTRlpDIB)
{
LPBITMAPINFOHEADERlpDIBHdr; //指向
BITMAPINFOHEADER的指针
lpDIBHdr=(LPBITMAPINFOHEADER)lpDIB;
LPSTRlpGray;
//计算位图图的信息头、调色板和图形数据的大小,并给灰度图分
配内存
intdwInfo=lpDIBHdr->biSize;
intdwData=lpDIBHdr->biSizeImage;
intdwGrayData=dwData/3;
intdwGrayPal=256*sizeof(RGBQUAD);
dwData=(lpDIBHdr->biHeight)*(lpDIBHdr->biWidth);
intsizeTotal=dwInfo+dwGrayPal+dwData; //灰度图,颜色
表长度为255
HGLOBALhGray=(HGLOBAL):
:
GlobalAlloc(GMEM_MOVEABLE|
GMEM_ZEROINIT,sizeTotal);
if(hGray==0)
{
returnfalse;//内存分配失败则返回false
}
lpGray=(LPSTR):
:
GlobalLock(hGray);
//创建灰度图的颜色表计算每个像素点的灰度值,即求平均即可
RGBQUAD*lpGrayRgbQuag=(RGBQUAD*)(lpGray+lpDIBHdr-
>biSize);
char*lpBits=lpDIB+lpDIBHdr->biSize;
introwLenSr=WIDTHBYTES(24*lpDIBHdr->biWidth);
introwLenDes=WIDTHBYTES(8*lpDIBHdr->biWidth);
BYTE*lpGrayBits=(BYTE*)(lpGrayRgbQuag)+dwGrayPal;
intaver=0;
inti,j,k;
if(24==lpDIBHdr->biBitCount)
{
for(i=0;i<256;i++)
{
lpGrayRgbQuag->rgbBlue=i;
lpGrayRgbQuag->rgbGreen=i;
lpGrayRgbQuag->rgbRed=i;
lpGrayRgbQuag->rgbReserved=0;
lpGrayRgbQuag++;
}
for(i=0;ibiHeight;i++)
{
for(j=0;jbiWidth;j++)
{
k=i*rowLenSr+3*j;
/*
lpGrayBits[i*rowLenDes+j]=(BYTE)(0.114*lpBits[k]
+
0.587*lpBits[k+1]
+
0.299*lpBits[k+2]+0.5);
*/
lpGrayBits[i*rowLenDes+j]=(BYTE)((117*lpBits[k]
+601
*lpBits[k+1]
+306
*lpBits[k+2]+512)>>10);//修改后的优化算法
}
//修正需要补零的像素行
for(j=lpDIBHdr->biWidth;j {
lpGrayBits[i*rowLenDes+j]=0;
}
}
}
//创建灰度图的信息头
LPBITMAPINFOHEADERlpGrayHdr=(LPBITMAPINFOHEADER)
lpGray;
memcpy(lpGrayHdr,lpDIBHdr,dwInfo);
lpGrayHdr->biSizeImage=sizeTotal;
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) f3(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))/3
4.加权平均法
根据重要性及其它指标,将三个分量以不同的权值进行加权平均。
由于人眼对绿色的敏感最高,对蓝色敏感最低,因此,按下式对RGB三分量进行加权平均能得到较合理的灰度图像。
f(i,j)=0.11R(i,j)+0.59G(i,j)+0.3B(i,j))
如何用C语言对彩色图像进行二值化?
想先是一副彩色图像变成灰度图像,再设定阈值对其进行二值
#include
#include
#include
#pragmapack
(1)
#defineR30
#defineG59
#defineB11
#defineONE255
#defineZERO0
typedefunsignedshortWORD;
typedefunsignedlongDWORD;
typedeflongLONG;
typedefunsignedcharBYTE;
typedefstructtagBITMAPFILEHEADER{//bmfh
WORDbfType;//位图文件的类型,必须为BM
DWORDbfSize;//位图文件的大小,以字节为单位
WORDbfReserved1;//位图文件保留字,必须为0
WORDbfReserved2;//位图文件保留字,必须为0
DWORDbfOffBits;//位图数据的起始位置,以相对于位图文件头的偏移量表示,以字节为单位
}BITMAPFILEHEADER;
typedefstructtagBITMAPINFOHEADER{//bmih
DWORDbiSize;//本结构所占用字节数
LONGbiWidth;//位图的宽度,以像素为单位
LONGbiHeight;//位图的高度,以像素为单位
WORDbiPlanes;//目标设备的级别,必须为1
WORDbiBitCount;//每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一
DWORDbiCompression;//位图压缩类型,必须是0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一
DWORDbiSizeImage;//位图的大小,以字节为单位
LONGbiXPelsPerMeter;//位图水平分辨率,每米像素数
LONGbiYPelsPerMeter;//位图垂直分辨率,每米像素数
DWORDbiClrUsed;//位图实际使用的颜色表中的颜色数
DWORDbiClrImportant;//位图显示过程中重要的颜色数
}BITMAPINFOHEADER;
typedefstructtagPOINT{
BYTEb;
BYTEg;
BYTEr;
}POINT;
intquit();
intquit()
{
puts("File'sformatwrong");
exit(0);