在http://www.cnblogs.com/Imageshop/archive/2011/11/13/2247614.html 一文中,作者给出了“自动对比度”的实现方法,非常nice
实际实现过程中,我发现文中有 “Dim HistRed(255)”这样的定义。一般来说,通道是0-255一个256阶的吧,如果不是语法的不同,应该是一个bug.
另附上opencv的实现代码,dirty code,欢迎有人优化!
Mat autocontrost(Mat matface) { //进行自动对比度校正 double HistRed[256]={0}; double HistGreen[256]={0}; double HistBlue[256]={0}; int bluemap[256]={0}; int redmap[256]={0}; int greenmap[256]={0}; double dlowcut = 0.1; double dhighcut = 0.1; for (int i=0;i<matface.rows;i++) { for (int j=0;j<matface.cols;j++) { int iblue =matface.at<Vec3b>(i,j)[0]; int igreen=matface.at<Vec3b>(i,j)[1]; int ired =matface.at<Vec3b>(i,j)[2]; HistBlue[iblue]++; HistGreen[igreen]++; HistRed[ired]++; } } int PixelAmount = matface.rows*matface.cols; int isum = 0; // blue int iminblue=0;int imaxblue=0; for (int y = 0;y<256;y++)//这两个操作我基本能够了解了 { isum= isum+HistBlue[y]; if (isum>=PixelAmount*dlowcut*0.01) { iminblue = y; break; } } isum = 0; for (int y=255;y>=0;y--) { isum=isum+HistBlue[y]; if (isum>=PixelAmount*dhighcut*0.01) { imaxblue=y; break; } } //red isum=0; int iminred=0;int imaxred=0; for (int y = 0;y<256;y++)//这两个操作我基本能够了解了 { isum= isum+HistRed[y]; if (isum>=PixelAmount*dlowcut*0.01) { iminred = y; break; } } isum = 0; for (int y=255;y>=0;y--) { isum=isum+HistRed[y]; if (isum>=PixelAmount*dhighcut*0.01) { imaxred=y; break; } } //green isum=0; int imingreen=0;int imaxgreen=0; for (int y = 0;y<256;y++)//这两个操作我基本能够了解了 { isum= isum+HistGreen[y]; if (isum>=PixelAmount*dlowcut*0.01) { imingreen = y; break; } } isum = 0; for (int y=255;y>=0;y--) { isum=isum+HistGreen[y]; if (isum>=PixelAmount*dhighcut*0.01) { imaxgreen=y; break; } } /自动色阶 //自动对比度 int imin = 255;int imax =0; if (imin>iminblue) imin = iminblue; if (imin>iminred) imin = iminred; if (imin>imingreen) imin = imingreen; iminblue = imin ; imingreen=imin; iminred = imin ; if (imax<imaxblue) imax = imaxblue; if (imax<imaxgreen) imax =imaxgreen; if (imax<imaxred) imax =imaxred; imaxred = imax; imaxgreen = imax; imaxblue=imax; ///// //blue for (int y=0;y<256;y++) { if (y<=iminblue) { bluemap[y]=0; } else { if (y>imaxblue) { bluemap[y]=255; } else { // BlueMap(Y) = (Y - MinBlue) / (MaxBlue - MinBlue) * 255 '线性隐射 float ftmp = (float)(y-iminblue)/(imaxblue-iminblue); bluemap[y]=(int)(ftmp*255); } } } //red for (int y=0;y<256;y++) { if (y<=iminred) { redmap[y]=0; } else { if (y>imaxred) { redmap[y]=255; } else { // BlueMap(Y) = (Y - MinBlue) / (MaxBlue - MinBlue) * 255 '线性隐射 float ftmp = (float)(y-iminred)/(imaxred-iminred); redmap[y]=(int)(ftmp*255); } } } //green for (int y=0;y<256;y++) { if (y<=imingreen) { greenmap[y]=0; } else { if (y>imaxgreen) { greenmap[y]=255; } else { // BlueMap(Y) = (Y - MinBlue) / (MaxBlue - MinBlue) * 255 '线性隐射 float ftmp = (float)(y-imingreen)/(imaxgreen-imingreen); greenmap[y]=(int)(ftmp*255); } } } //查表 for (int i=0;i<matface.rows;i++) { for (int j=0;j<matface.cols;j++) { matface.at<Vec3b>(i,j)[0]=bluemap[matface.at<Vec3b>(i,j)[0]]; matface.at<Vec3b>(i,j)[1]=greenmap[matface.at<Vec3b>(i,j)[1]]; matface.at<Vec3b>(i,j)[2]=redmap[matface.at<Vec3b>(i,j)[2]]; } } return matface; }