2

For handwritten Digit Recognition, I have trained my CNN with MNIST database.

Now, I have to process my input images to the MNIST Format for detecting the digit.

For the following image : enter image description here

I am using contours to separate 3 and 8, In order to detect and write "38" i need to send 3 first and then 8 to the CNN.

But the order of contours from cv2.findContours() are confusing, which sometimes detects 8 first then 3 making it "83".

How can i get the contours from left to write and similarly up to down ?

Vijay Kalmath
  • 178
  • 11
  • What you can do is create bounding rectangles around your two black digits, then from iterate from the left most rectangle and send all contours in that rectangle to your CNN. If you took [this](https://stackoverflow.com/questions/10262600/how-to-detect-region-of-large-of-white-pixels-using-opencv) as an example and went from top to bottom you would have two seperate rectangles – GPPK Nov 14 '17 at 14:32
  • Yes, done the bounding rectangle, how do I iterate from left to right? I know I can look at starting pixel coordinates, but is there an easier way than that? – Vijay Kalmath Nov 14 '17 at 14:36
  • Not really, just take the X,Y of the beginning of the Rect and iterate over from image.cols = 0. - This is probably confusing, like [this](http://answers.opencv.org/question/20012/sort-bounding-boxes-in-x-axis-of-a-image-in-order/) – GPPK Nov 14 '17 at 14:37

1 Answers1

2

What you can do is create bounding rectangles around your two black digits, then from iterate from the left most rectangle and send all contours in that rectangle to your CNN. If you took this as an example and went from top to bottom you would have two seperate rectangles:

Example code from that link:

contours, hier = cv2.findContours(gray,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
    if 200<cv2.contourArea(cnt)<5000:
        cv2.drawContours(img,[cnt],0,(0,255,0),2)
        cv2.drawContours(mask,[cnt],0,255,-1)

Then when you have a set of contours you can sort them in order:

import numpy as np

c = np.load(r"rect.npy")
contours = list(c)

# Example - contours = [(287, 117, 13, 46), (102, 117, 34, 47), (513, 116, 36, 49), (454, 116, 32, 49), (395, 116, 28, 48), (334, 116, 31, 49), (168, 116, 26, 49), (43, 116, 30, 48), (224, 115, 33, 50), (211, 33, 34, 47), ( 45, 33, 13, 46), (514, 32, 32, 49), (455, 32, 31, 49), (396, 32, 29, 48), (275, 32, 28, 48), (156, 32, 26, 49), (91, 32, 30, 48), (333, 31, 33, 50)] 

max_width = np.sum(c[::, (0, 2)], axis=1).max()
max_height = np.max(c[::, 3])
nearest = max_height * 1.4

contours.sort(key=lambda r: (int(nearest * round(float(r[1])/nearest)) * max_width + r[0]))

for x, y, w, h in contours:
    print "{:4} {:4} {:4} {:4}".format(x, y, w, h) 

Taken from - here

GPPK
  • 6,546
  • 4
  • 32
  • 57