opencv3编程入门(第九章9.1-9.5)

9.2绘制H-S直方图

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
	Mat srcImage, hsvImage;
	srcImage = imread("huashan.jpg");
	cvtColor(srcImage, hsvImage, COLOR_BGR2HSV);//转化为HSV颜色模型
	int hueBinNum = 30;//色调的直方图直条数量(色调量级)
	int saturationBinNum = 32;//饱和度的直方图直条数量(饱和度量级)
	int histSize[] = { hueBinNum,saturationBinNum };
	float hueRanges[] = { 0,180 };//色调的变化范围
	float saturationRanges[] = { 0,256 };//饱和度的变化范围
	const float* ranges[] = { hueRanges,saturationRanges };
	MatND dstHist;
	int channels[] = { 0,1 };//calcHist函数将计算第0和第1通道的直方图
	calcHist(&hsvImage, 1, channels, Mat(), dstHist, 2, histSize, ranges, true, false);
	//以上参数含义:输入的数组、数组个数为1、通道索引、不使用掩膜、输出的目标直方图
	//2表示:计算的直方图的维度、存放每个维度的直方图尺寸的数组、每一维的取值范围、最后两个为bool值.
	double maxValue = 0;
	minMaxLoc(dstHist, 0, &maxValue, 0, 0);
	int scale = 10;
	Mat histImag = Mat::zeros(saturationBinNum*scale, hueBinNum * 10, CV_8UC3);
	//双层循环进行直方图的绘制
	for(int hue=0;hue<hueBinNum;hue++)
		for (int saturation = 0;saturation < saturationBinNum;saturation++)
		{
			float binValue = dstHist.at<float>(hue, saturation);//直方图直条的值
			int intensity = cvRound(binValue * 255 / maxValue);//强度
			//进行绘制
			rectangle(histImag, Point(hue*scale, saturation*scale),
				Point((hue + 1)*scale - 1, (saturation + 1)*scale - 1), Scalar::all(intensity), FILLED);
		}
	imshow("素材图", srcImage);
	imshow("H-S直方图", histImag);
	waitKey();
}

程序执行结果如图:
在这里插入图片描述
9.24计算并绘制图像一维直方图:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
	Mat srcImage = imread("huashan.jpg", 0);
	imshow("原图", srcImage);
	if (!srcImage.data) { cout << "fail to load image" << endl;return false; }
	MatND dstHist;
	int dims = 1;
	float hranges[] = { 0,255 };
	const float *ranges[] = { hranges };
	int size = 256;
	int channels = 0;//函数计算第0通道的直方图
	calcHist(&srcImage, 1, &channels, Mat(), dstHist, dims, &size, ranges);
	int scale = 1;
	Mat dstImage(size*scale, size, CV_8U, Scalar(0));
	double minValue = 0;
	double maxValue = 0;
	minMaxLoc(dstHist, &minValue, &maxValue, 0, 0);
	int hpt = saturate_cast<int>(0.9*size);//绘制直方图
	for (int i = 0;i < 256;i++)
	{
		float binValue = dstHist.at<float>(i);
		int realValue = saturate_cast<int>(binValue*hpt / maxValue);
		rectangle(dstImage, Point(i*scale, size - 1),
			Point((i + 1)*scale - 1, size - realValue), Scalar::all(255));
	}
	imshow("一维直方图", dstImage);
	waitKey(0);
	return 0;
}

