0

I am working with code that was taken from this answer: Detect text region in image using Opencv

The code I am working with is:

import cv2
def captch_ex(file_name ):
    img  = cv2.imread(file_name)

    img_final = cv2.imread(file_name)
    img2gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, mask = cv2.threshold(img2gray, 180, 255, cv2.THRESH_BINARY)
    image_final = cv2.bitwise_and(img2gray , img2gray , mask =  mask)
    ret, new_img = cv2.threshold(image_final, 180 , 255, cv2.THRESH_BINARY)  # for black text , cv.THRESH_BINARY_INV
    '''
            line  8 to 12  : Remove noisy portion
    '''
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3 , 3)) # to manipulate the orientation of dilution , large x means horizonatally dilating  more, large y means vertically dilating more
    dilated = cv2.dilate(new_img,kernel,iterations = 9) # dilate , more the iteration more the dilation

    contours = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0] # get contours
    index = 0
    for contour in contours:
        # get rectangle bounding contour
        [x,y,w,h] = cv2.boundingRect(contour)

        #Don't plot small false positives that aren't text
        if w < 35 and h<35:
            continue

        # draw rectangle around contour on original image
        cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,255),2)

        #you can crop image and send to OCR  , false detected will return no text :)
        cropped = img_final[y :y +  h , x : x + w]

        s = file_name + 'crop_' + str(index) + '.png'
        cv2.imwrite(s , cropped)
        index = index + 1
    # write original image with added contours to disk

file_name ='rec_5.png'
captch_ex(file_name)

The biggest difference to point out is the following: contours = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)[0] The [0] was added because I kept receiving this error without it

Traceback (most recent call last):
  File "test2.py", line 38, in <module>
    captch_ex(file_name)
  File "test2.py", line 20, in captch_ex
    [x,y,w,h] = cv2.boundingRect(contour)
TypeError: points is not a numpy array, neither a scalar

Unfortunately, I can't find the source, but I read somewhere that there was a change in this method for version 3 and now this is required.

My issue is that when I feed this function an image I receive hundreds of 1 px. width cropped images, that do not accomplish what the function apparently solved in the referenced answer.

As of right now I am guessing that the additional [0] noted above could potentially be the cause of the error, but without it I can get the script to complete.

Community
  • 1
  • 1
metersk
  • 11,803
  • 21
  • 63
  • 100
  • the same problem is with me, when i execute the code i recieve hundreds of 1 px. width cropped images, i want to crop a particular area from the image, any suggestion? – Azam Rafique Dec 26 '18 at 09:51

1 Answers1

1

The issue is with the cv2.findContours() method, actually it has different return arguments for Opencv 2 and Opencv 3, You must check for the documentation of the Opencv version you are using, In general terms:

For Opencv 2:

contours, hierarchy = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

For Opencv 3:

image, contours, hierarchy = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)

Now you dont need that [0] hack to access the contours, You can further continue as :

for contour in contours:
    # get rectangle bounding contour
    [x,y,w,h] = cv2.boundingRect(contour)
ZdaR
  • 22,343
  • 7
  • 66
  • 87
  • great! solved my problem but this code don't show image with text bounding boxes, and just crops 3 images 0,1,2 from input image that is not text, please suggest me i want detect text with bounding boxes and crop each bounding box – Azam Rafique Dec 28 '18 at 08:08
  • `[x,y,w,h]` are the coordinates of a bounding-box, You can use these values to draw a rectangle using `cv2.rectangle()` or crop the image using `img[y:y+h, x:x+w]` – ZdaR Dec 28 '18 at 12:34