圖像處理_Opencv的霍夫(Hough)圓檢測定位、字符匹配、字符識別

我的圖像處理課程的一個實驗。

一.任務

識別字符:
在這裏插入圖片描述

二.使用平臺

Windows10專業版
VS2015企業版
C++ opencv3.2

三.圖像處理的思路

1.先定位感興趣區域(字符區域)

定位有兩種方法,一種是定位圓,另一種是定位直線
在這裏插入圖片描述

2.然後模版匹配(matchTemplate)

模版匹配需要做好模版。將感興趣區域找出後,可以採用像素投影分割法,將每個字符分割出來保存到本地文件夾做樣本。
在這裏插入圖片描述

四.圖像處理

整個流程:
1.讀入圖像
2.轉爲灰度
3.中值濾波
4.固定閾值二值化。(因爲我定位的是圓)
5.霍夫圓檢測找到圓心
6.根據圓心剪裁感興趣區域
7.讀取本地文件夾樣本
8.進行模版匹配
9.標出模板匹配結果

圖像:

1.轉爲灰度中值濾波

灰度後中值濾波

2.二值化後霍夫圓檢測

二值化、霍夫圓檢測

3.根據圓心座標裁出字符區域

感興趣區域

3.模版匹配後標記結果

結果

代碼:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>
#include <string>
using namespace cv;
using namespace std;

Mat src, dst, gray, binImg;
Mat eImage;

int main(int argc, char** argv)
{
	src = imread("G:\\U_lesson\\圖像處理\\實驗\\zf1.bmp");

	if (src.empty())
	{
		printf("can not load image....\n");
		return -1;
	}
	// 窗口命名
	namedWindow("test", CV_WINDOW_AUTOSIZE);
	imshow("test", src);

	//中值濾波
	Mat moutput;
	medianBlur(src, moutput, 11);
	imshow("moutput", moutput);

	cvtColor(moutput, gray, CV_BGR2GRAY);

	// 固定閾值二值化
	threshold(gray, binImg, 15, 255, THRESH_BINARY);
	imshow("binImg", binImg);

	// 霍夫圓檢測
	vector<Vec3f> pcircles;
	HoughCircles(binImg, pcircles, CV_HOUGH_GRADIENT, 1, 50, 15, 15, 25, 80);
	src.copyTo(dst);
    
    // 畫圓與圓心
	for (size_t i = 0; i < pcircles.size(); i++)
	{
		Vec3f cc = pcircles[i];
		circle(dst, Point(cc[0], cc[1]), cc[2], Scalar(0, 0, 255), 2, LINE_AA);
		circle(dst, Point(cc[0], cc[1]), 2, Scalar(98, 23, 255), 2, LINE_AA);
		cout << cc << endl;
	}
	imshow("dst", dst);

	 // 簡陋判斷有無圓心座標
	if (pcircles[0][0] > 0 && pcircles[0][1] > 0)
	{
		// 剪裁出字符區域
		int start_x = pcircles[0][0] - 280;
		int start_y = pcircles[0][1] + 80;
		int rect_width = 500;
		int rect_height = 140;
		Rect  rect(start_x, start_y, rect_width, rect_height);
		Mat ROI = src(rect);
		imshow("rect", ROI);

		Mat dst_gray, dst_bin;
		cvtColor(ROI, dst_gray, CV_BGR2GRAY);  

		int height = dst_gray.rows;
		int width = dst_gray.cols;

        // 取出本地文件的樣本
		vector<Mat> character_image;
		char tempstr[12] = { '2','0','1','8','1','2','0','7','2','5','1','C'};
		for (int i = 0; i <= 11; i++)
		{
			string ImgName = "character";
			ImgName = ImgName + to_string(i);
			ImgName = "G:\\U_lesson\\圖像處理\\實驗\\match\\" + ImgName + ".bmp";
			Mat temp = imread(ImgName);
			character_image.push_back(temp);
		}
		
		Mat tmp_dst;
		Mat find_dst;
		dst_gray.copyTo(find_dst);
		cvtColor(find_dst, find_dst, CV_GRAY2BGR);
		// 模版匹配
		for (int i = 0; i <= 11; i++)
		{
			Mat temp;
			cvtColor(character_image[i],temp, CV_BGR2GRAY);

			width = dst_gray.cols - temp.cols + 1;
			height = dst_gray.rows - temp.rows + 1;
			Mat result(width, height, CV_32FC1);

			Point minLoc;
			Point maxLoc;
			double min, max;
			Point temLoc;

			dst_gray.copyTo(tmp_dst);
			matchTemplate(dst_gray, temp, result, CV_TM_CCORR_NORMED, Mat());

			// 找到匹配的最大最小座標
			minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());
			temLoc = maxLoc;
			cout << temLoc << endl;
			
			// 畫出矩形框
			rectangle(find_dst, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
			
			
			string str(1, tempstr[i]);
			putText(find_dst, str, Point(temLoc.x, temLoc.y), FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 255, 0), 1, 8, 0);
			
			cout << tempstr[i] << endl;
			//rectangle(result, Rect(temLoc.x, temLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
		}

		imshow("AAA", find_dst);

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