OpenCV笔记(三)--直方图与模板匹配

直方图定义:

直方图均衡化-提高对比度-cv::equalizeHist

void equalizeHist( InputArray src, OutputArray dst ); //输入为八位灰度图像

从图片建立直方图-split,calcHist

api:

void split(const Mat& src, Mat* mvbegin);//三Mat图像转化为三个图像
void calcHist( const Mat* images,     //输入图像
               int nimages,           //图像数目
               const int* channels,   //通道数
               InputArray mask,       //可选择图像中哪些像素参与直方图计算,不使用填noArray()
               OutputArray hist,      //输出直方图数据
               int dims,              //维数
               const int* histSize,   //直方图级数
               const float** ranges,  //值域范围
               bool uniform = true, bool accumulate = false );

实战:

	vector<Mat> bgr_plances;
	split(src, bgr_plances);

	int histSize = 256;
	float range[] = { 0,256 };
	const float *histRanges = { range };
	Mat b_hist, g_hist, r_hist;
	calcHist(&bgr_plances[0], 1, 0, noArray(), b_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&bgr_plances[1], 1, 0, noArray(), g_hist, 1, &histSize, &histRanges, true, false);
	calcHist(&bgr_plances[2], 1, 0, noArray(), r_hist, 1, &histSize, &histRanges, true, false);

	int hist_h = 400;
	int hist_w = 512;
	int bin_w = hist_w / histSize;
	Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0));
	normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, noArray());
	normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, noArray());
	normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, noArray());

	for (size_t i = 1; i < histSize; i++)
	{
		line(histImage, Point((i - 1)*bin_w, hist_h - int(b_hist.at<float>(i - 1))),
			Point((i)*bin_w, hist_h - int(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);

		line(histImage, Point((i - 1)*bin_w, hist_h - int(g_hist.at<float>(i - 1))),
			Point((i)*bin_w, hist_h - int(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);

		line(histImage, Point((i - 1)*bin_w, hist_h - int(r_hist.at<float>(i - 1))),
			Point((i)*bin_w, hist_h - int(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
	}

	imshow("output", histImage);

直方图比较

对两个图像直方图求相关性,相关性高则可能是相同或相似的图片

 double compareHist( const SparseMat& H1, const SparseMat& H2, int method );
                    //输入                 输出                 比较方法
CV_COMP_CORREL 相关性方法 1
CV_COMP_CHISQR_ALT 卡方方法 1
CV_COMP_INTERSECT 交集法 1
CV_COMP_BHATTACHARYYA 巴氏距离 0

反向投影

暂时没看懂

模板匹配

源图像每个小块都与模板图像进行相关度计算,相关度最高的地方匹配

void matchTemplate( InputArray image, InputArray templ,  //源图像与模板图像
                    OutputArray result,  //输出结果,单通道32位浮点数,
                                         //width=W-w+1,height=H-h+1                
                    int method,          //匹配方法
                    InputArray mask = noArray() );

 

匹配方法 输入 完全匹配
方差匹配 TM_SQDIFF 0
归一化方差匹配 TM_SQDIFF_NORMED 0
相关性匹配 TM_CCORR 很大的数
归一化的互相关匹配 TM_CCORR_NORMED 1
相关系数匹配 TM_CCOEFF 1(误匹配-1)
归一化相关系数匹配 TM_CCOEFF_NORMED 1

尝试匹配二维码的三个定位点

    int width = src.cols - temp.cols;
	int height = src.rows - temp.rows;
	Mat result(width, height, CV_32FC1);

	matchTemplate(src, temp, result, CV_TM_SQDIFF_NORMED,Mat());

	Point minLoc, maxLoc;
	double min, max;
	src.copyTo(dst);
	for (size_t i = 0; i < 3; i++)
	{
		minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());
		rectangle(dst, Rect(minLoc.x, minLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
		rectangle(result, Rect(minLoc.x, minLoc.y, temp.cols, temp.rows), Scalar(255, 255, 255), 8, 8);
	}


	imshow("result", result);
	imshow("Output_Image", dst);

输出结果:

是不是可以用作二维码识别?

失败了,原因 模板图像大小与源图像上的定位点大小并不同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章