• Opencv 对比度增强 C++


    计算直方图

    # include <opencv2corecore.hpp>
    #include <opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.hpp>
    //#include<cmath>
    #include <iostream>
    using namespace std;
    using namespace cv;
    
    Mat calcGrayHist(const Mat& image)
    {
    	//存储256个灰度级的像素个数
    	Mat histogram = Mat::zeros(Size(256, 1), CV_32FC1);
    	//图像的高和宽
    	int rows = image.rows;
    	int cols = image.cols;
    	//计算每个灰度级的个数
    	for (int r = 0; r < rows; r++)
    	{
    		for (int c = 0; c < cols; c++)
    		{
    			int index = int(image.at<uchar>(r, c));
    			histogram.at<int>(0, index) += 1;
    		}
    	}
    	return histogram;
    }
    

    伽马变换

    # include <opencv2corecore.hpp>
    #include <opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.hpp>
    //#include<cmath>
    #include <iostream>
    using namespace std;
    using namespace cv;
    int main()
    {
    	Mat I = imread("c:/users/76973/desktop/picture/output_image2.jpg", IMREAD_GRAYSCALE);
    	//灰度值归一化
    	Mat fI;
    	I.convertTo(fI, CV_64F, 1 / 255.0, 0);
    	//伽马变换
    	double gamma = 0.5;
    	Mat O;
    	pow(fI, gamma, O);
    	//显示效果
    	imshow("O", O);
    	waitKey(0);
    }
    

    直方图正规化

    # include <opencv2corecore.hpp>
    #include <opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.hpp>
    //#include<cmath>
    #include <iostream>
    using namespace std;
    using namespace cv;
    int main()
    {
    	//利用C++的minMaxLoc求最大和最小灰度级
    	//输入图像矩阵
    	Mat I = imread("c:/users/76973/desktop/picture/output_image2.jpg", IMREAD_GRAYSCALE);
    	//找到I的最大值和最小值
    	double Imax, Imin;
    	minMaxLoc(I, &Imin, &Imax, NULL, NULL);
    	//设置 Omin 和 Omax
    	double Omin = 0, Omax = 255;
    	//计算 a 和 b
    	double a = (Omax - Omin) / (Imax - Imin);
    	double b = Omin - a * Imin;
    	//线性变换
    	Mat O;
    	convertScaleAbs(I, O, a, b);
    	//显示原图和正规化效果
    	imshow("I", I);
    	imshow("O", O);
    	waitKey(0);
    }
    

    也可以使用opencv的normalize函数

    # include <opencv2corecore.hpp>
    #include <opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.hpp>
    //#include<cmath>
    #include <iostream>
    using namespace std;
    using namespace cv;
    int main()
    {
    	//输入图像矩阵
    	Mat src = imread("c:/users/76973/desktop/picture/output_image2.jpg", IMREAD_GRAYSCALE);
    	//直方图正规化
    	Mat dst;
    	normalize(src, dst, 255, 0, NORM_MINMAX, CV_8U);
    	//显示
    	imshow("原图", src);
    	imshow("直方图正规化", dst);
    	waitKey(0);
    }
    

    全局直方图均值化

    # include <opencv2corecore.hpp>
    #include <opencv2highguihighgui.hpp>
    #include<opencv2imgprocimgproc.hpp>
    //#include<cmath>
    #include <iostream>
    using namespace std;
    using namespace cv;
    
    Mat calcGrayHist(const Mat& image)
    {
    	//存储256个灰度级的像素个数
    	Mat histogram = Mat::zeros(Size(256, 1), CV_32FC1);
    	//图像的高和宽
    	int rows = image.rows;
    	int cols = image.cols;
    	//计算每个灰度级的个数
    	for (int r = 0; r < rows; r++)
    	{
    		for (int c = 0; c < cols; c++)
    		{
    			int index = int(image.at<uchar>(r, c));
    			histogram.at<int>(0, index) += 1;
    		}
    	}
    	return histogram;
    }
    
    Mat equalHist(Mat image)
    {
    	CV_Assert(image.type() == CV_8UC1);
    	//灰度图像的高和宽
    	int rows = image.rows;
    	int cols = image.cols;
    	//第一步:计算图像的灰度直方图
    	Mat grayHist = calcGrayHist(image);
    	//第二步:计算累加灰度直方图
    	Mat zeroCumuMoment = Mat::zeros(Size(256, 1), CV_32SC1);
    	for (int p = 0; p < 256; p++)
    	{
    		if (p == 0)
    			zeroCumuMoment.at<int>(0, p) = grayHist.at<int>(0, 0);
    		else
    			zeroCumuMoment.at<int>(0, p) = zeroCumuMoment.at<int>(0, p - 1) + grayHist.at<int>(0, p);
    	}
    	//第三步:根据累加直方图得到输入灰度级和输出灰度级之间的映射关系
    	Mat outPut_q = Mat::zeros(Size(256, 1), CV_8UC1);
    	float cofficient = 256.0 / (rows * cols);
    	for (int p = 0; p < 256; p++)
    	{
    		float q = cofficient * zeroCumuMoment.at<int>(0, p) - 1;
    		if (q >= 0)
    			outPut_q.at<uchar>(0, p) = uchar(floor(q));
    		else
    			outPut_q.at<uchar>(0, p) = 0;
    	}
    	//第四步:得到直方图均衡化后的图像
    	Mat equalHistImage = Mat::zeros(image.size(), CV_8UC1);
    	for (int r = 0; r < rows; r++)
    	{
    		for (int c = 0; c < cols; c++)
    		{
    			int p = image.at<uchar>(r, c);
    			equalHistImage.at<uchar>(r, c) = outPut_q.at<uchar>(0, p);
    		}
    	}
    	return equalHistImage;
    }
    
    int main()
    {
    	Mat I =  imread("c:/users/76973/desktop/picture/output_image2.jpg", IMREAD_GRAYSCALE);
    	//直方图均衡化
    	Mat O;
    	equalizeHist(I, O);
    	imshow("I", I);
    	imshow("O", O);
    	waitKey(0);
    }
    

    限制对比度的自适应直方图均值化

    # include <opencv2corecore.hpp>
    # include <opencv2highguihighgui.hpp>
    # include<opencv2imgprocimgproc.hpp>
    # include <iostream>
    using namespace std;
    using namespace cv;
    int main()
    {
    	Mat I = imread("c:/users/76973/desktop/picture/output_image2.jpg", IMREAD_GRAYSCALE);
    	//构建CLAHE对象
    	Ptr<CLAHE> clahe = createCLAHE(3.0, Size(8, 8));
    	Mat O;
    	//限制对比度自适应直方图均衡化
    	clahe->apply(I, O);
    	//显示原图及均衡化后的效果
    	imshow("原图", I);
    	imshow("对比度增强", O);
    	waitKey(0);
    }
    
  • 相关阅读:
    电脑一族,打电脑时候的健康的坐姿
    根据时间戳,增量同步数据的解决办法
    写在前面
    《T-GCN: A Temporal Graph Convolutional Network for Traffic Prediction》 论文解读
    关于Graph Convolutional Network的初步理解
    图形学_opengl纹理映射
    推荐算法_CIKM-2019-AnalytiCup 冠军源码解读_2
    推荐算法_CIKM-2019-AnalytiCup 冠军源码解读
    leetcode_雇佣 K 名工人的最低成本(优先级队列,堆排序)
    图形学_Bezier曲线
  • 原文地址:https://www.cnblogs.com/PythonFCG/p/13860123.html
Copyright © 2020-2023  润新知