c++直方图匹配终极版,支持任意通道数(opencv版本)

实现思路:多个通道拆分,每个通道单独匹配。

对于每个通道,首先分别拉成一条,并按升序排序同时记下原编号,排序后每个像素比对,待匹配像素值不等于标准像素的,直接将待匹配对应位置像素更改为标准像素值。

实现效果

c++直方图匹配终极版,支持任意通道数(opencv版本)_第1张图片 标准影像
c++直方图匹配终极版,支持任意通道数(opencv版本)_第2张图片 待匹配影像
c++直方图匹配终极版,支持任意通道数(opencv版本)_第3张图片 匹配结果

 代码

依赖:

opencv_core
opencv_highgui
opencv_imgproc
opencv_imgcodecs

#include 
#include 
#include 
#include 


struct FloatSort
{
	int index;
	float value;
};

bool compare(FloatSort a, FloatSort b)
{
	return a.value < b.value;
}

cv::Mat CHistMatch(const cv::Mat img1, const cv::Mat img2)
{
	/// @brief img2到img1,单通道
	/// @param img1 第一张影像
	/// @param img2 第二张影像
	/// @return 
	cv::Mat mimg1 = img1.clone();
	cv::Mat mimg2 = img2.clone();
	//变换数据类型
	mimg1.convertTo(mimg1, CV_32FC1);
	mimg2.convertTo(mimg2, CV_32FC1);
	//变形
	mimg1 = mimg1.reshape(1, mimg1.rows * mimg1.cols);
	mimg2 = mimg2.reshape(1, mimg2.rows * mimg2.cols);
	//排序并记下序号
	std::vector mmimg1(mimg1.rows), mmimg2(mimg2.rows);
	for (size_t i = 0; i < mmimg1.size(); i++)
	{
		mmimg1[i].index = i;
		mmimg1[i].value = mimg1.at(i, 0);
		mmimg2[i].index = i;
		mmimg2[i].value = mimg2.at(i, 0);
	}
	sort(mmimg1.begin(), mmimg1.end(), compare);
	sort(mmimg2.begin(), mmimg2.end(), compare);
	//根据排序结果进行映射
	for (size_t i = 0; i < mmimg1.size(); i++)
	{
		float num1 = mmimg1[i].value;
		float num2 = mmimg2[i].value;
		if (num1 != num2)
		{
			mimg2.at(mmimg2[i].index, 0) = num1;
		}
	}
	//变换并返回
	cv::Mat nimg2 = cv::Mat(img2.rows, img2.cols, img2.type());
	mimg2.reshape(1, img2.rows).convertTo(nimg2, img2.type());
	return nimg2;
}

bool CHistMatch(const cv::Mat img1, const cv::Mat img2, cv::Mat &nimg)
{
	/// @brief img2到img1,任意通道,但必须一致
	/// @param img1 第一张影像
	/// @param img2 第二张影像
	/// @return 
	if (img1.channels() != img2.channels())
	{
		printf("通道不一致!!!");
		return false;
	}
	if (img1.size() != img2.size())
	{
		printf("大小不一致!!!");
		return false;
	}
	std::vector img1s, img2s, nimgs;
	cv::split(img1, img1s);
	cv::split(img2, img2s);
	for (int i(0); i < img1s.size(); ++i)
	{
		cv::Mat img = CHistMatch(img1s[i], img2s[i]);
		nimgs.push_back(img);
	}
	cv::merge(nimgs, nimg);
	return true;
}

int main()
{
	//读
	cv::Mat img1 = cv::imread("data/img1.jpg");
	cv::Mat img2 = cv::imread("data/img2.jpg");
	//做
	cv::Mat nimg2;
	CHistMatch(img1, img2, nimg2);
	//显
	/*cv::namedWindow("img1", 0);
	cv::namedWindow("img2", 0);
	cv::namedWindow("nimg2", 0);
	cv::imshow("img1", img1);
	cv::imshow("img2", img2);
	cv::imshow("nimg2", nimg2);
	cv::waitKey();*/
	//存
	cv::imwrite("data/nimg2.jpg", nimg2);
}

 

你可能感兴趣的:(图像处理,opencv,计算机视觉)