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);

輸出結果:

是不是可以用作二維碼識別?

失敗了,原因 模板圖像大小與源圖像上的定位點大小並不同。

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