Определить текстовую область на изображении, используя python и opencv

Я хочу обнаружить текстовую область изображений, используя python 2.7 и opencv 2.4.9, и нарисовать прямоугольную область вокруг нее. Как показано на рисунке ниже.

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

 Rahul K P12 июн. 2016 г., 11:33
Вы должны искать цвет на изображении. Но он имеет похожий цвет на вашем изображении, поэтому это может быть сложно. Если вы ищете только текст внутри, то есть библиотека под названием «tesseract»
 User941212 июн. 2016 г., 13:10
@A_A Делать это из первых принципов - это то, что я хочу. Я только хочу обнаружить отмеченные слова
 User941212 июн. 2016 г., 14:08
@A_A Просто то, что я хочу сделать, это обнаружить текстовые области голубых отпечатков домов, подобных этому.
 User941212 июн. 2016 г., 09:53
@flowfree Я не могу обновить его, так как есть другие компоненты проекта.
 A_A12 июн. 2016 г., 13:28
И это изображение или есть другие случаи, которые вы, возможно, должны охватить? Можно ли загрузить несколько репрезентативных случаев?
 A_A12 июн. 2016 г., 12:41
Вы ищете "инструментальное" решение? (Готовая функция из модуля или что-то в этом роде) или вы согласитесь сделать это из первых принципов? Это относительно просто сделать (обнаружить текст) в условиях, подобных тем, которые вы здесь описываете. Кроме того, вы пропустили слово «ЛИН» в шкафу на северо-западе большой спальни. Хотели бы вы также иметь возможность ловить эти письма?
 flowfree12 июн. 2016 г., 08:15
Если возможно, используйте OpenCV 3.1 и используйтеобнаружение текста сцены особенность.
 Mark Setchell25 июл. 2016 г., 18:51
Я полагаю, вы понимаете, что текст черный, а все остальное серо-голубое? Это всегда так? Если так, ответ прост.

Ответы на вопрос(1)

Существует несколько способов обнаружения текста на изображении.

Я рекомендую посмотреть наэтот вопрос здесь, поскольку это может ответить и на ваш случай. Хотя код написан не на python, код можно легко перевести с c ++ на python (просто посмотрите на API и конвертируйте методы из c ++ в python, не сложно. Я сделал это сам, когда попробовал их код для собственной проблемы) , Решения здесь могут не работать для вашего случая, но я рекомендую попробовать их.

Если бы я пошел по этому поводу, я бы сделал следующий процесс:

Подготовьте свое изображение: если все ваши изображения, которые вы хотите отредактировать, примерно такие же, как те, что вы предоставили, где фактический дизайн состоит из диапазона серых цветов, а текст всегда черный. Сначала я бы удалил все содержимое, которое не является черным (или уже белым). В результате останется только черный текст.

# must import if working with opencv in python
import numpy as np
import cv2

# removes pixels in image that are between the range of
# [lower_val,upper_val]
def remove_gray(img,lower_val,upper_val):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower_bound = np.array([0,0,lower_val])
    upper_bound = np.array([255,255,upper_val])
    mask = cv2.inRange(gray, lower_bound, upper_bound)
    return cv2.bitwise_and(gray, gray, mask = mask)

Теперь, когда у вас есть только черный текст, цель состоит в том, чтобы получить эти коробки. Как указывалось ранее, существуют разные способы решения этой проблемы.

Преобразование ширины хода (SWT)

Типичный способ поиска текстовых областей: вы можете найти текстовые области с помощью преобразования ширины штриха, как показано на«Обнаружение текста в естественных сценах с преобразованием ширины обводки» Борис Эпштейн, Эйал Офек и Йонатан Векслер. Если честно, если это так быстро и надежно, как я считаю, то этот метод более эффективен, чем мой код ниже. Вы все еще можете использовать приведенный выше код, чтобы удалить план проекта, и этоможет помочь общей производительности алгоритма SWT.

Вот библиотека с который реализует их алгоритм, но он считается очень сырым, а документация - неполной. Очевидно, что для использования этой библиотеки с python понадобится обертка, и на данный момент я не вижу официальной предложенной библиотеки.

Библиотека, которую я связалККТ, Это библиотека, которая предназначена для использования в ваших приложениях, а не для воссоздания алгоритмов. Так что это инструмент, который нужно использовать, который идет вразрез с желанием ОП сделать его из «Первых принципов», как указано в комментариях. Тем не менее, полезно знать, что он существует, если вы не хотите самостоятельно кодировать алгоритм.

Домашний сваренный без SWT метод

Если у вас есть метаданные для каждого изображения, например, в файле xml, в котором указано, сколько комнат помечено на каждом изображении, вы можете получить доступ к этому файлу xml, получить данные о количестве меток на изображении и затем сохранить его. число в некоторой переменной скажем,num_of_labels, Теперь возьмите свое изображение и проведите его через цикл while, который размывает с заданной вами скоростью, находя внешние контуры на изображении в каждом цикле и останавливая цикл, когда у вас будет то же количество внешних контуров, что и у вашего.num_of_labels, Затем просто найдите ограничивающую рамку каждого контура, и все готово.

# erodes image based on given kernel size (erosion = expands black areas)
def erode( img, kern_size = 3 ):
    retval, img = cv2.threshold(img, 254.0, 255.0, cv2.THRESH_BINARY) # threshold to deal with only black and white.
    kern = np.ones((kern_size,kern_size),np.uint8) # make a kernel for erosion based on given kernel size.
    eroded = cv2.erode(img, kern, 1) # erode your image to blobbify black areas
    y,x = eroded.shape # get shape of image to make a white boarder around image of 1px, to avoid problems with find contours.
    return cv2.rectangle(eroded, (0,0), (x,y), (255,255,255), 1)

# finds contours of eroded image
def prep( img, kern_size = 3 ):    
    img = erode( img, kern_size )
    retval, img = cv2.threshold(img, 200.0, 255.0, cv2.THRESH_BINARY_INV) #   invert colors for findContours
    return cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) # Find Contours of Image

# given img & number of desired blobs, returns contours of blobs.
def blobbify(img, num_of_labels, kern_size = 3, dilation_rate = 10):
    prep_img, contours, hierarchy = prep( img.copy(), kern_size ) # dilate img and check current contour count.
    while len(contours) > num_of_labels:
        kern_size += dilation_rate # add dilation_rate to kern_size to increase the blob. Remember kern_size must always be odd.
        previous = (prep_img, contours, hierarchy)
        processed_img, contours, hierarchy = prep( img.copy(), kern_size ) # dilate img and check current contour count, again.
    if len(contours) < num_of_labels:
        return (processed_img, contours, hierarchy)
    else:
        return previous

# finds bounding boxes of all contours
def bounding_box(contours):
    bBox = []
    for curve in contours:
        box = cv2.boundingRect(curve)
    bBox.append(box)
    return bBox

Получающиеся в результате вышеописанного способа поля будут иметь пространство вокруг меток, и это может включать в себя часть оригинального дизайна, если поля применяются к исходному изображению. Чтобы избежать этого, создайте области интереса с помощью новых найденных полей и обрежьте пустое пространство. Затем сохраните форму этой roi как вашу новую коробку.

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

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

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

Модуль обнаружения текста сцены в OpenCV 3

Как уже упоминалось в комментариях к вашему вопросу, в opencv 3 уже есть средства обнаружения текста сцены (не определения текста документа). Я понимаю, что у вас нет возможности переключать версии, но для тех, у кого такой же вопрос и не ограничен к более старой версии opencv я решил включить это в конце. Документацию по обнаружению текста сцены можно найти с помощью простого поиска Google.

Модуль opencv для обнаружения текста также поставляется с функцией распознавания текста, которая реализует tessaract, который является бесплатным модулем распознавания текста с открытым исходным кодом. Недостатком tessaract и, следовательно, модуля распознавания текста в opencv является то, что он не так совершенен, как коммерческие приложения, и требует много времени для использования. Таким образом, снижается его производительность, но он бесплатен в использовании, поэтому это лучшее, что мы получили, не платя денег, если вы также хотите распознавать текст.

Ссылки:

Документация OpenCvСтарая документацияИсходный код находится здесь, для анализа и понимания

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

 m33n08 февр. 2018 г., 11:20
Я читал об этом, и есть несколько реализаций на Python SWT, которые могут быть полезны для вас: [1]github.com/marrrcin/swt-python [2]github.com/mypetyak/StrokeWidthTransform

Ваш ответ на вопрос