VC数字图像处理编程讲座之一 联系客服

发布时间 : 星期五 文章VC数字图像处理编程讲座之一更新完毕开始阅读6a20e79951e79b8968022653

4.马赛克效果

马赛克显示是指图像被分成许多的小块,它们以随机的次序显示出来,直到图像显示完毕。实现马赛克的效果主要解决的问题是如何定义显示随机序列的小方块,这个问题的解决可以在定义过小方块的基础上,用一个数组来记录各个方块的左上角的坐标的位置。显示图像过程中,产生一个随机数来挑选即将显示的小方块,显示后将该方块的位置坐标从数组中剔除。清除过程与之相仿。剔除显示过的方块的位置坐标的方法是将该数组中的最后的一个点的坐标拷贝到当前位置,然后删除数组中的最后点的坐标,经过实现发现这样处理有时显示的图像是不完整的,分析其原因是生成随机数的过程有舍入溢出误差。读者可以采用其它的办法解决这个问题,例如可以生成固定的随机数组或采用一个动态的数组来跟踪未显示的图像方块的坐标等方法。

....................................... int m,n;

int RectSize=60;//方块的宽、高尺寸为60个像素;

if(lpDIBHdr->biWidth%RectSize!=0)//得到图像水平方块的个数; m= lpDIBHdr->biWidth/RectSize+1;

else

m= lpDIBHdr->biWidth/RectSize;

if(lpDIBHdr->biHeight%RectSize!=0)//得到图像垂直方块的个数; n= lpDIBHdr->biHeight/RectSize+1; else

n=lpDIBHdr->biHeight/RectSize;

POINT *point=new POINT[n*m];//申请一个数组用来记录各个方块的左上角的坐标;

POINT point1; for(int a=0;a

for(int b=0;b {

point1.x=a*RectSize; point1.y=b*RectSize; *(point+a*b+b)=point1; }

//开始随机的显示各个小方块;

中国图象图形网 www.image2003.com

double fMax=RAND_MAX;//定义Rand()函数的最大值; for(int k=m*n-1;k>=0;k--) {

int c=(int)((double)(m*n)*rand()/fMax); int mx=point[c].x; int my=point[c].y;

//显示对应的图像的小块;

StretchDIBits (hDC,mx,my,RectSize,RectSize, mx,lpDIBHdr->biHeight-my,RectSize,RectSize, lpDIBBits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);

point[c].x=point[k].x; point[c].y=point[k].y; DelayTime(50); }

.......................................

5.图像的淡入淡出效果

图像的淡入淡出的显示效果被广泛的应用在多媒体娱乐软件中,是一种特别重要的特效显示方法。淡入就是将显示图像的目标区域由本色逐渐过度的图像中的各个像素点的颜色;淡出就是由显示的图像逐渐过度到目标区域的本色。实现图像的淡入淡出有两种办法:一是均匀的改变图像的调色板中的颜色索引值;另一种方法是改变图像像素的灰度值。第一种方法实现起来比较繁琐,第二种方法就比较简单。下面是我们采用第二种方法实现图像淡入效果的代码:

.......................................

//申请一个与图像缓冲区相同大小的内存;

hdibcopy=(HDIB)GlobalAlloc(GMEM_SHARE,lpDIBHdr->biWidth*lpDIBHdr->biHeight);

lpbits=(BYTE*)GlobalLock(hdibcopy); //将缓冲区的数据初始化;

for(int k=0;kbiWidth*lpDIBHdr->biHeight;k++) {

*(lpbits+k)=(BYTE)255;

中国图象图形网 www.image2003.com

}

//显示最初的图像为\白色\

StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0, lpDIBHdr->biWidth,lpDIBHdr->biHeight, lpbits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);

//布尔变量end用来标志何时淡入处理结束; BOOL end=false;

while(!end) { int a=0;

for(int k=0;kbiWidth*lpDIBHdr->biHeight;k++) {

//判断是否待显示的像素的灰度值已经小于原始图像对应点的灰度值,如是则计数;

if(*(lpbits+k)<*(lpDIBBits+k)) a++;

else//否则对应点的灰度值继续减少; *(lpbits+k)-=(BYTE)10;

}

//显示处理后的图像数据lpbits;

StretchDIBits (hDC,0,0,lpDIBHdr->biWidth,lpDIBHdr->biHeight,0,0, lpDIBHdr->biWidth,lpDIBHdr->biHeight, lpbits,(LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS, SRCCOPY);

//如果所有的点的灰度值的都小于或等于原始图像的像素点的灰度值,则认为图像的淡入处理结束。

if(a==lpDIBHdr->biWidth*lpDIBHdr->biHeight)

end=true; DelayTime(50); .......................................

本文上面的内容介绍了几种图像的特殊显示效果,代码在Windows2000和Visual C++6.0编程环境下编译通过,运行正常,处理达到了预期的效果。读者可以将上面介绍的显示图像的函数和处理思路结合起来,实现更多效果。 VC编程实现灰度图像与彩色图像的相互转换

中国图象图形网 www.image2003.com

PhotoShop的图像处理功能很强,其中有一个功能是将灰度图像转换为彩色图像,数字图像处理中,也经常要遇到灰度图像与彩色图像相互转换的问题,如何自己解决这个问题,值得大家探讨,现将我解决这类问题的方法陈述如下:

工程应用中经常要遇到需要把彩色图像到灰度图像的变换的问题,采集卡过来的图像为彩色图像,为加快处理速度,要把彩色图像转换为黑白图象,这个问题比较好解决,一般情况下彩色图像每个像素用三个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝),转换后的黑白图像的一个像素用一个字节表示该点的灰度值,它的值在0~255之间,数值越大,该点越白,既越亮,越小则越黑。转换公式为Gray(i,j)=0.11*R(i,j)+ 0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)为转换后的黑白图像在(i,j)点处的灰度值,我们可以观察该式,其中绿色所占的比重最大,所以转换时可以直接使用G值作为转换后的灰度。

至于灰度图像转换为彩色图像,技术上称为灰度图像的伪彩色处理,这是一种视觉效果明显而技术又不是很复杂的图像增强技术。灰度图像中,如果相邻像素点的灰度相差不大,但包含了丰富的信息的话,人眼则无法从图像中提取相应的信息,因为人眼分辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这样将黑白图像转换为彩色图像人眼可以提取更多的信息量。在转换过程中,经常采用的技术是灰度级-彩色变换,意思就是对黑白图像上的每一个像素点,取得该点的灰度值并送入三个通道经过实施不同的变换,产生相应的R、G、B的亮度值,即所求彩色图像对应像素点的彩色值,具体变换公式很多,我采用的是最常用的一种,变换曲线图如下:

上图中,三个图分别代表了三个变换通道,R、G、B指的是变换后对应点的R、G、B分量值,L指的是各个分量的最大值为255,G(x,y)为相应点的灰度值。理论上就这些,下面是我用VC实现的源代码,图一为我的灰度位图,图二为伪彩色处理后的结果图。我这个实现函数中是如何得到灰度位图的数据的就不多讲了,有兴趣的朋友可参考我在天极网上九月十号发表的《VC灰度位图处理》一文,那里应该讲的很清楚了。需要读者注意的是彩色图像中每个象素中的三个字节分别代表的分量,第一个字节为B,第二个为G值、最后一个为R值,这个顺序不要搞错了。代码实现如下:

void CDibView::OnMenuchange() file://图像转换实现函数 {

// TOD Add your command handler code here

中国图象图形网 www.image2003.com