代码如下
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
Mat source;
const int NUM = 10000;
void getNumChar(Mat &Output);
int main(int argc, char ** argv)
{
Mat dst1, dst2, Output;
Mat src = imread("D:/profession/visual studio/test1/81.jpg");
if (src.empty())
{
printf("could not load image...\n");
return -1;
}
cvtColor(src, src, COLOR_BGR2GRAY);
bilateralFilter(src, dst1, 25, 50, 3);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(dst1, dst2, dst1.depth(), kernel);
threshold(dst2, Output, 0, 255, THRESH_OTSU | THRESH_BINARY);
vector<Vec3f> pcircles;
HoughCircles(dst1, pcircles, HOUGH_GRADIENT, 1.5, 20, 150, 200, 0, 0);
if (pcircles[0][2] != 0)
{
printf("仪表盘\n");
}
else if (pcircles[0][2] == 0)
{
Mat image = Output.clone();
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(image, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);//找出图片外轮廓,不要连内轮廓也找出来
Rect rc[NUM];
int t = 0;
for (int i = 0; i < contours.size(); i++)
{
rc[i] = boundingRect(contours.at(i));//boundingRect()计算轮廓的垂直边界最小矩形,矩形是与图像上下边界平行的
t++;
}
//由于轮廓顺序不是字符顺序所以要排序,主要根据矩形左上方坐标排序,排序从左到右
for (int i = 0; i < t; i++)
{
for (int j = i+1; j < t; j++)
{
if (rc[i].x>rc[j].x)
{
Rect temp = rc[i];
rc[i] = rc[j];
rc[j] = temp;
}
}
}
//把排序后的图片一一识别
for (int i = 0; i < contours.size(); i++)
{
Mat ROI = Output(rc[i]);
getNumChar(ROI);
}
}
waitKey(0);
return 0;
}
//识别数字
void getNumChar(Mat &source)
{
for (int i = 0; i < 10; i++)
{
int result_num[] = { 0,1,2,3,4,5,6,7,8,9 };
char buf[10];
Mat L1;
Mat temp = imread(buf);
cvtColor(temp, temp, COLOR_BGR2GRAY);
bilateralFilter(temp, temp, 25, 50, 3);
Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
filter2D(temp, temp, temp.depth(), kernel);
threshold(temp, temp, 0, 255, THRESH_OTSU | THRESH_BINARY);
int width = source.cols - temp.cols + 1;
int height = source.rows - temp.rows + 1;
Mat result(width, height, CV_32FC1);
matchTemplate(source, temp, result, CV_TM_SQDIFF, Mat());//模板匹配
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
Point minLoc;
Point maxLoc;
double min,max;
minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());
if (min < 1)
{
cout << result_num[i];
}
}
}
|