C++ opencv实现直方图匹配

直方图匹配应用在很多场合,奈何opencv未提供可以直接拿来用的函数。直方图匹配的主要思想是计算出灰度映射矩阵,根据灰度映射实现将模板图像的风格迁移至待匹配图像。以下为依赖opencv库实现的直方图匹配

#include<iostream>
#include<opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
	//定义修改图像,灰度修改图像, 修改直方图,目标图像,灰度目标图像,目标直方图, 规定化增强图像
	Mat image1, image1_gray, hist1, image2, image2_gray, hist2, image_enhanced;   
	image1 = imread("D:\\下载\\1.jpg",0);  //读取图像;
	if (image1.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}

	cvtColor(image1, image1_gray, COLOR_BGR2GRAY);  //灰度化
	imshow(" image1_gray", image1_gray);   //显示灰度图像

	image2 = imread("D:\\下载\\2.jpg",0);  //读取图像;
	if (image2.empty())
	{
		cout << "读取错误" << endl;
		return -1;
	}

	cvtColor(image2, image2_gray, COLOR_BGR2GRAY);  //灰度化
	imshow(" image2_gray", image2_gray);   //显示灰度图像


	//获取两个均衡化图像的直方图
	int histsize = 256;
	float ranges[] = { 0,256 };
	const float* histRanges = { ranges };
	calcHist(&image1_gray, 1, 0, Mat(), hist1, 1, &histsize, &histRanges, true, false);
	calcHist(&image2_gray, 1, 0, Mat(), hist2, 1, &histsize, &histRanges, true, false);

	//计算两个均衡化图像直方图的累积概率
	float hist1_cdf[256] = { hist1.at<float>(0) };
	float hist2_cdf[256] = { hist2.at<float>(0) };
	for (int i = 1; i < 256; i++)
	{
		hist1_cdf[i] = (hist1_cdf[i - 1] + hist1.at<float>(i));
		hist2_cdf[i] = (hist2_cdf[i - 1] + hist2.at<float>(i));
	}

	for (int i = 0; i < 256; i++)
	{
		hist1_cdf[i] = hist1_cdf[i] / (image1_gray.rows * image1_gray.cols);
		hist2_cdf[i] = hist2_cdf[i] / (image2_gray.rows * image2_gray.cols);
	}

	// 两个累计概率之间的差值,用于找到最接近的点
	float diff_cdf[256][256];
	for (int i = 0; i < 256; i++) {
		for (int j = 0; j < 256; j++)
		{
			diff_cdf[i][j] = fabs(hist1_cdf[i] - hist2_cdf[j]);
		}
	}

	Mat lut(1, 256, CV_8U);
	for (int i = 0; i < 256; i++)
	{
		//查找源灰度级为i的映射灰度和i的累积概率差最小(灰度接近)的规定化灰度
		float min = diff_cdf[i][0];
		int index = 0;
		for (int j = 0; j < 256; j++) {
			if (min > diff_cdf[i][j]) {
				min = diff_cdf[i][j];
				index = j;
			}
		}
		lut.at<uchar>(i) = index;
	}
	LUT(image1_gray, lut, image_enhanced);  //图像中进行映射
	
	imshow("image_enhanced", image_enhanced);


	waitKey(0);  //暂停,保持图像显示,等待按键结束
	return 0;
}

                          原图                                                模板图像                        直方图匹配后图像

猜你喜欢

转载自blog.csdn.net/weixin_54474317/article/details/135096541
今日推荐