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