图片中数字的分割

参考: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;
}

程序效果如下:


原图为:







你可能感兴趣的:(图片中数字的分割)