Ask Your Question
1

Merging nearby rectangles(edited)

asked 2020-06-15 12:24:48 -0600

DispooL gravatar image

updated 2020-06-15 21:29:11 -0600

supra56 gravatar image

Hello everyone! I need to merge every nearby digit rectangles so there is should be only 6 rectangles. I've been trying to achieve this for the whole week and I'm soo tired. It would be so nice if anyone could help me. I have a bunch of sorted rectangles from left to right and the task is to split them to separate digits somehow. I grab contours using findContours cv2.findContours(threshed_img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

My question is really similar to this

Code:

import imutils
import cv2

img = cv2.imread('a.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
ret, threshed_img = cv2.threshold(blurred, 200, 255, cv2.THRESH_BINARY_INV)
# find contours and get the external one

#edged = imutils.auto_canny(threshed_img)

ctrz = cv2.findContours(threshed_img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(ctrz)
(cnts, boundingBoxes) = contours.sort_contours(cnts, method="left-to-right")
boundingBoxes = list(boundingBoxes)

Example of sorted rectangels that I draw(x,y,w,h) [ [126, 815, 42, 57], [127, 922, 41, 53], [141, 689, 35, 57], [143, 577, 40, 51], [148, 449, 33, 49], [160, 298, 37, 47], [169, 199, 39, 53], [189, 812, 25, 26], [193, 918, 24, 34], [198, 576, 31, 54] ] Drawn rectangles image description Desired output image description

edit retag flag offensive close merge delete

Comments

2

that recognizes handwritten digits and I need to merge two nearby digit rectangles

so, that's some object-detection network, not plain clasification ? or is your "merging rectangles" a problem in the preprocessing step ?

please clarify, what you're using, and anyway, show code

also, are you aware of the NMS boxes functions in cv2.dnn ?

berak gravatar imageberak ( 2020-06-15 12:36:22 -0600 )edit
1

I just classify every rectangle but I have nothing to do with them. The task is make up single number from classified rectangles

DispooL gravatar imageDispooL ( 2020-06-15 12:59:43 -0600 )edit

seriously, please edit your question, and make it explain, what you're doing, else noone can help you

berak gravatar imageberak ( 2020-06-15 13:31:32 -0600 )edit

can you maybe start all over and explain, how you obtain those rects ?

berak gravatar imageberak ( 2020-06-15 14:55:28 -0600 )edit

I'm really sorry. Added link to code

DispooL gravatar imageDispooL ( 2020-06-15 15:09:25 -0600 )edit

I need to merge nearby rectangles somehow

DispooL gravatar imageDispooL ( 2020-06-15 16:21:57 -0600 )edit
1

Instead of joining char lvl rectangles - detect them together with your object detection algorithm (word level segmentation is the word here)

holger gravatar imageholger ( 2020-06-15 20:06:19 -0600 )edit

How to do this? I know its sounds soo stupid but maybe u will give a little piece of code?

DispooL gravatar imageDispooL ( 2020-06-16 01:19:34 -0600 )edit

Hmm its actually more a conceptual thing. In object detection you have labeled input data. You have to mark the object your want to detect. Instead of marking the characters - you mark the whole word.

And then you train a model. How to do this is a bit out of scope

holger gravatar imageholger ( 2020-06-16 04:39:45 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2020-06-17 06:00:34 -0600

i hope this will help you (i am not a python coder)

some code taken and modified from https://github.com/Breta01/handwritin...

image description

from imutils import contours
import imutils
import cv2

def union(a,b):
    x = min(a[0], b[0])
    y = min(a[1], b[1])
    w = max(a[0]+a[2], b[0]+b[2]) - x
    h = max(a[1]+a[3], b[1]+b[3]) - y
    return [x, y, w, h]

def _intersect(a,b):
    x = max(a[0], b[0])
    y = max(a[1], b[1])
    w = min(a[0]+a[2], b[0]+b[2]) - x
    h = min(a[1]+a[3], b[1]+b[3]) - y
    if h<0:                                              # in original code :  if w<0 or h<0:
        return False
    return True

def _group_rectangles(rec):
    """
    Uion intersecting rectangles.
    Args:
        rec - list of rectangles in form [x, y, w, h]
    Return:
        list of grouped ractangles 
    """
    tested = [False for i in range(len(rec))]
    final = []
    i = 0
    while i < len(rec):
        if not tested[i]:
            j = i+1
            while j < len(rec):
                if not tested[j] and _intersect(rec[i], rec[j]):
                    rec[i] = union(rec[i], rec[j])
                    tested[j] = True
                    j = i
                j += 1
            final += [rec[i]]
        i += 1

    return final

img = cv2.imread('e:/test/hr-ocr.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold image
ret, threshed_img = cv2.threshold(gray, 80, 255, cv2.THRESH_BINARY_INV)

# find contours and get the external one

#edged = imutils.auto_canny(threshed_img)

ctrz = cv2.findContours(threshed_img, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(ctrz)
(cnts, boundingBoxes) = imutils.contours.sort_contours(cnts, method="left-to-right")
boundingBoxes = list(boundingBoxes)
boundingBoxes = _group_rectangles(boundingBoxes)

for (x, y, w, h) in boundingBoxes:
    cv2.rectangle(img, (x, y),(x+w,y+h), (0, 255, 0), 2)

cv2.imshow('img',img)
cv2.waitKey()
cv2.destroyWindow('img')
edit flag offensive delete link more

Comments

1

The character detection was also made with find contours. If the environment is fixed and does not contain many variations - the posted code is totally fine.

CNN might be an overkill in this case.

holger gravatar imageholger ( 2020-06-17 18:59:12 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2020-06-15 12:24:02 -0600

Seen: 4,048 times

Last updated: Jun 17 '20