opencv对比度增强方法算法汇总

1、线性变换

线性变化是最好理解的,假设原图为srcimg , 变换后的图像为dstimg,则:

dstimg = a * srcimg +b

a为变换系数,如果a>1 ,则输出图像的对比度增大,当0<a<1则对比度有所减小,b值影响图像的亮度,当b>0时,图像亮度增加,b<0图像亮度减小;

cpp 复制代码
void MainWindow::on_pushButton_clicked()
{
    Mat srcImg = imread("D:\\1.jpg");
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    Mat imgShow ;
    cvtColor(srcImg, imgShow, COLOR_BGR2RGB); // 图像格式转换
    QImage qImg = QImage((unsigned char*)(imgShow.data), imgShow.cols,
                         imgShow.rows, imgShow.cols*imgShow.channels(), QImage::Format_RGB888);
    ui->label->resize(qImg.width()/2 , qImg.height()/2);
    ui->label->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label->size(), Qt::KeepAspectRatio)));
}


void MainWindow::on_pushButton_3_clicked()
{
    Mat srcImg = imread("D:\\1.jpg");
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    srcImg =0.8 *srcImg -10;
    Mat imgShow ;
    cvtColor(srcImg, imgShow, COLOR_BGR2RGB); // 图像格式转换
    QImage qImg = QImage((unsigned char*)(imgShow.data), imgShow.cols,
                         imgShow.rows, imgShow.cols*imgShow.channels(), QImage::Format_RGB888);
    ui->label_2->resize(qImg.width()/2 , qImg.height()/2);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}

2、分段线性变换

分段性变换实在线性变换的基础上进行分段处理,分段是根据灰度值进行区分:

dstimg =0 if灰度值<50

dstimg = srcimg - 50 if 50<灰度值<150

dstimg = 0.1*srcimg if灰度值>150

cpp 复制代码
void MainWindow::on_pushButton_4_clicked()
{
    Mat srcImg = imread("D:\\1.jpg");
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    for(int i=0;i<srcImg.rows;++i)
    {
        uchar*ptr = srcImg.ptr<uchar>(i);

        for(int j =0;j<srcImg.cols;++j)
        {
            for(int m=0;m<3;++m)
            {
                if(ptr[j*3+m]<50)
                {
                    ptr[j*3+m] = 0;
                }
                else if(ptr[j*3+m]>150)
                {
                    ptr[j*3+m] = ptr[j*3+m] - 50;
                }
                else
                {
                    ptr[j*3+m] = 0.1*ptr[j*3+m];
                }
            }

        }
    }
    Mat imgShow ;
    cvtColor(srcImg, imgShow, COLOR_BGR2RGB); // 图像格式转换

    QImage qImg = QImage((unsigned char*)(imgShow.data), imgShow.cols,
                         imgShow.rows, imgShow.cols*imgShow.channels(), QImage::Format_RGB888);
    ui->label_2->resize(qImg.width()/2 , qImg.height()/2);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}

3、伽马变换

伽马变换,就是对原图灰度值进行幂运算,比如2次方,3次方,0.5次方。。。

1、将原图归一化到【0,1】

2、开始幂运算

3、归一化到【0,255】

cpp 复制代码
void MainWindow::on_pushButton_5_clicked()
{
    Mat srcImg = imread("D:\\1.jpg",0);
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }

    //1、直接便利像素
    for(int i=0;i<srcImg.rows;++i)
    {
        uchar*ptr = srcImg.ptr<uchar>(i);

        for(int j =0;j<srcImg.cols;++j)
        {
            //归一化
            double s = ptr[j]/255.0;
            double t = pow(s,2);
            //扩展到255
            ptr[j] = 255*t;
        }
    }

    //2、调用接口
    //灰度归一化
    // srcImg.convertTo(srcImg , CV_64F , 1.0/255);
    // Mat dstImg;
    // cv::pow(srcImg , 2,dstImg);
    // dstImg.convertTo(srcImg , CV_8U , 255,0);

    QImage qImg = QImage((unsigned char*)(srcImg.data), srcImg.cols,
                         srcImg.rows, srcImg.cols*srcImg.channels(), QImage::Format_Grayscale8);
    ui->label_2->resize(qImg.width()/2 , qImg.height()/2);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}

4、直方图正规化

