刚才写了一个识别数字的程序,然后除了7以外的数都识别成功了,先放个问题截图吧,下面会放源码
如图所示,7的位置不是最前也不是最后,顺序逻辑上来讲肯定是没问题的,然后我又独自显示了目标图和模板图片的7的中心,都是在正确的位置上,那应该也排除了轮廓识别错误的问题。
而且我还输出了一下7匹配时的matchShapes(hu2, src_hu, CONTOURS_MATCH_I1, 0);这个函数的返回值,发现每一个值都大的离谱(600-700之间),而其他数字识别时都是最多十几。
实在想不出还有啥办法了,不知道问题出在了哪,恳求各位的帮忙,感激不尽
以下是源码
#include<opencv2/opencv.hpp>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
using namespace cv;
void numbers_template(vector<Point>& contours);
bool comp1(vector<Point>& c1, vector<Point>& c2)
{
Moments m1 = moments(c1);
Moments m2 = moments(c2);
double cx1 = m1.m10 / m1.m00;
double cx2 = m2.m10 / m2.m00;
return cx1 < cx2;
}//自定义vector的升序,以轮廓中心的x值为根据,进行升序。
Mat src = imread("D:/picture/numbers.png");
int main()
{
if (src.empty())
{
cout << "图片加载失败" << endl;
return -1;
}
imshow("原图", src);
//二值化图片
Mat gray, binary;
GaussianBlur(src, src, Size(3, 3), 1.0);
cvtColor(src, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
imshow("二值化", binary);
//提取图片轮廓
vector<vector<Point>>contours;
vector<Vec4i>hierarchy;
findContours(binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());//获取的轮廓不是从左到右依次排序的
sort(contours.begin(), contours.end(), comp1);
cout << "识别的结果为\t";
for (size_t t = 0; t < contours.size(); t++)//轮廓处理
{
drawContours(src, contours, t, Scalar(0, 0, 255), 1, 8);
numbers_template(contours[t]);
}
imshow("提取轮廓后", src);
waitKey(0);
destroyAllWindows();
return 0;
}
void numbers_template(vector<Point>& contours)
{
//计算输入进来原图轮廓的弧距
Moments src_mm = moments(contours);
Mat src_hu;
HuMoments(src_mm, src_hu);
//模板图片的轮廓发现
Mat image = imread("D:/picture/allnum.PNG");
Mat gray, binary;
GaussianBlur(image, image, Size(3, 3), 1.0);
cvtColor(image, gray, COLOR_BGR2GRAY);
threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);
vector<vector<Point>>contours2;
vector<Vec4i>hierarchy;
findContours(binary, contours2, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
drawContours(image, contours2, -1, Scalar(0, 0, 255), 1, 8);
sort(contours2.begin(), contours2.end(), comp1);
imshow("模板图片的轮廓", image);
//原图的轮廓与模板图片每一个轮廓的弧距进行对比
for (size_t t = 0; t < contours2.size(); t++)
{
Moments mm2 = moments(contours2[t]);
Mat hu2;
HuMoments(mm2, hu2);
double dist = matchShapes(hu2, src_hu, CONTOURS_MATCH_I1, 0);
if (dist < 0.5)
{
double cx = src_mm.m10 / src_mm.m00;//中心位置的x
double cy = src_mm.m01 / src_mm.m00;//中心位置的y
putText(src, format("%d", t), Point(cx, cy+50), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 255, 0), 2);
cout << t << '\t';
}
}
}