Пороговое изображение в OpenCV - PullRequest
0 голосов
/ 15 января 2020

У меня есть следующее изображение, которое является отсканированным изображением бумаги формата А4. Мне нужно сделать так, чтобы отдельные символы отсканированного изображения были преобразованы в изображение размером 28 * 28 или 32 * 32. Я делаю это для генерации набора данных для Ovan Devanagari. Я применил простое обмолот, которое мне не помогает. Но когда я применил адаптивное обмолот, результат не такой, как ожидалось. This is my input scanned image

После выполнения градации серого и определения порога я получаю следующее изображение с порогом threshed image

Изображение моего финального индивидуального персонажа похоже на enter image description here

Но мои ожидаемые изображения (28 * 28) были похожи. . enter image description here

Мой исходный код:

# grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# cv2.imshow('gray', gray)

# binary
#simple threshing
#ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
#cv2.imshow('threshold', thresh)
# adaptive threshing
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY_INV,11,6)
cv2.imshow('threshold', thresh)

# dilation
kernel = np.ones((10, 1), np.uint8)
img_dilation = cv2.dilate(thresh, kernel, iterations=1)

# find contours
# cv2.findCountours() function changed from OpenCV3 to OpenCV4: now it have only two parameters instead of 3
cv2MajorVersion = cv2.__version__.split(".")[0]
# check for contours on thresh
if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
else:
    im2, ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, 
cv2.CHAIN_APPROX_SIMPLE)

# sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

for i, ctr in enumerate(sorted_ctrs):
    # Get bounding box
    x, y, w, h = cv2.boundingRect(ctr)

    # Getting ROI
    # roi = image[y:y + h, x:x + w]
    roi = thresh[y:y + h, x:x + w]

    # resizing
    resize = cv2.resize(roi, (28, 28))

    if w > 15 and h > 15:
        cv2.imwrite(str(i) + str(time.time()) + '{}.png'.format(i), resize)

Подскажите, пожалуйста, как извлечь отдельный символ в черно-белом 28 * 28 изображении для сбора набора данных. Если у вас есть какие-либо идеи о создании набора данных, он будет очень полезен.

Ответы [ 2 ]

1 голос
/ 15 января 2020

Проблема в том, как вы находите контуры.

Входной параметр, который требует Режимы поиска контура в cv.findContours() (доступны следующие опции)

cv.RETR_LIST, cv.RETR_TREE, cv.RETR_CCOMP, cv.RETR_EXTERNAL

cv.RETR_EXTERNAL находит только самый внешний элемент в семействе вложенных контуров. Больше можно найти здесь

Так с вашим кодом на

if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

При рисовании прямоугольников на контурах отображается Only parent contour in nested contours

При изменении кода поиска контуров с помощью cv2.RETR_LIST

if int(cv2MajorVersion) >= 4:
    ctrs, hier = cv2.findContours(thresh.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

При рисовании прямоугольников на контурах отображается All contours irrespective of the hierarchy

Позже, используя ваши логики c с ограниченным размером контуров if w > 15 and h > 15: (при изменении этого размера по мере необходимости) вы можете получить изображения символов

Отредактировано

if (w > 20 and h > 20) and (w < 130 and h < 120):
   cv2.imwrite(str(i) + str(time.time()) + '{}.png'.format(i), resize)

Desired output

0 голосов
/ 15 января 2020

Это работает для меня, дает хорошие картинки, черно-белые:

#!/usr/bin/env python

import cv2

counter = 0
img = cv2.imread( 'Downloads/dewangari.jpg' )
print img.shape #(2338, 1700, 3)
img = img[77:1942,91:1517]
img.shape   # (1426, 1623, 3)

_, img = cv2.threshold( img[:,:,2], 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)

x_size = img.shape[0] / 15
y_size = img.shape[1] / 8

for i in range(8) :
    for j in range(15) :
        cell = img[j*x_size+7:(j+1)*x_size-7,i*y_size+7:(i+1)*y_size-7]
        cv2.imshow( 'frame', cell )

        cell = (255 - cell)   # this inverts the image

        cv2.imwrite( 'image_%03d.png' % counter, cell)
        counter += 1  # this saves the image

        cv2.waitKey(0)

cv2.destroyAllWindows()

enter image description here enter image description here enter image description here

и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...