简体   繁体   中英

How to clear numbers from the image using openCV?

I'm trying to remove numbers which are laying inside the circular part of image, numbers are in black in color and background varies between red,yellow, blue and green.

I am using opencv to remove those numbers. I used a mask which extracts numbers from image, with help of cv2.inpaint tried to remove those numbers from images. For my further analysis I required to have clear image. But my current approach gives distorted image and numbers are not completely removed.

I tried changing the threshold values, lowering will neglect numbers from dark shaded area such as from green and red.

import cv2
img = cv2.imread('scan_1.jpg')
mask = cv2.threshold(img,50,255,cv2.THRESH_BINARY_INV)[1][:,:,0]
cv2.imshow('mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()
dst = cv2.inpaint(img, mask, 5, cv2.INPAINT_TELEA)
cv2.imshow('dst',dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('ost_1.jpg',dst)

Input images: a) scan_1.jpg b) scan_2.jpg

Output images: a) ost_1.jpg b) ost_2.jpg

Expected Image: Circles can ignored, but something similar to it is required.

Here is my attempt, a better/easier solution might be acquired if you do not care about preserving texts outside of your circle.

import cv2
import numpy as np 

#  connectivity method used for finding connected components, 4 vs 8
CONNECTIVITY = 4

#  HSV threshold for finding black pixels
H_THRESHOLD = 179
S_THRESHOLD = 255
V_THRESHOLD = 150

#  read image 
img = cv2.imread("a1.jpg")
img_height = img.shape[0]
img_width = img.shape[1]

#  save a copy for creating resulting image
result = img.copy()

#  convert image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

#  found the circle in the image
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, 1.7, minDist= 100, param1 = 48, param2 = 100, minRadius=70, maxRadius=100)

#  draw found circle, for visual only
circle_output = img.copy()


#  check if we found exactly 1 circle
num_circles = len(circles)
print("Number of found circles:{}".format(num_circles))
if (num_circles != 1):
    print("invalid number of circles found ({}), should be 1".format(num_circles))
    exit(0)

#  save center position and radius of found circle
circle_x = 0 
circle_y = 0
circle_radius = 0
if circles is not None:
    # convert the (x, y) coordinates and radius of the circles to integers
    circles = np.round(circles[0, :]).astype("int")

    for (x, y, radius) in circles:
        circle_x, circle_y, circle_radius = (x, y, radius)
        cv2.circle(circle_output, (circle_x, circle_y), circle_radius, (255, 0, 0), 4)
        print("circle center:({},{}), radius:{}".format(x,y,radius))


#  keep a median filtered version of image, will be used later
median_filtered = cv2.medianBlur(img, 21)

# Convert BGR to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# define range of black color in HSV
lower_val = np.array([0,0,0])
upper_val = np.array([H_THRESHOLD,S_THRESHOLD,V_THRESHOLD])

# Threshold the HSV image to get only black colors
mask = cv2.inRange(hsv, lower_val, upper_val)

#  find connected components
components = cv2.connectedComponentsWithStats(mask, CONNECTIVITY, cv2.CV_32S)

#  apply median filtering to found components
#centers = components[3]
num_components = components[0]
print("Number of found connected components:{}".format(num_components))

labels = components[1]
stats = components[2]
for i in range(1, num_components):
    left = stats[i, cv2.CC_STAT_LEFT] - 10
    top = stats[i, cv2.CC_STAT_TOP] - 10
    width = stats[i, cv2.CC_STAT_WIDTH] + 10
    height = stats[i, cv2.CC_STAT_HEIGHT] + 10

    #  iterate each pixel and replace them if 
    #they are inside circle
    for row in range(top, top+height+1):
        for col in range(left, left+width+1):
            dx = col - circle_x
            dy = row - circle_y
            if (dx*dx + dy*dy <= circle_radius * circle_radius):
                result[row, col] = median_filtered[row, col]

#  smooth the image, may be necessary?
#result = cv2.blur(result, (3,3))


# display image(s)
cv2.imshow("img", img)
cv2.imshow("gray", gray)
cv2.imshow("found circle:", circle_output)
cv2.imshow("mask", mask)
cv2.imshow("result", result) 

cv2.waitKey(0)
cv2.destroyAllWindows()

Result for a1:
结果为a1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM