zoukankan      html  css  js  c++  java
  • 自动对比度的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;
    }
  • 相关阅读:
    c/c++混编
    inotify监听文件
    二维数组
    CentOS7 修改系统时间
    书签书签
    c语言并行程序设计之路(四)(barrier的实现和条件变量)
    MPI分布式内存编程(一):预备知识
    有些狮子不喝咖啡:条件式与合取式的翻译
    【部分博客已搬家至博客园】对CSDN、博客园和简书的一点比较
    c语言并行程序设计之路(三)(信号量与同步)
  • 原文地址:https://www.cnblogs.com/jsxyhelu/p/4051858.html
Copyright © 2011-2022 走看看