简体   繁体   English

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

[英]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. 我使用opencv删除这些数字。 I used a mask which extracts numbers from image, with help of cv2.inpaint tried to remove those numbers from images. 我使用了一个从图像中提取数字的掩码,在cv2.inpaint的帮助下试图从图像中删除这些数字。 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 输入图像:a) scan_1.jpg b) scan_2.jpg

Output images: a) ost_1.jpg b) ost_2.jpg 输出图像: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的结果:
结果为a1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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