我的图像处理课程的一个实验。
一.任务
识别字符:
二.使用平台
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;
}
被抛弃的写随笔公众号改写技术文章了,感兴趣的可以关注公众号:王崇卫