直方图变换在实际工程中的应用很广,一些美化照片的软件很多工具都是在图像的直方图上作文章
下面介绍两个简单的直方图变换函数:直方图拉伸与直方图均衡化。
如果图像的灰度在直方图上显示集中在某一个区间,则说明图像色彩单一,我们可以将其扩展到更宽的灰度范围内让图像更有层次感。
变换函数:将图像的一种灰度值经过变换得到另一个灰度。
直方图变换的核心就是变换函数,s=T(r),r是变换前的灰度值,s是变换后的灰度值,如要我们想将[a,b]区间的灰度变换到[0,255]范围内,则变换函数是:T(r)=255*(r-a)/(b-a)。
我们在OpenCV中创建这样一个变换函数:
// 创建一个1*256的矢量 Mat lut(1,256,CV_8U); for(int i=0;i<256;i++) { if(lut.at<uchar>(i)<imin) lut.at<uchar>(i)=0; else if(lut.at<uchar>(i)>imax) lut.at<uchar>(i)=255; else lut.at<uchar>(i)=static_cast<uchar>( 255.0*(i-imin)/(imax-imin)+0.5); }
其中imax,imin是图像中的最小灰度与最大灰度。我们可以从直方图中求出:
int imax,imin; for(imin=0;imin<256;imin++) { if(hist.at<uchar>(imin)>minValue) break; } for(imax=255;imax>-1;imax--) { if(hist.at<uchar>(imax)>minValue) break; }
最后我们应用OpenCV中的LUT函数,把变换应用在直方图上即可。
LUT(image,lut,result);
第二个参数就像一个查找表一样,将原图像中的灰度按表查找,然后把灰度值替换为表中对应的值。
有了上面灰度拉伸的例子就不难理解图像的直方图均衡了,直方图均衡化可以让图像灰度分布更加均匀,让图像的对比度增强。
在OpenCV中直方图均衡不用像灰度拉伸那样先构造一个变换函数,它有直接对应的函数,当然你如果有兴趣也可以去尝试写一下变换函数均衡化的变换原理会稍复杂一些,在OpenCV这个系列里面,不会太多的介绍数字图像中的算法,以后有机会再专门来讨论。
int main() { Mat Image=imread("../cat.png"); cvtColor(Image,Image,CV_BGR2GRAY); Mat result; equalizeHist(Image,result); return 0; }