Search code examples
pythonpython-3.xopencvtesseractrectangles

OpenCV Rectangle Fills Entire Screen


I'm trying to draw a filled rectangle around some OCR'd text.

    d = pytesseract.image_to_data(image, output_type=Output.DICT)
    os.remove(filename);

    n_boxes = len(d['level'])
    for i in range(n_boxes):
        (x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i])
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 0), 1)

    cv2.imwrite("./output/{}.png".format("blurred_" + str(os.getpid())), image);

This line seems to be the problem: cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 0), 1)

When I replace 1 with -1, which should draw the filled rectangle, it instead fills the entire image with the filled rectangle.

Without fill, you can see what should be colored: no fill

With fill: fill

Here's the full code, if needed:

from PIL import Image
import pytesseract
from pytesseract import Output
import argparse, cv2, os
import numpy as np

ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
    help="path of image to be blurrified")
ap.add_argument("-b", "--blurtype", required=True,
    help="blur [words] or [character]s")
ap.add_argument("-p", "--preprocess", type=str, default="thresh",
    help="preprocess type")
args = vars(ap.parse_args())

image = cv2.imread(args["image"])
h, w, _ = image.shape
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

if args["preprocess"] == "thresh":
    gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
elif args["preprocess"] == "blur":
    gray = cv2.medianBlur(gray, 3)

filename = "./temp/{}.png".format("grayscale_" + str(os.getpid()))
cv2.imwrite(filename, gray)

if args["blurtype"] == "character":
    
    text = pytesseract.image_to_boxes(Image.open(filename))
    os.remove(filename);

    for b in text.splitlines():
        b = b.split(' ')
        image = cv2.rectangle(image, (int(b[1]), h - int(b[2])), (int(b[3]), h - int(b[4])), (0, 0, 0), -1)

    cv2.imwrite("./output/{}.png".format("blurred_" + str(os.getpid())), image);
elif args["blurtype"]== "words":

    d = pytesseract.image_to_data(image, output_type=Output.DICT)
    os.remove(filename);

    n_boxes = len(d['level'])
    for i in range(n_boxes):
        (x, y, w, h) = (d['left'][i], d['top'][i], d['width'][i], d['height'][i])
        cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 0), 1)

    cv2.imwrite("./output/{}.png".format("blurred_" + str(os.getpid())), image);

Help would be greatly appreciated!


Solution

  • The pytesseract is making a bounding box of the complete image also. To view this, with thickness 1, making rectangle of (0, 255, 0) color. Thus, when you pass thickness = -1, the image's bounding box is also colored and hence the compete image is being colored. To avoid this, reject that rectangle.