自动对比度的opencv实现

在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;
}

 

posted on 2022-12-03 15:32  jsxyhelu  阅读(143)  评论(0编辑  收藏  举报

导航