最新数字图像处理算法实现精编版.docx

上传人:b****8 文档编号:10059877 上传时间:2023-02-08 格式:DOCX 页数:40 大小:32.24KB
下载 相关 举报
最新数字图像处理算法实现精编版.docx_第1页
第1页 / 共40页
最新数字图像处理算法实现精编版.docx_第2页
第2页 / 共40页
最新数字图像处理算法实现精编版.docx_第3页
第3页 / 共40页
最新数字图像处理算法实现精编版.docx_第4页
第4页 / 共40页
最新数字图像处理算法实现精编版.docx_第5页
第5页 / 共40页
点击查看更多>>
下载资源
资源描述

最新数字图像处理算法实现精编版.docx

《最新数字图像处理算法实现精编版.docx》由会员分享,可在线阅读,更多相关《最新数字图像处理算法实现精编版.docx(40页珍藏版)》请在冰豆网上搜索。

最新数字图像处理算法实现精编版.docx

最新数字图像处理算法实现精编版

 

2020年数字图像处理算法实现精编版

数字图像处理算法实现

------------编程心得

(1)

2001414班朱伟20014123

摘要:

关于空间域图像处理算法框架,直方图处理,空间域滤波器算法框架的编程心得,使用GDI+(C++)

一,图像文件的读取

初学数字图像处理时,图像文件的读取往往是一件麻烦的事情,我们要面对各种各样的图像文件格式,如果仅用C++的fstream库那就必须了解各种图像编码格式,这对于初学图像处理是不太现实的,需要一个能帮助轻松读取各类图像文件的库。

在Win32平台上GDI+(C++)是不错的选择,不光使用上相对于Win32GDI要容易得多,而且也容易移植到.Net平台上的GDI+。

Gdiplus:

:

Bitmap类为我们提供了读取各类图像文件的接口,Bitmap:

:

LockBits方法产生的BitmapData类也为我们提供了高速访问图像文件流的途径。

这样我们就可以将精力集中于图像处理算法的实现,而不用关心各种图像编码。

具体使用方式请参考MSDN中GDI+文档中关于Bitmap类和BitmapData类的说明。

另外GDI+仅在WindowsXP/2003上获得直接支持,对于Windows2000必须安装相关DLL,或者安装有Office2003,VisualStudio2003.Net等软件。

二,空间域图像处理算法框架

(1)在空间域图像处理中,对于一个图像我们往往需要对其逐个像素的进行处理,对每个像素的处理使用相同的算法(或者是图像中的某个矩形部分)。

即,对于图像f(x,y),其中0≤x≤M,0≤y≤N,图像为M*N大小,使用算法algo,则f(x,y)=algo(f(x,y))。

事先实现一个算法框架,然后再以函数指针或函数对象(functor,即实现operator()的对象)传入算法,可以减轻编程的工作量。

如下代码便是一例:

#ifndefPROCESSALGO_H

#definePROCESSALGO_H

 

#include

#include

 

 

namespacensimgtk

