参考: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; }
程序效果如下:
原图为: