Как обрезать каждый символ на изображении, используя Python OpenCV? - PullRequest
3 голосов
/ 02 марта 2020

Я сгенерировал изображение OpenCV, как это

enter image description here

Из последней строки кода, как мне обрезать и показать каждый символ на текущем изображении отдельно?

Код

    labels = measure.label(thresh, connectivity=2, background=0)
    charCandidates = np.zeros(thresh.shape, dtype="uint8")

    for label in np.unique(labels):

        if label == 0:
            continue

        labelMask = np.zeros(thresh.shape, dtype="uint8")
        labelMask[labels == label] = 255
        cnts = cv2.findContours(labelMask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        cnts = imutils.grab_contours(cnts)

        if len(cnts) > 0:
            c = max(cnts, key=cv2.contourArea)
            (boxX, boxY, boxW, boxH) = cv2.boundingRect(c)

            aspectRatio = boxW / float(boxH)
            solidity = cv2.contourArea(c) / float(boxW * boxH)
            heightRatio = boxH / float(crop_frame.shape[0])

            keepAspectRatio = aspectRatio < 1.0
            keepSolidity = solidity > 0.15
            keepHeight = heightRatio > 0.4 and heightRatio < 0.95


        if keepAspectRatio and keepSolidity and keepHeight:
            hull = cv2.convexHull(c)
            cv2.drawContours(charCandidates, [hull], -1, 255, -1)

    charCandidates = segmentation.clear_border(charCandidates)
    cnts = cv2.findContours(charCandidates.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    cv2.imshow("Original Candidates", charCandidates)

    thresh = cv2.bitwise_and(thresh, thresh, mask=charCandidates)
    cv2.imshow("Char Threshold", thresh)

Большое спасибо.

1 Ответ

2 голосов
/ 03 марта 2020

Вот простой подход:

  • Преобразование в оттенки серого
  • Порог Оцу
  • Поиск контуров, сортировка контуров слева направо направо и фильтруем, используя область контура
  • Извлечение ROI

После определения порога Оцу для получения двоичного изображения мы сортируем контуры слева направо, используя imutils.contours.sort_contours(). Это гарантирует, что, когда мы перебираем каждый контур, у нас есть каждый символ в правильном порядке. Кроме того, мы фильтруем, используя минимальную пороговую площадь, чтобы удалить небольшой шум. Вот обнаруженные символы

enter image description here

Мы можем извлечь каждый символ, используя Numpy нарезку. Вот каждый сохраненный символ ROI

enter image description here

import cv2
from imutils import contours

# Load image, grayscale, Otsu's threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray,0,255,cv2.THRESH_OTSU + cv2.THRESH_BINARY)[1]

# Find contours, sort from left-to-right, then crop
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts, _ = contours.sort_contours(cnts, method="left-to-right")

ROI_number = 0
for c in cnts:
    area = cv2.contourArea(c)
    if area > 10:
        x,y,w,h = cv2.boundingRect(c)
        ROI = 255 - image[y:y+h, x:x+w]
        cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
        cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)
        ROI_number += 1

cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...