{

template

:

PixelFormatpixelFormat,classProcessor>

boolProcessPixelsOneByOne(Gdiplus:

:

Bitmap*constp_bitmap,Processorprocessor,unsignedintx,unsignedinty,

unsignedintwidth,unsignedintheight)

{

if(p_bitmap==NULL)

{

returnfalse;

}

 

if((width+x>p_bitmap->GetWidth())||(height+y>p_bitmap->GetHeight()))

{

returnfalse;

}

 

Gdiplus:

:

BitmapDatabitmapData;

Gdiplus:

:

Rectrect(x,y,width,height);

if(p_bitmap->LockBits(&rect,Gdiplus:

:

ImageLockModeWrite,pixelFormat,&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

 

pixelType*pixels=(pixelType*)bitmapData.Scan0;

 

for(unsignedintrow=0;row

{

for(unsignedintcol=0;col

{

processor(&pixels[col+row*bitmapData.Stride/sizeof(pixelType)]);

}

}

 

if(p_bitmap->UnlockBits(&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

returntrue;

}

}

 

#endif

ProcessPixelsOneByOne函数可以对图像中从(x,y)位置起始,width*height大小的区域进行处理。

模板参数pixelType用于指定像素大小,例如在Win32平台上传入unsignedchar即为8位,用于8阶灰度图。

模板参数Processor为图像处理算法实现,可以定义类实现voidoperator(pixelType*)函数,或者传入同样接口的函数指针。

如下便是一些算法示例(说明见具体注释):

#ifndefSPATIALDOMAIN_H

#defineSPATIALDOMAIN_H

#include

#include

 

namespacensimgtk

{

//8阶灰度图的灰度反转算法

classNegativeGray8

{

public:

voidoperator()(unsignedchar*constp_value)

{

*p_value^=0xff;

}

};

//8阶灰度图的Gamma校正算法

classGammaCorrectGray8

{

private:

unsignedchard_s[256];

public:

GammaCorrectGray8:

:

GammaCorrectGray8(doublec,doublegamma);

 

voidoperator()(unsignedchar*constp_value)

{

*p_value=d_s[*p_value];

}

};

 

//8阶灰度图的饱和度拉伸算法

classContrastStretchingGray8

{

private:

unsignedchard_s[256];

public:

ContrastStretchingGray8:

:

ContrastStretchingGray8(doublea1,doubleb1,unsignedintx1,

doublea2,doubleb2,unsignedintx2,doublea3,doubleb3);

 

voidoperator()(unsignedchar*constp_value)

{

*p_value=d_s[*p_value];

}

};

//8阶灰度图的位平面分割,构造函数指定位平面号

classBitPlaneSliceGray8

{

private:

unsignedchard_s[256];

public:

BitPlaneSliceGray8(unsignedcharbitPlaneNum);

 

voidoperator()(unsignedchar*constp_value)

{

*p_value=d_s[*p_value];

}

};

}

 

#endif

 

//上述类中各构造函数的实现代码,应该分在另一个文件中,此处为说明方便,一并列出

#include"SpatialDomain/spatialDomain.h"

 

namespacensimgtk

{

GammaCorrectGray8:

:

GammaCorrectGray8(doublec,doublegamma)

{

doubletemp;

for(unsignedinti=0;i<256;++i)

{

temp=ceil(c*255.0*pow(double(i)/255.0,gamma));

d_s[i]=unsignedchar(temp);

}

}

 

ContrastStretchingGray8:

:

ContrastStretchingGray8(doublea1,doubleb1,unsignedintx1,

doublea2,doubleb2,unsignedintx2,doublea3,doubleb3)

{

if(x1>255||x2>255||x1>x1)

{

for(unsignedinti=0;i<256;++i)

d_s[i]=i;

}

else

{

doubletmp;

for(unsignedinti=0;i

{

tmp=ceil(a1*double(i)+b1);

d_s[i]=(unsignedchar)tmp;

}

 

for(unsignedinti=x1;i

{

tmp=ceil(a2*double(i)+b2);

d_s[i]=(unsignedchar)tmp;

}

 

for(unsignedinti=x2;i<256;++i)

{

tmp=ceil(a3*double(i)+b3);

d_s[i]=(unsignedchar)tmp;

}

}

}

 

BitPlaneSliceGray8:

:

BitPlaneSliceGray8(unsignedcharbitPlaneNum)

{

unsignedcharbitMaskArray[8]=

{

0x01,0x02,0x04,0x08,

0x10,0x20,0x40,0x80

};

 

for(unsignedinti=0;i<256;++i)

{

unsignedchartmp=i;

tmp&=bitMaskArray[bitPlaneNum];

tmp=(tmp>>bitPlaneNum)*255;

d_s[i]=tmp;

}

}

}

(2)直方图在GDI+1.0中没有获得支持,我们必须自行实现。

直方图相关的处理在数字图像处理中占有重要地位,可以通过它获取图像灰度级的统计信息,且可以通过直方图进行一些重要的图像增强技术,如直方图均衡化,直方图规定化,基本全局门限等。

下面是获取8阶图像直方图的算法实现:

namespacensimgtk

{

boolGetHistogramNormalizeGray8(Gdiplus:

:

Bitmap*constp_bitmap,float*histogramArray)

{

if(p_bitmap==NULL||histogramArray==NULL)

{

returnfalse;

}

 

Gdiplus:

:

BitmapDatabitmapData;

Gdiplus:

:

Rectrect(0,0,p_bitmap->GetWidth(),p_bitmap->GetHeight());

 

if(p_bitmap->LockBits(&rect,Gdiplus:

:

ImageLockModeRead,PixelFormat8bppIndexed,&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

 

unsignedchar*pixels=(unsignedchar*)bitmapData.Scan0;

unsignedinthistogram[256];

for(inti=0;i<256;++i)

{

histogram[i]=0;

}

 

for(unsignedintrow=0;rowGetWidth();++row)

{

for(unsignedintcol=0;colGetHeight();++col)

{

++histogram[pixels[col+row*bitmapData.Stride]];

}

}

 

constunsignedinttotalPixels=p_bitmap->GetWidth()*p_bitmap->GetHeight();

for(inti=0;i<256;++i)

{

histogramArray[i]=float(histogram[i])/float(totalPixels);

}

 

if(p_bitmap->UnlockBits(&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

 

returntrue;

}

}

在获取直方图后(即上面算法的第二个参数),再将其作为参数传入下面的对象的构造函数,然后以该对象为仿函数传入ProcessPixelsOneByOne即可实现8阶图像直方图均衡化:

#ifndefSPATIALDOMAIN_H

#defineSPATIALDOMAIN_H

 

#include

#include

 

namespacensimgtk

{

//8阶灰度图的直方图均衡化

classHistogramEqualizationGray8

{

private:

unsignedchard_s[256];

public:

HistogramEqualizationGray8(constfloat*consthistogramArray);

voidoperator()(unsignedchar*constp_value)

{

*p_value=d_s[*p_value];

}

};

}

 

#endif

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include"SpatialDomain/spatialDomain.h"

 

namespacensimgtk

{

HistogramEqualizationGray8:

:

HistogramEqualizationGray8(constfloat*consthistogramArray)

{

if(histogramArray!

=NULL)

{

floatsum=0.0;

for(inti=0;i<256;++i)

{

sum+=histogramArray[i];

d_s[i]=unsignedchar(sum*255);

}

}

}

}

(3)空间域滤波器,滤波器是一个m*n大小的掩模,其中m,n均为大于1的奇数。

滤波器逐像素地通过图像的全部或部分矩形区域,然后逐像素地对掩模覆盖下的像素使用滤波器算法获得响应,将响应赋值于当前像素即掩模中心像素,另外滤波器算法使用中将会涉及到图像边缘的问题,这可以对边缘部分掩模使用补零法补齐掩模下无像素值的区域,或者掩模的移动范围以不越出图像边缘的方式移动,当然这些处理方法都会给图像边缘部分带来不良效果,但是一般情况下,图像边缘部分往往不是我们关注的部分或者没有重要的信息。

下面的滤波器算法框架SpatialFilterAlgo即以补零法(zero-padding)实现:

#ifndefSPATIALFILTER_H

#defineSPATIALFILTER_H

 

#include

#include

#include

#include

#include

#include

 

namespacensimgtk

{

template

:

PixelFormatpixelFormat,classFilterMask>

boolSpatialFilterAlgo(Gdiplus:

:

Bitmap*constp_bitmap,FilterMaskfilterMask,unsignedintx,unsignedinty,

unsignedintwidth,unsignedintheight)

{

if(p_bitmap==NULL)

{

returnfalse;

}

 

if((width+x>p_bitmap->GetWidth())||(height+y>p_bitmap->GetHeight()))

{

returnfalse;

}

 

Gdiplus:

:

BitmapDatabitmapData;

Gdiplus:

:

Rectrect(x,y,width,height);

if(p_bitmap->LockBits(&rect,Gdiplus:

:

ImageLockModeWrite,pixelFormat,&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

 

pixelType*pixels=(pixelType*)bitmapData.Scan0;

constunsignedintm=filterMask.d_m;//mask'swidth

constunsignedintn=filterMask.d_n;//mask'sheight

std:

:

vectortmpImage((m-1+width)*(n-1+height));//extendimagetousezero-padding

//copyoriginalbitmaptoextendedimagewithzero-paddingmethod

for(unsignedintrow=0;row

{

for(unsignedintcol=0;col

{

tmpImage[(col+m/2)+(row+n/2)*(bitmapData.Stride/sizeof(pixelType)+m-1)]=

pixels[col+row*bitmapData.Stride/sizeof(pixelType)];

}

}

//processeverypixelwithfilterMask

for(unsignedintrow=0;row

{

for(unsignedintcol=0;col

{

//fillthe"m*n"maskwiththecurrentpixel'sneighborhood

for(unsignedinti=0;i

{

for(unsignedintj=0;j

{

filterMask.d_mask[i*m+j]=tmpImage[(col+j)+(row+i)*(bitmapData.Stride/sizeof(pixelType)+m-1)];

}

}

//replacethecurrentpixelwithfiltermask'sresponse

pixels[col+row*bitmapData.Stride/sizeof(pixelType)]=filterMask.response();

}

}

 

if(p_bitmap->UnlockBits(&bitmapData)!

=Gdiplus:

:

Ok)

{

returnfalse;

}

returntrue;

}

}

 

#endif

其中模板参数FilterMask即为滤波掩模算法。

通常的滤波算法有均值滤波器,可以模糊化图像,去除图形中的细节部分,使得我们可以关注图像中较为明显的部分,均值滤波器用于周期性噪声。

中值滤波器用于图像中存在椒盐噪声也即脉冲噪声的情况下。

另外有基于一阶微分的Sobel梯度算子和基于两阶微分的拉普拉斯算子,它们往往被用于边缘检测中。

下面是一些滤波器算法的具体实现,所以滤波器算法都应该实现pixelTyperesponse()函数以及有d_mask,d_m,d_n成员,这可以通过继承__filteMask类获得(不需要付出虚函数代价)。

#ifndefSPATIALFILTER_H

#defineSPATIALFILTER_H

 

#include

#include

#include

#include

#include

#include

 

namespacensimgtk

{

//滤波器掩模的基类,提供掩模大小d_m,d_n,掩模覆盖下的m*n个像素值d_mask

//othersfilterMaskshouldinheritit

template

struct__filterMask

{

constunsignedintd_m;

constunsignedintd_n;

 

//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1