参考:http://icodeit.org/2013/01/basic-digits-recognization/
当一张图中出现多个数字时,需要先将数字单独分割出来,然后再一 一 识别
采用的是轮廓大小判断法 来判断是否有数字
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/ml/ml.hpp>
#include <vector>
using namespace std;
using namespace cv;
void mycanny(cv::Mat& img, cv::Mat& out)
{
// Convert to gray
cv::cvtColor(img,out,CV_BGR2GRAY);
// Compute Canny edges
cv::Canny(out,out,100,200);
// Invert the image
cv::threshold(out,out,128,255,cv::THRESH_BINARY_INV);
}
int main()
{
/
Mat org=imread("865_origin.png",1);
imshow("865_origin.png",org);
//*************************************预处理*************************************///
Mat out ;
cvtColor(org,out,COLOR_BGR2GRAY);
threshold(out,out, 48, 255, CV_THRESH_BINARY_INV);
//由于轮廓检测算法需要从黑色的背景中搜索白色的轮廓,所有此处的threshold最后一项参数为cv.CV_THRESH_BINARY_INV,即反转黑白色。
imshow("threshold",out);
medianBlur(out,out,3);//中值滤波
Mat yuchuli=out.clone() ;
imshow("预处理结果",yuchuli);
//*************************************轮廓查找*************************************
vector<vector<Point>>contours;
findContours(out,contours, RETR_EXTERNAL,CHAIN_APPROX_SIMPLE);//查找所有外轮廓,输入图像必须为二值图
Mat lunkuo=org.clone();
drawContours(lunkuo,contours,-1,Scalar(0,0,255),1);// 画出所有轮廓
// imshow(" 画出所有轮廓",lunkuo);
/画出质心
//std::vector<std::vector<cv::Point>>::const_iterator itc= contours.begin();
//while (itc!=contours.end()) {
// // compute all moments
// cv::Moments mom= cv::moments(cv::Mat(*itc++));
// // draw mass center
// cv::circle(img,
// // position of mass center converted to integer
// cv::Point(mom.m10/mom.m00,mom.m01/mom.m00),
// 2,cv::Scalar(0),2); // draw black dot
//}
//cv::namedWindow("Some Shape descriptors");
//cv::imshow("Some Shape descriptors",img);
//Mat result(img.size(),CV_8UC3,Scalar(255,255,255));
//*************************************剔除超过范围的轮廓*************************************///
Mat result=org.clone();
vector<std::vector<cv::Point>>::const_iterator itc= contours.begin();
int cmin=50,cmax=500; //剔除超过范围的轮廓
while (itc!=contours.end()) {
cout<<itc->size() <<endl;
if (itc->size() < cmin || itc->size() > cmax)
itc= contours.erase(itc);
else
++itc;
}
//*************************************画出各个轮廓的最小包围矩形************************************///
for (int i=0;i<contours.size();i++)
{
Rect r =boundingRect(Mat(contours[i]));
rectangle(lunkuo,r,Scalar(0,255,0),1);
}
imshow("矩形框定位置",lunkuo);
//************************************* 切割出定位的矩形************************************///
char filenamew[255];
sprintf(filenamew,"定位矩形");
char rectnum[255];
char file[255];
Mat pic;
for (int i=0;i<contours.size();i++)
{
sprintf(file,"%s%d",filenamew,i);
sprintf(rectnum,"%s%d.bmp",filenamew,i);
Rect r =boundingRect(Mat(contours[i]));
pic=yuchuli(r);//选定roi
// resize(pic,pic,Size(128,128));//把切割的图片缩放成1128*1128
imwrite(rectnum,pic);
imshow(file,pic);
}
//************退出程序**************///
waitKey();
return 0;
}
程序效果如下:
原图为: