SHARE
TWEET

Part 1: Extracting contours from text

a guest Jan 9th, 2013 7,831 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. ayoungprogrammer.blogspot.com
  3.  
  4. Part 1: Extracting contours from text
  5.  
  6. */
  7.  
  8. #include <iostream>
  9.  
  10.  #include <Windows.h>
  11.  
  12. #ifdef _CH_
  13. #pragma package <opencv>
  14. #endif
  15.  
  16. #ifndef _EiC
  17. #include "cv.h"
  18. #include "highgui.h"
  19. #include "ml.h"
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <ctype.h>
  23. #endif
  24.  
  25. using namespace std;
  26. using namespace cv;
  27.  
  28.  
  29. class comparator{
  30. public:
  31.         bool operator()(vector<Point> c1,vector<Point>c2){
  32.                
  33.                 return boundingRect( Mat(c1)).x<boundingRect( Mat(c2)).x;
  34.  
  35.         }
  36.  
  37. };
  38.  
  39.  
  40.  
  41. void extractContours(Mat& image,vector< vector<Point> > contours_poly){
  42.  
  43.  
  44.        
  45.         //Sort contorus by x value going from left to right
  46.         sort(contours_poly.begin(),contours_poly.end(),comparator());
  47.  
  48.  
  49.         //Loop through all contours to extract
  50.          for( int i = 0; i< contours_poly.size(); i++ ){
  51.  
  52.                 Rect r = boundingRect( Mat(contours_poly[i]) );
  53.                
  54.                
  55.                 Mat mask = Mat::zeros(image.size(), CV_8UC1);
  56.                 //Draw mask onto image
  57.                 drawContours(mask, contours_poly, i, Scalar(255), CV_FILLED);
  58.  
  59.                 //Check for equal sign (2 dashes on top of each other) and merge
  60.                 if(i+1<contours_poly.size()){
  61.                         Rect r2 = boundingRect( Mat(contours_poly[i+1]) );
  62.                         if(abs(r2.x-r.x)<20){
  63.                                 //Draw mask onto image
  64.                                 drawContours(mask, contours_poly, i+1, Scalar(255), CV_FILLED);
  65.                                 i++;
  66.                                 int minX = min(r.x,r2.x);
  67.                                 int minY = min(r.y,r2.y);
  68.                                 int maxX =  max(r.x+r.width,r2.x+r2.width);
  69.                                 int maxY = max(r.y+r.height,r2.y+r2.height);
  70.                                 r = Rect(minX,minY,maxX - minX,maxY-minY);
  71.  
  72.                         }
  73.                 }
  74.                 //Copy
  75.                  Mat extractPic;
  76.                  //Extract the character using the mask
  77.                  image.copyTo(extractPic,mask);
  78.                  Mat resizedPic = extractPic(r);
  79.        
  80.                 cv::Mat image=resizedPic.clone();
  81.  
  82.                 //Show image
  83.                 imshow("image",image);
  84.                 char ch  = waitKey(0);
  85.                 stringstream searchMask;
  86.                 searchMask<<i<<".jpg";
  87.                 imwrite(searchMask.str(),resizedPic);
  88.  
  89.          }
  90.  
  91.  
  92.  
  93.  
  94.  
  95. }
  96.  
  97. void getContours(const char* filename)
  98. {
  99.   cv::Mat img = cv::imread(filename, 0);
  100.  
  101.  
  102.   //Apply blur to smooth edges and use adapative thresholding
  103.    cv::Size size(3,3);
  104.   cv::GaussianBlur(img,img,size,0);
  105.    adaptiveThreshold(img, img,255,CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY,75,10);
  106.   cv::bitwise_not(img, img);
  107.  
  108.  
  109.  
  110.  
  111.   cv::Mat img2 = img.clone();
  112.  
  113.  
  114.   std::vector<cv::Point> points;
  115.   cv::Mat_<uchar>::iterator it = img.begin<uchar>();
  116.   cv::Mat_<uchar>::iterator end = img.end<uchar>();
  117.   for (; it != end; ++it)
  118.     if (*it)
  119.       points.push_back(it.pos());
  120.  
  121.   cv::RotatedRect box = cv::minAreaRect(cv::Mat(points));
  122.  
  123.    double angle = box.angle;
  124.   if (angle < -45.)
  125.     angle += 90.;
  126.          
  127.   cv::Point2f vertices[4];
  128.   box.points(vertices);
  129.   for(int i = 0; i < 4; ++i)
  130.     cv::line(img, vertices[i], vertices[(i + 1) % 4], cv::Scalar(255, 0, 0), 1, CV_AA);
  131.  
  132.          
  133.  
  134.    cv::Mat rot_mat = cv::getRotationMatrix2D(box.center, angle, 1);
  135.  
  136.    cv::Mat rotated;
  137.   cv::warpAffine(img2, rotated, rot_mat, img.size(), cv::INTER_CUBIC);
  138.  
  139.        
  140.  
  141.   cv::Size box_size = box.size;
  142.   if (box.angle < -45.)
  143.     std::swap(box_size.width, box_size.height);
  144.   cv::Mat cropped;
  145.  
  146.   cv::getRectSubPix(rotated, box_size, box.center, cropped);
  147.   cv::imshow("Cropped", cropped);
  148.   imwrite("example5.jpg",cropped);
  149.        
  150.         Mat cropped2=cropped.clone();
  151. cvtColor(cropped2,cropped2,CV_GRAY2RGB);
  152.  
  153. Mat cropped3 = cropped.clone();
  154. cvtColor(cropped3,cropped3,CV_GRAY2RGB);
  155.  
  156.  vector<vector<Point> > contours;
  157.   vector<Vec4i> hierarchy;
  158.  
  159.   /// Find contours
  160.   cv:: findContours( cropped, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_TC89_KCOS, Point(0, 0) );
  161.  
  162.  
  163.  
  164.   /// Approximate contours to polygons + get bounding rects and circles
  165.   vector<vector<Point> > contours_poly( contours.size() );
  166.   vector<Rect> boundRect( contours.size() );
  167.   vector<Point2f>center( contours.size() );
  168.   vector<float>radius( contours.size() );
  169.  
  170.  
  171.   //Get poly contours
  172.         for( int i = 0; i < contours.size(); i++ )
  173.      {
  174.                  approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
  175.      }
  176.  
  177.  
  178.   //Get only important contours, merge contours that are within another
  179.   vector<vector<Point> > validContours;
  180.         for (int i=0;i<contours_poly.size();i++){
  181.                
  182.                 Rect r = boundingRect(Mat(contours_poly[i]));
  183.                 if(r.area()<100)continue;
  184.                 bool inside = false;
  185.                 for(int j=0;j<contours_poly.size();j++){
  186.                         if(j==i)continue;
  187.                        
  188.                         Rect r2 = boundingRect(Mat(contours_poly[j]));
  189.                         if(r2.area()<100||r2.area()<r.area())continue;
  190.                         if(r.x>r2.x&&r.x+r.width<r2.x+r2.width&&
  191.                                 r.y>r2.y&&r.y+r.height<r2.y+r2.height){
  192.  
  193.                                 inside = true;
  194.                         }
  195.                 }
  196.                 if(inside)continue;
  197.                 validContours.push_back(contours_poly[i]);
  198.         }
  199.  
  200.  
  201.         //Get bounding rects
  202.         for(int i=0;i<validContours.size();i++){
  203.                 boundRect[i] = boundingRect( Mat(validContours[i]) );
  204.         }
  205.  
  206.  
  207.         //Display
  208.   Scalar color = Scalar(0,255,0);
  209.   for( int i = 0; i< validContours.size(); i++ )
  210.      {
  211.         if(boundRect[i].area()<100)continue;
  212.       drawContours( cropped2, validContours, i, color, 1, 8, vector<Vec4i>(), 0, Point() );
  213.        rectangle( cropped2, boundRect[i].tl(), boundRect[i].br(),color, 2, 8, 0 );
  214.      }
  215.  
  216.   //imwrite("example6.jpg",cropped2);
  217.   imshow("Contours",cropped2);
  218.  
  219.   extractContours(cropped3,validContours);
  220.  
  221. cv::waitKey(0);
  222.  
  223. }
  224.  
  225.  
  226.  
  227.  
  228.  
  229. int main(void){
  230.  
  231. char fileName[256];
  232. cin>>fileName;
  233. getContours(fileName);
  234.  
  235. }
RAW Paste Data
Pastebin PRO Summer Special!
Get 60% OFF on Pastebin PRO accounts!
Top