如何使用openCV从图像中清除数字?

时间:2019-03-29 06:17:43

标签: python-3.x image opencv image-processing opencv3.0

我正在尝试删除位于图像圆形部分内的数字,数字为黑色,背景在红色,黄色,蓝色和绿色之间变化。

我正在使用opencv删除这些数字。我使用了一个从图像中提取数字的蒙版,借助cv2.inpaint尝试从图像中删除那些数字。 为了进一步分析,我需要有清晰的图像。但是我目前的方法给出了失真的图像,数字并没有完全消除。

我尝试更改阈值,降低阈值会忽略绿色和红色等深色阴影区域中的数字。

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)

输入图像:a)scan_1.jpg b)scan_2.jpg

输出图像:a)ost_1.jpg b)ost_2.jpg

期望的图像:Circles can ignored, but something similar to it is required.

1 个答案:

答案 0 :(得分:1)

这是我的尝试,如果您不关心在圈子外保存文字,可能会获得更好/更轻松的解决方案。

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()

a1的结果:
Result for a1