程序执行效果如图:
在这里插入图片描述
9.25绘制RGB三色直方图:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
	Mat srcImage = imread("huashan.jpg");
	imshow("原图", srcImage);
	if (!srcImage.data) { cout << "fail to load image" << endl;return 0; }
	int bins = 256;
	int hist_size[] = { bins };
	float range[] = { 0,256 };
	const float*ranges[] = { range };
	MatND redHist,blueHist,greenHist;
	//分别进行R、G、B的直方图计算
	int channels_r[] = { 0 };
	calcHist(&srcImage, 1, channels_r, Mat(), redHist, 1, hist_size, ranges,true,false);
	int channels_g[] = { 1 };
	calcHist(&srcImage, 1, channels_g, Mat(), greenHist, 1, hist_size, ranges, true, false);
	int channels_b[] = { 2 };
	calcHist(&srcImage, 2, channels_b, Mat(), blueHist, 1, hist_size, ranges, true, false);
	double maxValue_red, maxValue_green, maxValue_blue;
	minMaxLoc(redHist, 0, &maxValue_red, 0, 0);
	minMaxLoc(greenHist, 0, &maxValue_green, 0, 0);
	minMaxLoc(blueHist, 0, &maxValue_blue, 0, 0);
	int scale = 1;
	int histHeight = 256;
	Mat histImage = Mat::zeros(histHeight, bins * 3, CV_8UC3);
	//开始绘制直方图
	for (int i = 0;i < bins;i++)
	{
		float binValue_red = redHist.at<float>(i);
		float binValue_green = greenHist.at<float>(i);
		float binValue_blue = blueHist.at<float>(i);
		int intensity_red = cvRound(binValue_red*histHeight / maxValue_red);
		//cvRound():返回跟参数最接近的整数值,即四舍五入;
		int intensity_green = cvRound(binValue_green*histHeight / maxValue_green);
		int intensity_blue = cvRound(binValue_blue*histHeight / maxValue_blue);
		//分别绘制三色分量的直方图
		rectangle(histImage, Point(i*scale, histHeight - 1),
			Point((i + 1)*scale - 1, histHeight-intensity_red), Scalar(255,0,0));
		rectangle(histImage, Point((i+bins)*scale, histHeight - 1),
			Point((i +bins+ 1)*scale - 1, histHeight - intensity_green), Scalar(0, 255, 0));
		rectangle(histImage, Point((i+bins*2)*scale, histHeight - 1),
			Point((i +bins*2+ 1)*scale - 1, histHeight - intensity_blue), Scalar( 0, 0,255));
	}
	imshow("图像的RGB直方图", histImage);
	waitKey(0);
	return 0;
}

程序执行结果如图:
在这里插入图片描述
9.3直方图对比:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
	Mat srcImage_base, hsvImage_base;
	Mat srcImage_test1, hsvImage_test1;
	Mat srcImage_test2, hsvImage_test2;
	Mat hsvImage_halfDown;
	srcImage_base = imread("tsg.jpg");
	srcImage_test1 = imread("1.jpg", 1);
	srcImage_test2 = imread("2.jpg", 1);
	imshow("基准图像", srcImage_base);
	imshow("测试图像1", srcImage_test1);
	imshow("测试图像2", srcImage_test2);
	cvtColor(srcImage_base, hsvImage_base, COLOR_BGR2HSV);
	cvtColor(srcImage_test1, hsvImage_test1, COLOR_BGR2HSV);
	cvtColor(srcImage_test2, hsvImage_test2, COLOR_BGR2HSV);
	//创建包含基准图像下半部的半身图像
	hsvImage_halfDown = hsvImage_base(Range(hsvImage_base.rows / 2,
		hsvImage_base.rows - 1), Range(0, hsvImage_base.cols - 1));
	int h_bins = 50;int s_bins = 60;
	int histSize[] = { h_bins,s_bins };
	float h_ranges[] = { 0,256 };
	float s_ranges[] = { 0,180 };
	const float*ranges[] = { h_ranges,s_ranges };
	int channels[] = { 0,1 };//使用第0和第1通道
	MatND baseHist, halfDownHist, testHist1, testHist2;//创建储存直方图的MATND类
	//计算直方图并归一化
	calcHist(&hsvImage_base, 1, channels, Mat(), baseHist, 2, histSize, ranges, true, false);
	normalize(baseHist, baseHist, 0, 1, NORM_MINMAX, -1, Mat());
	calcHist(&hsvImage_halfDown, 1, channels, Mat(), halfDownHist, 2, histSize, ranges, true, false);
	normalize(halfDownHist, halfDownHist, 0, 1, NORM_MINMAX, -1, Mat());
	calcHist(&hsvImage_test1, 1, channels, Mat(), testHist1, 2, histSize, ranges, true, false);
	normalize(testHist1, testHist1, 0, 1, NORM_MINMAX, -1, Mat());
	calcHist(&hsvImage_test2, 1, channels, Mat(), testHist2, 2, histSize, ranges, true, false);
	normalize(testHist2, testHist2, 0, 1, NORM_MINMAX, -1, Mat());
	for (int i = 0;i < 4;i++)//循环依次使用4种直方图对比方法
	{
		int compare_method = i;
		double base_base = compareHist(baseHist, baseHist, compare_method);
		double base_half = compareHist(baseHist, halfDownHist, compare_method);
		double base_test1 = compareHist(baseHist, testHist1, compare_method);
		double base_test2 = compareHist(baseHist, testHist2, compare_method);
		printf("方法[%d]的匹配结果如下:\n基准图-基准图:%f,基准图-半身图:%f,基准图-测视图1:%f,基准图-测试图2:%f\n"
			, i, base_base, base_half, base_test1, base_test2);
	}
	printf("检测结束,");
	waitKey();
	return 0;
}
	

