Detect and remove rectangles surrounding character

Viewed 222

How can i remove rectangles surrounding characters and digits so i can perform OCR after? Here is an example:

example

I assume that the lines are continous. I tried to do it with OpenCV contours but so far it appears to be quite unrobust algorithm that heavily depends on the noize of the image, width of the lines etc.

I'm interested in the most general and robust algorithm. I can also consider neural solutions, but so far i've found only CRAFT (https://github.com/clovaai/CRAFT-pytorch) to detect and extract characters, which also often fails on the case when the word is splitted by its characters/digits inside squares/rectangles.

1 Answers

We can remove them using findContours to get the boxes.

We need to make a mask of the image first. I'm using the [200, 255] range to get the white background. I then eroded the mask to make sure that the boxes have enough separation from one another.

enter image description here

Then I used findContours to get the boxes. I removed small contours to filter out the numbers inside the boxes. I redrew the boxes without the numbers inside of them.

enter image description here

I then went back over the original image and whited-out the masked areas.

enter image description here

import cv2
import numpy as np

# load image
img = cv2.imread("numbers.png");
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
mask = cv2.inRange(gray, 200, 255);

# erode to enhance box separation
kernel = np.ones((3,3), np.uint8);
mask = cv2.erode(mask, kernel, iterations = 1);

# contours OpenCV3.4, if you're using OpenCV 2 or 4, it returns (contours, _)
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);

# only take big boxes
cutoff = 250;
big_cons = [];
for con in contours:
    area = cv2.contourArea(con)
    if area > cutoff:
        big_cons.append(con);
        print(area);

# make a mask
redraw = np.zeros_like(mask);
cv2.drawContours(redraw, big_cons, -1, (255), -1);
redraw = cv2.bitwise_not(redraw);
img[redraw == 255] = (255,255,255); # replace with whatever color you want as your background

# show
cv2.imshow("Image", img);
cv2.imshow("Mask", mask);
cv2.imshow("redraw", redraw);
cv2.waitKey(0);
Related