在 一文中,作者给出了“自动对比度”的实现方法,非常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;
}