SHARE
TWEET

Part 2: Classifying characters

MichaelYoung Jan 12th, 2013 2,738 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ayoungprogrammer.blogspot.com
  3.  
  4. Part 2: Training: Classifying characters
  5. */
  6.  
  7. #include <iostream>
  8.  #include <Windows.h>
  9.  
  10. #ifdef _CH_
  11. #pragma package <opencv>
  12. #endif
  13.  
  14. #ifndef _EiC
  15. #include "cv.h"
  16. #include "highgui.h"
  17. #include "ml.h"
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <ctype.h>
  21. #endif
  22.  
  23. using namespace std;
  24. using namespace cv;
  25.  
  26.  
  27. bool createDir(const std::string& dirName_in)
  28. {
  29.   if (CreateDirectory(dirName_in.c_str(), NULL)){
  30.         return true;
  31.   }else return false;
  32. }
  33.  
  34. int numOfFiles(char* searchPath)
  35. {
  36.         WIN32_FIND_DATA FindData;
  37.         HANDLE          hFiles;
  38.         LPTSTR          lptszFiles[100];
  39.         UINT            nFileCount = 0;
  40.  
  41.         hFiles = FindFirstFile(searchPath, &FindData);
  42.        
  43.         if (hFiles == INVALID_HANDLE_VALUE)
  44.                 return 0;
  45.  
  46.         bool bFinished = false;
  47.         while(!bFinished){
  48.                 if(!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)){
  49.                         nFileCount++;
  50.                 }
  51.  
  52.                 if(!FindNextFile(hFiles, &FindData)){
  53.                         bFinished = true;
  54.                 }
  55.         }
  56.         FindClose(hFiles);
  57.         return nFileCount;
  58. }
  59.  
  60.  
  61.  
  62. class comparator{
  63. public:
  64.         bool operator()(vector<Point> c1,vector<Point>c2){
  65.                
  66.                 return boundingRect( Mat(c1)).x<boundingRect( Mat(c2)).x;
  67.  
  68.         }
  69.  
  70. };
  71.  
  72.  
  73. void extractContours(Mat& image,vector< vector<Point> > contours_poly){
  74.  
  75.         vector<Mat> extracted;
  76.  
  77.         sort(contours_poly.begin(),contours_poly.end(),comparator());
  78.  
  79.  
  80.         char curDir[256];
  81.         GetCurrentDirectory(256,curDir);
  82.  
  83.         stringstream fileOutput;
  84.         fileOutput<<curDir<<"\\output\\";
  85.  
  86.         createDir("output");
  87.  
  88.  
  89.  
  90.        
  91.  
  92.         //Loop through all contours to extract
  93.                  for( int i = 0; i< contours_poly.size(); i++ ){
  94.  
  95.                         Rect r = boundingRect( Mat(contours_poly[i]) );
  96.                        
  97.                        
  98.                         Mat mask = Mat::zeros(image.size(), CV_8UC1);
  99.                         //Draw mask
  100.                         drawContours(mask, contours_poly, i, Scalar(255), CV_FILLED);
  101.  
  102.                         //Check for equal sign (2 dashes on top of each other) and merge
  103.                         if(i+1<contours_poly.size()){
  104.                                 Rect r2 = boundingRect( Mat(contours_poly[i+1]) );
  105.                                 //Shape on top of another shape
  106.                                 if(abs(r2.x-r.x)<20){
  107.                                         drawContours(mask, contours_poly, i+1, Scalar(255), CV_FILLED);
  108.                                         i++;
  109.                                         int minX = min(r.x,r2.x);
  110.                                         int minY = min(r.y,r2.y);
  111.                                         int maxX =  max(r.x+r.width,r2.x+r2.width);
  112.                                         int maxY = max(r.y+r.height,r2.y+r2.height);
  113.                                         r = Rect(minX,minY,maxX - minX,maxY-minY);
  114.  
  115.                                         //Ignore equal signs
  116.                                         if((double)r.width/r.height>3.0){
  117.                                                 continue;
  118.                                         }
  119.  
  120.                                 }
  121.                         }
  122.                        
  123.                         //Ignore dashes
  124.                         if((double)r.width/r.height>3.0){
  125.                                
  126.                                
  127.                                 continue;
  128.  
  129.                         }
  130.                        
  131.  
  132.                         //Extract shape from mask
  133.                          Mat extractPic;
  134.                          image.copyTo(extractPic,mask);
  135.                          Mat resizedPic = extractPic(r);//extractPic(cv::Range(r.x, r.y), cv::Range(r.x+r.width, r.y+r.height));
  136.        
  137.                         cv::Mat image=resizedPic.clone();
  138.                         imshow("image",image);
  139.                         char ch  = waitKey(0);
  140.  
  141.                         stringstream outputFile;
  142.                         outputFile<<fileOutput.str()<<ch;
  143.                        
  144.                         createDir(outputFile.str());
  145.                        
  146.                         //Search for jpgs
  147.                         stringstream searchMask;
  148.                         searchMask<<outputFile.str()<<"\\*.jpg";
  149.  
  150.                         //Write to file
  151.                         int n = numOfFiles((char*)searchMask.str().c_str());
  152.                         outputFile<<"\\"<<n<<".jpg";
  153.                         imwrite(outputFile.str(),resizedPic);
  154.  
  155.  
  156.                  }
  157.  
  158.  
  159.  
  160. }
  161.  
  162. void getContours(const char* filename)
  163. {
  164.   cv::Mat img = cv::imread(filename, 0);
  165.  
  166.  
  167.   //Apply blur to smooth edges and use adapative thresholding
  168.    cv::Size size(3,3);
  169.   cv::GaussianBlur(img,img,size,0);
  170.    adaptiveThreshold(img, img,255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,75,10);
  171.   cv::bitwise_not(img, img);
  172.  
  173.  
  174.   cv::Mat img2 = img.clone();
  175.  
  176.   //Rotate the points from calculated angle
  177.   std::vector<cv::Point> points;
  178.   cv::Mat_<uchar>::iterator it = img.begin<uchar>();
  179.   cv::Mat_<uchar>::iterator end = img.end<uchar>();
  180.   for (; it != end; ++it)
  181.     if (*it)
  182.       points.push_back(it.pos());
  183.  
  184.  
  185.   cv::Point2f vertices[4];
  186.  
  187.   cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
  188.    double angle = box.angle;
  189.   if (angle < -45.)
  190.     angle += 90.;
  191.  
  192.    box.points(vertices);
  193.   for(int i = 0; i < 4; ++i)
  194.     cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), 1, CV_AA);
  195.  
  196.  
  197.  
  198.    cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);
  199.  
  200.    cv::Mat rotated;
  201.   cv::warpAffine(img2, rotated, rot_mat, img.size(), cv::INTER_CUBIC);
  202.  
  203.        
  204.  
  205.   cv::Size box_size = box.size;
  206.   if (box.angle < -45.)
  207.     std::swap(box_size.width, box_size.height);
  208.   cv::Mat cropped;
  209.  
  210.   cv::getRectSubPix(rotated, box_size, box.center, cropped);
  211.   cv::imshow("Cropped", cropped);
  212.        
  213.         Mat cropped2=cropped.clone();
  214. cvtColor(cropped2,cropped2,CV_GRAY2RGB);
  215.  
  216. Mat cropped3 = cropped.clone();
  217. cvtColor(cropped3,cropped3,CV_GRAY2RGB);
  218.  
  219.  vector<vector<Point> > contours;
  220.   vector<Vec4i> hierarchy;
  221.  
  222.   /// Find contours
  223.   cv:: findContours( cropped, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS, Point(0, 0) );
  224.  
  225.  
  226.  
  227.   /// Approximate contours to polygons + get bounding rects and circles
  228.   vector<vector<Point> > contours_poly( contours.size() );
  229.   vector<Rect> boundRect( contours.size() );
  230.   vector<Point2f>center( contours.size() );
  231.   vector<float>radius( contours.size() );
  232.  
  233.  
  234.   //Get poly contours
  235.         for( int i = 0; i < contours.size(); i++ ) {
  236.                  approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
  237.      }
  238.  
  239.  
  240.   //Get only important contours, merge contours that are within another
  241.  
  242.   vector<vector<Point> > validContours;
  243.         for (int i=0;i<contours_poly.size();i++){
  244.                
  245.                 Rect r = boundingRect(Mat(contours_poly[i]));
  246.                 if(r.area()<100)continue;
  247.                 bool inside = false;
  248.                 for(int j=0;j<contours_poly.size();j++){
  249.                         if(j==i)continue;
  250.                        
  251.                         Rect r2 = boundingRect(Mat(contours_poly[j]));
  252.                         if(r2.area()<100||r2.area()<r.area())continue;
  253.                         if(r.x>r2.x&&r.x+r.width<r2.x+r2.width&&
  254.                                 r.y>r2.y&&r.y+r.height<r2.y+r2.height){
  255.  
  256.                                 inside = true;
  257.                         }
  258.                 }
  259.                 if(inside)continue;
  260.                 validContours.push_back(contours_poly[i]);
  261.         }
  262.  
  263.  
  264. //Get bounding rects
  265.         for(int i=0;i<validContours.size();i++){
  266.                 boundRect[i] = boundingRect( Mat(validContours[i]) );
  267.         }
  268.  
  269.  
  270. //Display
  271.   Scalar color = Scalar(0,255,0);
  272.   for( int i = 0; i< validContours.size(); i++ )
  273.      {
  274.                 if(boundRect[i].area()<100)continue;
  275.       drawContours( cropped2, validContours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
  276.        rectangle( cropped2, boundRect[i].tl(), boundRect[i].br(),color, 2, 8, 0 );
  277.      }
  278.   extractContours(cropped3,validContours);
  279.  
  280. cv::waitKey(0);
  281.  
  282. }
  283.  
  284.  
  285.  
  286.  
  287. int main(void){
  288.  
  289. char fileName[256];
  290. cin>>fileName;
  291. getContours(fileName);
  292.  
  293. }
RAW Paste Data
Pastebin PRO Summer Special!
Get 60% OFF on Pastebin PRO accounts!
Top