自动对比度的opencv实现

本文详细阐述了一种自动对比度调整的实现方法,并通过代码示例进行了展示。该算法通过对图像各通道直方图的分析,自动确定色阶范围,从而实现对比度的优化。此外,提供了一个简单的优化代码,方便读者进一步研究与实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

转载于:https://www.cnblogs.com/jsxyhelu/p/4051858.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值