假设图像 A 中灰度范围【50,100】 , 将其灰度值按照特特定公式拉伸到图像B【0,255】或者任意其他值,比如【0,100】 , 【100,200】 , 这就叫直方图正规化

公式如下:a = (Bmax - Bmin)/(Amax - Amin) b = Bmin-aAmin;
dstimg = a
srcimg +b;

opencv自带函数 normalize()

cpp 复制代码
void MainWindow::on_pushButton_6_clicked()
{
    Mat srcImg = imread("D:\\1.jpg",0);
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    normalize(srcImg , srcImg,255,150 , NORM_MINMAX);

    QImage qImg = QImage((unsigned char*)(srcImg.data), srcImg.cols,
                         srcImg.rows, srcImg.cols*srcImg.channels(), QImage::Format_Grayscale8);
    ui->label_2->resize(qImg.width()/2 , qImg.height()/2);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}

5、直方图均衡化

直方图均衡化本质就是平衡图像内的灰度值,避免灰度值扎堆,而将其分散

cpp 复制代码
void MainWindow::on_pushButton_7_clicked()
{
    Mat srcImg = imread("D:\\3.jpg",0);
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    //normalize(srcImg , srcImg,255,150 , NORM_MINMAX);
    equalizeHist(srcImg , srcImg);

    QImage qImg = QImage((unsigned char*)(srcImg.data), srcImg.cols,
                         srcImg.rows, srcImg.cols*srcImg.channels(), QImage::Format_Grayscale8);
    ui->label_2->resize(qImg.width()/4 , qImg.height()/4);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}

6、局部自适应直方图均衡化

自适应直方图均衡化首先将图像划分成不重叠的区域块,然后对每一块分别进行直方图均衡化,在没有噪声影响的情况下,每一个区域的灰度直方图都会被限制在一个小的灰度级内,但是若要存在噪声,经过局部直方图均衡化后,噪声将会被放大,为了避免这种情况,提出了限制对比度,如果直方图的bin超过了预先设置的阈值,那么将会被裁掉,然后将裁掉的部分平均分给其他bin , 这样就重构了直方图,避免噪声的影响

cpp 复制代码
void MainWindow::on_pushButton_8_clicked()
{
    Mat srcImg = imread("D:\\5.jpg",0);
    if(srcImg.empty())
    {
        QMessageBox::information(this,"警告","图片读取失败,请检查图片路径!");
        return;
    }
    //normalize(srcImg , srcImg,255,150 , NORM_MINMAX);
    // equalizeHist(srcImg , srcImg);
    Ptr<CLAHE> clahe =  createCLAHE(2.0 , Size(8,8));
    clahe->apply(srcImg , srcImg);


    QImage qImg = QImage((unsigned char*)(srcImg.data), srcImg.cols,
                         srcImg.rows, srcImg.cols*srcImg.channels(), QImage::Format_Grayscale8);
    ui->label_2->resize(qImg.width()/2 , qImg.height()/2);
    ui->label_2->setPixmap(QPixmap::fromImage(qImg.scaled(ui->label_2->size(), Qt::KeepAspectRatio)));
}
相关推荐
刽子手发艺36 分钟前
Selenium+OpenCV处理滑块验证问题
opencv·selenium·webpack
Paddi93042 分钟前
Codeforces Round 1004 (Div. 1) C. Bitwise Slides
c++·算法
Luis Li 的猫猫2 小时前
深度学习中的知识蒸馏
人工智能·经验分享·深度学习·学习·算法
查理零世2 小时前
【蓝桥杯集训·每日一题2025】 AcWing 6118. 蛋糕游戏 python
python·算法·蓝桥杯
敲代码的小王!2 小时前
MD5加密算法和BCrypt密码加密算法
java·算法·安全
带娃的IT创业者3 小时前
机器学习实战(6):支持向量机(SVM)——强大的非线性分类器
算法·机器学习·支持向量机
木觞清4 小时前
PyTorch与TensorFlow的对比:哪个框架更适合你的项目?
人工智能·pytorch·tensorflow
孑么5 小时前
力扣 买卖股票的最佳时机
算法·leetcode·职场和发展·贪心算法·动态规划
诚信爱国敬业友善6 小时前
常见排序方法的总结归类
开发语言·python·算法
gentle_ice7 小时前
跳跃游戏 II - 贪心算法解法
数据结构·算法·leetcode·贪心算法