Ask Your Question
1

Number Extraction from Metal surface

asked 2014-02-19 05:05:27 -0500

Nagaraj gravatar image

updated 2017-12-23 05:02:10 -0500

image description

Blockquote

Hi, I have to extract the number 1 in an Image and the number recognized by tesseract.

Please suggest me the ideas to implement and process this image .

Regards Nagaraj

edit retag flag offensive close merge delete

Comments

prakharmohan gravatar imageprakharmohan ( 2014-02-20 01:00:36 -0500 )edit

@Nagaraj So your sample image always be like this only ?

Haris gravatar imageHaris ( 2014-02-20 22:58:43 -0500 )edit

@prakharmohan , Ya I tried I have done threshold and segmentation . Due to uneven contrast of the image I will get too much noise and tesseract won't detect . plz can u suggest me how can extract 1 from this image without background .

Nagaraj gravatar imageNagaraj ( 2014-02-24 02:46:54 -0500 )edit

@Haris Moonamkunnu , Yes my sample image is like this only

Nagaraj gravatar imageNagaraj ( 2014-02-24 02:48:34 -0500 )edit

@Haris Moonamkunnu, Sir, thanks a lot :)

Nagaraj gravatar imageNagaraj ( 2014-02-24 23:37:25 -0500 )edit

Welcome.........

Haris gravatar imageHaris ( 2014-02-24 23:42:16 -0500 )edit

@Nagaraj Accept the answer if it is working then!

prakharmohan gravatar imageprakharmohan ( 2014-02-25 00:40:44 -0500 )edit

2 answers

Sort by ยป oldest newest most voted
5

answered 2014-02-24 06:18:54 -0500

Haris gravatar image

You can segment the number easily using watershed() for this you need to create markers to distinguish foreground and background.

1. Create Mask: As first step we will create make image, you need to do adaptiveThreshold(), contour finding(largest), convexHull() etc..

image description image description

Below is the code how to do it

Mat src=imread("src.jpg",1);
Mat thr,gray;
cvtColor(src,gray,CV_BGR2GRAY);
adaptiveThreshold(gray,thr,255,ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY,51,5);

vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
int largest_contour_index=0;
int largest_area=0;
Mat mask(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
findContours( thr.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
 {
  double a=contourArea( contours[i],false);  //  Find the area of contour
  if(a>largest_area){
  largest_area=a;
  largest_contour_index=i;                //Store the index of largest contour
  }
 }
 vector<vector<Point> >hull(1);
 convexHull(contours[largest_contour_index],  hull[0],false,true );
 drawContours( mask, hull, 0, Scalar(125), -1, 8, vector<Vec4i>(), 0, Point() );

2. Create Foreground: For this you need to do again adaptiveThreshold() but with THRESH_BINARY_INV option, and erode() result to reduce noise, finally find biggest contour which represent your foreground object, here you need to consider the mask while copying to foreground image. The result look like the object to be segmented, but for better result we will move to next steps like background creation, watershed etc..

image description

 Mat fg;
 adaptiveThreshold(gray,thr,255,ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY_INV,151,5);
 erode(thr,thr,Mat(),Point(-1,-1),1);
 contours.clear();
 hierarchy.clear();
 largest_contour_index=0;
 largest_area=0;
 thr.copyTo(fg,mask),
 findContours( fg, contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
  for( int i = 0; i< contours.size(); i++ ) // iterate through each contour.
   {
    double a=contourArea( contours[i],false);  //  Find the area of contour
    if(a>largest_area){
    largest_area=a;
    largest_contour_index=i;                //Store the index of largest contour
    }
   }

 fg.setTo(0);
 drawContours( fg,contours, largest_contour_index, Scalar(255),CV_FILLED, 8, hierarchy );

3. Create Background: Creating background marker is easy as you have mask and foreground just subtract foreground from mask, then apply erode() to make little separation between fg and bg while merging.

image description

 Mat bg=mask-fg;
 erode(bg,bg,Mat(),Point(-1,-1),7);

4. Create Marker for Watershed: Just add up fg and bg and convert CV_32S for passing watershed() image description

5. Perform watershed Operation: Here you need to pass this marker image along with your source image.

image description

 markers.convertTo(markers, CV_32S);
 watershed(src, markers);
 markers.convertTo(markers,CV_8U);
 imshow("Segmented",markers);
edit flag offensive delete link more

Comments

Brilliant! :)

prakharmohan gravatar imageprakharmohan ( 2014-02-25 00:39:55 -0500 )edit

@Haris Moonamkunnu, sir, This output picture is input to tesseract , Unable to detect the number by tessseract . and how to correct the edges in the image .

Nagaraj gravatar imageNagaraj ( 2014-03-04 06:59:46 -0500 )edit
0

answered 2014-02-24 03:36:18 -0500

Nagaraj gravatar image

I have tried like this ..!(manually croped and apply threshold and segmentation ) image description image description If do more threshold i will lose some part of number . please suggest me how to extract only 1 from image .

edit flag offensive delete link more
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2014-02-19 05:05:27 -0500

Seen: 620 times

Last updated: Feb 24 '14