Home > Blockchain >  Remove triangle from the image(python, opencv)
Remove triangle from the image(python, opencv)

Time:11-01

I'm newbie in OpenCV. I want to remove the small triangles from the image blow. I have tried to use close morphology with a custom kernel, but it doesn't work.

enter image description here

Here is my kernel to recognize a pair of triangles. Because I want to keep the text unchanged, so I create kernel of the pair of triangles:

kernel = np.array([
    [1,1,0,0,0,0],
    [1,1,1,1,0,0],
    [1,1,1,1,1,1],
    [0,0,0,0,0,0],
    [0,0,0,0,0,0],
    [1,1,1,1,1,1],
    [1,1,1,1,0,0],
    [1,1,0,0,0,0]
], dtype=np.uint8)

src_img = cv2.imread("triangle_and_text.png")
gray = cv2.cvtColor(src_img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV   cv2.THRESH_OTSU)[1]
removed_triangles = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)
cv2.imwrite("removed_triangles.png", 255 - removed_triangles)

enter image description here

Where I'm wrong?

CodePudding user response:

import cv2
import sys
import numpy as np

pth = sys.path[0]


def removeTri():
    # Load image
    im = cv2.imread("%s/im.png" % pth)

    # Make a gray version
    im_thresh = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

    # Make a black and white version
    im_thresh = cv2.adaptiveThreshold(
        im_thresh, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2
    )

    # Merge channels
    im_thresh = cv2.merge((im_thresh, im_thresh, im_thresh))

    # Remove small noise
    im_thick = cv2.medianBlur(im_thresh, 9)

    # Connect components
    im_thick = cv2.erode(im_thick, np.ones((31, 31)))

    # Draw a white border around shape to avoid errors in blob finding
    cv2.rectangle(im_thick, (0, 0), im.shape[:2], (255, 255, 255), 10)

    # To find each blob and size of each
    im_out = im.copy()
    im_thick = ~cv2.split(im_thick)[0]
    cnts, _ = cv2.findContours(im_thick, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    cnts = list(cnts)
    cnts.sort(
        key=lambda p: max(cv2.boundingRect(p)[2], cv2.boundingRect(p)[3]), reverse=True
    )
    for cnt in cnts:
        peri = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.02 * peri, True)
        x, y, w, h = cv2.boundingRect(approx)
        cv2.rectangle(im_out, (x, y), (x   w, y   h), (0, 255, 0), 2)

    # Draw biggest blob in blue color
    x, y, w, h = cv2.boundingRect(cnts[0])
    cv2.rectangle(im_out, (x, y), (x   w, y   h), (255, 0, 0), 2)

    # Make a mask of text area
    mask = im_thick.copy()
    mask[:] = 0
    cv2.rectangle(mask, (x, y), (x   w, y   h), (255, 255, 255), -1)

    # Extract the final text using mask
    im_res=im.copy()
    im_res[np.where(mask==0)]=(255,255,255)

    # Save output image
    im_thick = cv2.merge((im_thick, im_thick, im_thick))
    mask = cv2.merge((mask, mask, mask))
    top = np.hstack((im, im_thresh, im_thick))
    btm = np.hstack((im_out, mask, im_res))
    cv2.imwrite("%s/im_out.png" % pth, np.vstack((top, btm)))


if __name__ == "__main__":
    removeTri()

enter image description here

  • Related