使用visual studio,基于opencv完成一个直方图匹配算法,输入两个图片,完成彩色图片(三通道)的直方图匹配,要求处理两张图片的颜色分布不同的情况,并且可以处理两张图片的对比度不同的情况
时间: 2024-04-29 15:23:50 浏览: 8
以下是基于OpenCV的直方图匹配算法的代码,可以处理两张图片的颜色分布不同和对比度不同的情况:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat histogram_matching(Mat src, Mat ref)
{
Mat src_channels[3], ref_channels[3];
split(src, src_channels);
split(ref, ref_channels);
Mat result(src.size(), CV_8UC3);
for (int i = 0; i < 3; i++)
{
// 计算源图和参考图的直方图
int histSize = 256;
float range[] = { 0, 256 };
const float* histRange = { range };
bool uniform = true, accumulate = false;
Mat src_hist, ref_hist;
calcHist(&src_channels[i], 1, 0, Mat(), src_hist, 1, &histSize, &histRange, uniform, accumulate);
calcHist(&ref_channels[i], 1, 0, Mat(), ref_hist, 1, &histSize, &histRange, uniform, accumulate);
// 计算源图和参考图的累积直方图
Mat src_cum_hist(histSize, 1, CV_32FC1);
Mat ref_cum_hist(histSize, 1, CV_32FC1);
src_cum_hist.at<float>(0, 0) = src_hist.at<float>(0, 0);
ref_cum_hist.at<float>(0, 0) = ref_hist.at<float>(0, 0);
for (int j = 1; j < histSize; j++)
{
src_cum_hist.at<float>(j, 0) = src_cum_hist.at<float>(j - 1, 0) + src_hist.at<float>(j, 0);
ref_cum_hist.at<float>(j, 0) = ref_cum_hist.at<float>(j - 1, 0) + ref_hist.at<float>(j, 0);
}
// 计算源图和参考图的累积直方图归一化
src_cum_hist /= src_cum_hist.at<float>(histSize - 1, 0);
ref_cum_hist /= ref_cum_hist.at<float>(histSize - 1, 0);
// 直方图匹配
Mat lookup_table(1, histSize, CV_8UC1);
for (int j = 0; j < histSize; j++)
{
int k = histSize - 1;
while (k >= 0 && ref_cum_hist.at<float>(j, 0) <= src_cum_hist.at<float>(k, 0))
k--;
lookup_table.at<uchar>(j, 0) = k;
}
// 应用查找表
LUT(src_channels[i], lookup_table, result.channels()[i]);
}
return result;
}
int main()
{
Mat src = imread("img1.jpg");
Mat ref = imread("img2.jpg");
if (src.empty() || ref.empty())
{
cout << "Could not open or find the images!\n";
return -1;
}
// 调整对比度
float alpha = 1.5;
float beta = 50;
src.convertTo(src, -1, alpha, beta);
Mat result = histogram_matching(src, ref);
namedWindow("Source", WINDOW_NORMAL);
namedWindow("Reference", WINDOW_NORMAL);
namedWindow("Result", WINDOW_NORMAL);
imshow("Source", src);
imshow("Reference", ref);
imshow("Result", result);
waitKey(0);
return 0;
}
```
首先将源图和参考图分离成三个通道。然后对于每个通道,计算源图和参考图的直方图和累积直方图,并计算直方图匹配的查找表。最后将查找表应用到源图的每个通道上,得到匹配后的结果。
在实现中,还加入了对比度的调整,可以通过alpha和beta参数来控制。