原图2:
在这里插入图片描述

程序执行结果如图:
在这里插入图片描述
9.4:反向投影:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "原始图"
Mat g_srcImage, g_hsvImage, g_hueImage;
int g_bins = 30;//直方图组距
void on_BinChange(int, void*);
int main()
{
	g_srcImage = imread("sz.jpg", 1);
	if (!g_srcImage.data) { cout << "fail to load image" << endl;return 0; }
	cvtColor(g_srcImage, g_hsvImage, COLOR_BGR2HSV);
	//分离Hue色调通道
	g_hueImage.create(g_hsvImage.size(), g_hsvImage.depth());
	int ch[] = { 0,0 };
	mixChannels(&g_hsvImage, 1, &g_hueImage, 1, ch, 1);
	//以上参数含义依次是:输入的数组(需要相同的大小和深度)、src输入的矩阵数、输出数组、输出的矩阵数
	//对指定通道进行复制的数组索引、第五个参数的索引数。
	namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
	createTrackbar("色调组距", WINDOW_NAME1, &g_bins, 180, on_BinChange);
	on_BinChange(0, 0);
	imshow("WINDOW_NAME1", g_srcImage);
	waitKey(0);
	return 0;
}
void on_BinChange(int,void*)
{
	MatND hist;
	int histSize = MAX(g_bins, 2);
	float hue_range[] = { 0,180};
	const float*ranges = { hue_range };
	calcHist(&g_hueImage, 1, 0, Mat(), hist, 1, &histSize, &ranges, true, false);
	normalize(hist,hist,0, 255, NORM_MINMAX, -1, Mat());
	MatND backproj;//每一维数值的取值范围
	calcBackProject(&g_hueImage, 1, 0, hist, backproj, &ranges, 1, true);//计算反向投影
	imshow("反向投影", backproj);
	int w = 400;int h = 400;
	int bin_w = cvRound((double)w / histSize);
	Mat histImage = Mat::zeros(w, h, CV_8UC3);
	for (int i = 0;i < g_bins;i++)
	{
		//绘制直方图
		rectangle(histImage, Point(i*bin_w, h), Point((i + 1)*bin_w,
			h - cvRound(hist.at<float>(i)*h / 255)), Scalar(100, 123, 255), -1);
	}
	imshow("直方图", histImage);
}

程序执行结果如图;
在这里插入图片描述
9.5模板匹配:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
using namespace cv;
using namespace std;
#define WINDOW_NAME1 "原始图"
#define WINDOW_NAME2 "效果图"
Mat g_srcImage, g_templateImage, g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;
void on_Matching(int, void*);
int main()
{
	g_srcImage = imread("ying.jpg", 1);
	g_templateImage = imread("test.jpg", 1);
	imshow("template", g_templateImage);
	namedWindow(WINDOW_NAME1, WINDOW_AUTOSIZE);
	namedWindow(WINDOW_NAME2, WINDOW_AUTOSIZE);
	createTrackbar("方法", WINDOW_NAME1, &g_nMatchMethod, g_nMaxTrackbarNum, on_Matching);
	on_Matching(0, 0);
	waitKey(0);
	return 0;
}
void on_Matching(int, void*)
{
	Mat srcImage;
	g_srcImage.copyTo(srcImage);
	int resultImage_rows = g_srcImage.rows - g_templateImage.rows + 1;
	int resultImage_cols = g_srcImage.cols - g_templateImage.cols + 1;
	g_resultImage.create(resultImage_rows, resultImage_cols, CV_32FC1);
	//进行匹配和标准化
	matchTemplate(g_srcImage, g_templateImage, g_resultImage, g_nMatchMethod);
	normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
	double minValue, maxValue;
	Point minLocation;Point maxLocation;
	Point matchLocation;
	//通过minMaxLoc定位最匹配的位置
	minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());
	//对于方法TM_SQDIFF和TM_SQDIFF_NORMED,越小的数值匹配度越高,其余的数值越大匹配度越高
	if (g_nMatchMethod == TM_SQDIFF || g_nMatchMethod == TM_SQDIFF_NORMED)
	{
		matchLocation = minLocation;
	}
	else { matchLocation = maxLocation; }
	//绘制矩形
	rectangle(srcImage, matchLocation, Point(matchLocation.x + g_templateImage.cols,
		matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
	rectangle(g_resultImage, matchLocation, Point(matchLocation.x + g_templateImage.cols,
		matchLocation.y + g_templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
	imshow("WINDOW_NAME1", srcImage);
	imshow("WINDOW_NAME2", g_resultImage);

}

程序执行结果如图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值