Opencv 对比度增强 C++

Opencv 对比度增强 C++

  • 计算直方图
  • 伽马变换
  • 直方图正规化
  • 全局直方图均值化
  • 限制对比度的自适应直方图均值化

计算直方图

# include 
#include 
#include
//#include
#include 
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 
#include 
#include
//#include
#include 
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 
#include 
#include
//#include
#include 
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 
#include 
#include
//#include
#include 
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 
#include 
#include
//#include
#include 
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 
# include 
# include
# include 
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);
}

你可能感兴趣的:(Opencv)