图像直方图、模板匹配

目录

1、图像直方图

1.1 直方图统计

 1.2 直方图像素统计

 1.3 直方图绘制

2、直方图均衡化

2.1 实现

2.2 效果

3、直方图匹配

3.1 匹配原理

 3.2 实现

4、模板匹配

4.1 模板匹配

4.2 模板匹配函数

 4.3 模板匹配方法标志

 4.4 代码实现

1、图像直方图

1.1 直方图统计

 1.2 直方图像素统计

 1.3 直方图绘制

//直方图绘制
int test1()
{
	Mat img = imread("F:/testMap/lena.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat gray;
	cvtColor(img, gray, COLOR_BGR2GRAY);//设置提取直方图的相关变量
	Mat hist; //用于存放直方图计算结果
	const int channels[1] = { 0 };//通道索引
	const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值
	float inRanges[2] = { 0, 255 };
	const float* ranges[1] = { inRanges }; //像素灰度值范围
	calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges);//计算图像直方图

	//准备绘制直方图
	int hist_w = 512;
	int hist_h = 400;
	int width = 2;
	Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	//for (int i = 1; i <= hist.rows; i++)
	//{
	//	rectangle(histImage, Point(width*(i - 1), hist_h - 1),
	//		Point(width*i - 1, hist_h - cvRound(hist.at<float>(i - 1) / 15)),
	//		Scalar(255, 255, 255), -1);
	//}

	Mat hist_INF;
	normalize(hist, hist_INF, 1, 0, NORM_INF, -1, Mat());//归一化
	for (int i = 1; i <= hist_INF.rows; i++)
	{
		rectangle(histImage, Point(width*(i - 1), hist_h - 1),
			Point(width*i - 1, hist_h - cvRound(hist_h*hist_INF.at<float>(i - 1)) - 1), Scalar(255, 255, 255), -1);
	}

	imshow("histImage", histImage);
	imshow("gray", gray);
	waitKey(0);
}

2、直方图均衡化

2.1 实现

 

//直方图均衡化
void drawHist(Mat &hist, int type, string name)//归一化并绘制直方图函数
{
	int hist_w = 512;
	int hist_h = 512;
	int width = 2;
	Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	normalize(hist, hist, 1, 0, type, -1, Mat());
	for (int i = 1; i <= hist.rows; i++)
	{
		rectangle(histImage, Point(width*(i - 1), hist_h - 1),
			Point(width*i - 1, hist_h - cvRound(hist_h*hist.at<float>(i - 1)) - 1),
			Scalar(255, 255, 255), -1);
	}
	imshow(name, histImage);
}
int test2()
{
	Mat img = imread("F:/testMap/hist.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat gray, hist, hist2;
	cvtColor(img, gray, COLOR_BGR2GRAY);

	Mat equalImg;
	equalizeHist(gray, equalImg); //将图像直方图均衡化
	const int channels[1] = { 0 };
	float inRanges[2] = { 0, 255 };
	const float* ranges[1] = { inRanges };
	const int bins[1] = { 256 };
	calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges);
	calcHist(&equalImg, 1, channels, Mat(), hist2, 1, bins, ranges);
	drawHist(hist, NORM_INF, "hist");
	drawHist(hist2, NORM_INF, "hist2");
	
	imshow("原图", gray);
	imshow("均衡化后的图像", equalImg);
}

2.2 效果

显示更加清晰的纹理信息

 

 

3、直方图匹配

3.1 匹配原理

 3.2 实现


void drawHist(Mat &hist, int type, string name)//归一化并绘制直方图函数
{
	int hist_w = 512;
	int hist_h = 512;
	int width = 2;
	Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
	normalize(hist, hist, 1, 0, type, -1, Mat());
	for (int i = 1; i <= hist.rows; i++)
	{
		rectangle(histImage, Point(width*(i - 1), hist_h - 1),
			Point(width*i - 1, hist_h - cvRound(20*hist_h*hist.at<float>(i - 1)) - 1),//20* 改变直方图的高度
			Scalar(255, 255, 255), -1);
	}
	imshow(name, histImage);
}
//直方图匹配
int test3()
{
	Mat img1 = imread("F:/testMap/hist.png");
	Mat img2 = imread("F:/testMap/lena.png");
	if (img1.empty() || img2.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat hist1, hist2;
	//计算两张图像直方图
	const int channels[1] = { 0 };
	float inRanges[2] = { 0, 255 };
	const float* ranges[1] = { inRanges };
	const int bins[1] = { 256 };
	calcHist(&img1, 1, channels, Mat(), hist1, 1, bins, ranges);
	calcHist(&img2, 1, channels, Mat(), hist2, 1, bins, ranges);

	//归一化两张图像的直方图
	drawHist(hist1, NORM_L1, "hist1");
	drawHist(hist2, NORM_L1, "hist2");

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

	//构建累积概率误差矩阵
	float diff_cdf[256][256];
	for (int i = 0; i < 256; i++)
	{
		for (int j = 0; j < 256; j++)
		{
			diff_cdf[i][j] = fabs(histl_cdf[i] - hist2_cdf[j]);
		}
	}

	//生成LUT映射表
	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 = 1; j < 256; j++)
		{
			if (min > diff_cdf[i][j])
			{
				min = diff_cdf[i][j];
				index = j;
			}
			lut.at<uchar>(i) = (uchar)index;
		}
	}

	Mat result,hist3;
	LUT(img1,lut,result); 
	imshow("待匹配图像",img1);
	imshow("匹配的模板图像",img2);
	imshow("直方图匹配结果", result);
	calcHist(&result,1,channels, Mat(), hist3,1, bins,ranges); 
	drawHist(hist3,NORM_L1,"hist3");//绘制匹配后的图像直方图
	waitKey(0);
	return 0;
}

4、模板匹配

4.1 模板匹配

 

4.2 模板匹配函数

 4.3 模板匹配方法标志

0 1标志匹配结果越大说明越不匹配

 4.4 代码实现

//模板匹配
int test4()
{
	Mat img = imread("F:/testMap/lena.png");
	Mat temp = imread("F:/testMap/lenaFace.png");
	Mat result;

	matchTemplate(img,temp,result,TM_CCOEFF_NORMED); 
	double maxVal,minVal;

	Point maxLoc,minLoc;
	minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

	rectangle(img,Point(maxLoc.x,maxLoc.y),Point(maxLoc.x + temp.cols,maxLoc.y + temp.rows),Scalar(0,0,255),2);
	
	imshow("原图像", img);
	imshow("模板", temp);
	imshow("result", result);
	waitKey(0);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhang丶&|!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值