This is a Raspberry Pi run, opencv3.
OPENCV provides a handwritten digital picture to us, as shown, as a sample library for identifying handwritten numbers.
0 to 9 A total of 10 numbers, each number has five lines, a row of 100 digits. First of all, we need to intercept these 5,000 numbers.
The picture size is 1000*2000, and each number block size is 20*20.
1. Intercept samples and store
The following code is the process of intercepting the above numbers and storing them in a matrix
The training data, generally will be two matrices, one matrix holds the data image, the other matrix holds the data image corresponding number
Mat src = imread ("Sample.png"); Mat Grayimage; Cvtcolor (SRC, grayimage, cv_bgr2gray); Threshold (Grayimage, Grayimage, -,255, cv_thresh_binary); intp = -;//a number size of 20*20 intm = grayimage.rows/p;//number of numbers in a rampage m intn = grayimage.cols/p;//Number of columns in the column nMat data, labels;//Data is stored in the sample, and the label is the number corresponding to a data sample. for(inti =0; I < n; i++){ inty = i * p;//position of the beginning of the first digit of the vertical column for(intj =0; J < M; J + +){ intx = J * p;//the position of the first number of rowsMat DST; Grayimage (Range (x,x+ P), Range (y, y +p)). CopyTo (DST); Data.push_back (Dst.reshape (0,1));//change 20*20 size matrix to 1*400 vectorLabels.push_back (J/5);//numbers that correspond to the data vectors stored}} data.convertto (data, cv_32f); //changing the data type of a pixel to a floating-point typeMat Traindata, trainlabels; Traindata= Data (Range (0, the), Range::all ()); Trainlabels= Labels (Range (0, the), Range::all ());
2. Processing images of numbers to be identified
//processing generation detection ImagesMat Image, DST; Image= Imread ("6.png"); Cvtcolor (image, image, Color_bgr2gray); Threshold (image, image, -,255, CV_THRESH_BINARY_INV); Imshow ("Image", Image); Image.copyto (DST); Vector< vector<point> >contours; Vector<Vec4i>hierarchy; Findcontours (image,contours, Hierarchy, cv_retr_external, cv_chain_approx_none); Vector<Point> point = contours[0]; Rect rect=Boundingrect (point); intx = rect.x, y =Rect.y; intH=rect.height, W =Rect.width; Mat Now= DST (Range (x, x+h-1), Range (Y, y+w-1)); //DST (rect). CopyTo (now);Resize (Now,now,size ( -, -));
3. Use the KNN algorithm to identify the image to be recognized as a training sample of the same processing
I am running the program, has been the following error, changed several ways to deal with the picture, still no use
mat_<float> nums; Nums = Now.reshape (0,1); Nums.convertto (Nums, cv_32f); Imshow (" image to be measured ", now) ; /* Mat mm; Mm.push_back (Now.reshape (0,1)); Mm.convertto (mm,cv_32f); Mat nums = mm (Range (0,1), Range::all ()); /*float imagedata[20*20]; for (int i =0; i <, i++) {for (int j=0;j<20;j++) { imagedata[i *20 +j] = now.data[i *20+j]; } } Mat Nums (1,20*20, cv_32f, imagedata); */
The last view of the source code finds no other parameters:
Error Knn->findnearest (nums, 1, Mat ()); 1, temp); // to pass in a specific mat type
The final identification code is
// Create a KNN classifier ptr<ml::knearest> KNN = (Ml::knearest::create ()); KNN->setisclassifier (true); Ptr<ml::TrainData> tdata = ml::traindata::create (traindata,ml::row_sample, trainlabels); KNN---Train (tdata); Mat temp; float 1 , temp); << result<<endl;
Check it out many times and just can't identify all
Program defect: Image processing problem to be detected. Cannot intercept a suitable ROI region
Let's improve.
opencv--recognition of handwritten numerals