Как очистить цифры с изображения с помощью openCV? - PullRequest
3 голосов
/ 29 марта 2019

Я пытаюсь удалить числа, которые лежат внутри круглой части изображения, цифры черного цвета, а фон изменяется между красным, желтым, синим и зеленым.

Я использую 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

Ожидаемое изображение: Круги можно игнорировать, но требуется нечто подобное.

1 Ответ

1 голос
/ 29 марта 2019

Вот моя попытка, может быть найдено лучшее / более простое решение, если вы не заботитесь о сохранении текстов за пределами вашего круга.

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

...