Как сегментировать символы и слова из изображений в контуры - PullRequest
1 голос
/ 21 июня 2019

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

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

def imageSegmentation(fldr):
        for file in fldr:
            for f in os.listdir(file):
                im = cv2.imread(file+f)
                #print(f)
                imgray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
                ret, thresh = cv2.threshold(imgray, 127, 255, 0)
                contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
                con_img=cv2.drawContours(im, contours, -1, (0,0,0), 1)
                #cv2.imshow("Contour_Image",con_img)
                #cv2.waitKey(0)
                #cv2.destroyAllWindows()

                newfolder=file+"\\contour\\"+f+"\\"
                os.makedirs(newfolder, exist_ok=True)
                fname=os.path.splitext(f)[0]
                cv2.imwrite((newfolder+fname+".png"),con_img)
                #cv2.imshow("con_img",con_img)
                #cv2.waitKey()
                #cv2.destroyAllWindows()

                newfolder2=file+"\\seg\\"+fname+"\\"
                os.makedirs(newfolder2,exist_ok=True)
                sorted_ctrs = sorted(contours, key=lambda cntr: cv2.boundingRect(cntr)[0])

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

                    # Getting ROI
                    roi = im[y:y + h, x:x + w]
                    #roi=~roi

                    if w > 9 and h > 27:
                        cv2.imwrite(newfolder2+"{}.png".format(i), roi)

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

1

2

3

4

5

6

1 Ответ

1 голос
/ 22 июня 2019

Так как ваш вопрос не совсем понятен, если вы хотите извлечь отдельные символы или целые слова, вот подход, чтобы сделать оба.

Отдельные символы

Основная идея здесь

  • Преобразование изображения в оттенки серого и размытие по Гауссу
  • Выполнить обнаружение острых кромок
  • Найти контуры
  • Итерация по контурам и фильтрация по минимальной площади
  • Получить ограничивающие рамки и извлечь ROI

Обнаружение Canny Edge с использованием cv2.Canny()

enter image description here

Теперь мы перебираем контуры, используя cv2.findContours(), фильтруем, используя cv2.contourArea(), затем рисуем ограничивающие рамки. enter image description here

Вот результаты для некоторых других ваших входных изображений

enter image description here enter image description here

enter image description here enter image description here

import cv2

image = cv2.imread('1.png')
original = image.copy()

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
canny = cv2.Canny(blur, 120, 255, 1)

cnts = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

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

cv2.imshow('blur', blur)
cv2.imshow('canny', canny)
cv2.imshow('image', image)
cv2.waitKey(0)

Всего слов

Теперь, если вы хотите извлечь целые слова, вам нужно немного изменить стратегию

  • Преобразование изображения в оттенки серого и размытие по Гауссу
  • Выполнить обнаружение острых кромок
  • Расширьте, чтобы получить один контур
  • Найти контуры
  • Итерация по контурам и фильтрация с использованием минимальной площади
  • Получить ограничивающие рамки и извлечь ROI

Распознавание краев Canny

enter image description here

Расширить, используя cv2.dilate() для соединения контуров

enter image description here

Найти ограничивающие рамки и фильтр, используя область контура

enter image description here

Извлеченный ROI

enter image description here

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

import cv2

image = cv2.imread('1.png')
original = image.copy()

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
canny = cv2.Canny(blur, 120, 255, 1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9,9))
dilate = cv2.dilate(canny, kernel, iterations=5)
cnts = cv2.findContours(dilate, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

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

cv2.imshow('blur', blur)
cv2.imshow('dilate', dilate)
cv2.imshow('canny', canny)
cv2.imshow('image', image)
cv2.waitKey(0)
...