//图像预处理第6步:分割,并在分割出来的字符外面画框以标识 void CChildView::OnImgprcDivide() { m_charRect=CharSegment(m_hDIB); //在屏幕上显示位图 CDC* pDC=GetDC(); DisplayDIB(pDC,m_hDIB); DrawFrame(pDC,m_hDIB,m_charRect,2,RGB(20,60,200)); }
// 阈值分割 vector<CharSegment> OCR::segment(Plate plate) { Mat input = plate.plateImg; vector<CharSegment> output; Mat thresholdImage; threshold(input, thresholdImage, 60, 255, CV_THRESH_BINARY_INV); if (DEBUG) imshow("Threshold plate", thresholdImage); Mat img_contours; thresholdImage.copyTo(img_contours); // 找到可能的车牌的轮廓 vector< vector< Point> > contours; findContours(img_contours, contours, // 检测的轮廓数组,每一个轮廓用一个point类型的vector表示 CV_RETR_EXTERNAL, // 表示只检测外轮廓 CV_CHAIN_APPROX_NONE); // 轮廓的近似办法,这里存储所有的轮廓点 // 在白色的图上画出蓝色的轮廓 cv::Mat result; thresholdImage.copyTo(result); cvtColor(result, result, CV_GRAY2RGB); cv::drawContours(result, contours, -1, // 所有的轮廓都画出 cv::Scalar(255, 0, 0), // 颜色 1); // 线粗 // 对每个轮廓检测和提取最小区域的有界矩形区域 vector<vector<Point> >::iterator itc = contours.begin(); char res[20]; int i = 0; // 若没有达到设定的宽高比要求,移去该区域 while (itc != contours.end()) { Rect mr = boundingRect(Mat(*itc)); rectangle(result, mr, Scalar(0, 255, 0)); // 裁剪图像 Mat auxRoi(thresholdImage, mr); if (verifySizes(auxRoi)) { auxRoi = preprocessChar(auxRoi); output.push_back(CharSegment(auxRoi, mr)); //保存每个字符图片 sprintf(res, "PlateNumber%d.jpg", i); i++; imwrite(res, auxRoi); rectangle(result, mr, Scalar(0, 125, 255)); } ++itc; } if (DEBUG) cout << "Num chars: " << output.size() << "\n"; if (DEBUG) imshow("SEgmented Chars", result); return output; }
//Segment the chars from plate vector<CharSegment> OCR::segment(Plate plate){ Mat input=plate.plateImg; vector<CharSegment> output; //Threshold input image Mat img_threshold; //To make char image clearly // threshold(input, img_threshold, 60, 255, CV_THRESH_BINARY_INV); //Spain // threshold(input, img_threshold, 150~160, 255, CV_THRESH_BINARY); //China // TODO: IMPORTANT threshold(input, img_threshold, 175, 255, CV_THRESH_BINARY); //China if(debug) { imshow("OCR_Threshold_Binary", img_threshold); } Mat img_contours; img_threshold.copyTo(img_contours); //Find contours of possibles characters vector< vector< Point> > contours; findContours(img_contours, contours, // a vector of contours CV_RETR_EXTERNAL, // retrieve the external contours CV_CHAIN_APPROX_NONE); // all pixels of each contours // Draw blue contours on a white image cv::Mat result; img_threshold.copyTo(result); cvtColor(result, result, CV_GRAY2RGB); cv::drawContours(result, contours, -1, // draw all contours cv::Scalar(255,0,0), // in BLUE 1); // with a thickness of 1 //Start to iterate to each contour founded vector<vector<Point> >::iterator itc = contours.begin(); //Remove patch that are no inside limits of aspect ratio and area. while (itc!=contours.end()) { //Create bounding rect of object Rect mr = boundingRect(Mat(*itc)); rectangle(result, mr, Scalar(0,255,0)); //Possible chars in GREEN //Crop image Mat auxRoi(img_threshold, mr); if(verifySizes(auxRoi)){ auxRoi=preprocessChar(auxRoi); output.push_back(CharSegment(auxRoi, mr)); rectangle(result, mr, Scalar(0,0,255)); //Possible chars in RED } ++itc; } if(debug) { cout << "OCR number of chars: " << output.size() << "\n"; imshow("OCR Chars", result); cvWaitKey(0); } return output; }