Обнаружение текста и сегментация с использованием Python OpenCV

Я использую приведенный ниже алгоритм для разделения предложений на слова и слов на символы. Как вы можете видеть в выводе ниже, буквы «S» и «T» в слове «STAND» связаны вместе, и я не могу понять, что я сделал не так, буду рад, если вы сможете мне помочь, ребята.

2. Я уже обучил модель на наборе данных букв EMNIST. Моя модель может предсказать только одну букву за раз. Чтобы продолжить, мне нужно извлечь каждое поле символов в массив изображений символов. В конечном итоге я стремлюсь создать массив, содержащий все изображения персонажей. После этого я планирую использовать свою модель для прогнозирования каждого персонажа индивидуально.

Кроме того, мне нужно будет изменить размер каждого символа до 28x28 пикселей, поскольку модель обучена предсказывать буквы по изображениям такого размера. У меня возникли проблемы с этим. Надеюсь, вы сможете мне помочь.

import cv2



# Preprocessing

def preProcessing(myImage):
    grayImg = cv2.cvtColor(myImage, cv2.COLOR_BGR2GRAY)
    # cv2.imshow('Gray Image', grayImg)
    # cv2.waitKey()

    ret, thresh1 = cv2.threshold(grayImg, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    # cv2.imshow('After threshold', thresh1)
    # cv2.waitKey()

    print(f'The threshold valua applied to the image is: {ret} ')
    horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (18, 18))
    dilation = cv2.dilate(thresh1, horizontal_kernel, iterations=1)
    horizontal_contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    im2 = myImage.copy()

    for cnt in horizontal_contours:
        x, y, w, h = cv2.boundingRect(cnt)
        rect = cv2.rectangle(im2, (x, y), (x + w, y + h), (255, 255, 255), 0)
    im2= seg_word(rect)
    #im2 = seg_word(rect)
    #im2=character_seg(im2)
    return im2

# Word segmentation
def seg_word(wordImage):
    # convert the input image into gray scale
    grayImg = cv2.cvtColor(wordImage, cv2.COLOR_BGR2GRAY)

    # Binarize the gray image with OTSU algorithm
    ret, thresh2 = cv2.threshold(grayImg, 0, 255, cv2.THRESH_OTSU | cv2.THRESH_BINARY_INV)
    #print(ret)

    # create a Structuring Element size of 8*10 for the vertical contouring
    vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (8, 10))

    # apply Dilation for once only
    dilation = cv2.dilate(thresh2, vertical_kernel, iterations=1)

    #fingd the vertical contours
    vertical_contours, hierarchy = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    word_img = wordImage.copy()

    # Run through each contour and extract the bounding box
    for cnt in vertical_contours:
        #computes the minimum rectangle
        x, y, w, h = cv2.boundingRect(cnt)
        # Draw a rectangular from the top left to the bottom right with the
        # given Coordinates x,y and height and width
        rect = cv2.rectangle(word_img, (x, y), (x + w, y + h), (0, 255, 0), 0)
    # apply a Character Segmentation and return the output Image
    word_img= character_seg(rect)
    return word_img

# Character segmentation
def character_seg(img):
    #conver the input image int gray scale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Threshold the image
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

    # Apply morphological erosion to remove small artifacts
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,5))
    eroded = cv2.erode(thresh, kernel, iterations=1)

    # Apply morphological dilation to expand the characters
    dilated = cv2.dilate(eroded, kernel, iterations=3)

    # Find contours in the image
    contours, hierarchy = cv2.findContours(dilated, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    # Iterate through each contour and extract the bounding box
    for contour in contours:
            (x, y, w, h) = cv2.boundingRect(contour)
            cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0 ), 2)
    return  img

# Load the test image
image_path = r"C:\Users\student\Desktop\FinalProject\Flask\uploads\1_lWmB8FGf1uWT6r1TichK-Q- 
ezgif.com-webp-to-png-converter.png"
myImage = cv2.imread(image_path)
# Display the image
cv2.imshow('Text Image', myImage)
cv2.waitKey(0)

processed_img = preProcessing(myImage)
cv2.imshow('Text Image', processed_img)
cv2.waitKey(0)

цвет персонажа можно легко использовать в качестве порога с помощью cv2.inRange(). Замените свой подход к выделению серого порога пороговым значением изображения с подходом, который я упомянул.

Tino D 07.05.2024 20:29

@TinoD не совсем понял, не мог бы ты связаться со мной лично и объяснить немного больше?

Nuevo 07.05.2024 21:21

Я опубликую ответ завтра, возможно, также поищу дубликаты...

Tino D 07.05.2024 21:30

Хорошо, я буду следить, спасибо.

Nuevo 07.05.2024 23:14

Эй, ты не выложил оригинальное изображение, можешь, пожалуйста, это сделать?

Tino D 08.05.2024 08:58

Оптимально попробовать следующий подход и опубликовать ответ самостоятельно, если у вас получилось: stackoverflow.com/a/59014523/16815358

Tino D 08.05.2024 08:59

@TinoD Я добавил оригинальное фото

Nuevo 08.05.2024 13:43
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
7
185
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я просто напишу ту часть, где можно было бы улучшить предварительную обработку. Опять же, цвет текста очень легко выбрать и установить пороговое значение с помощью cv2.inRange:

im = cv2.imread("text.png") # read image
lower = (60, 60, 0) # define lower limit
upper = (100, 100, 40) # and upper limit
mask = cv2.inRange(im, lower, upper) # use cv2.inRange
maskClosed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((3,3), dtype = np.uint8)) # use morph close to fill the holes in the mask
plt.imshow(maskClosed) # show mask

Результат:

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

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

Nuevo 09.05.2024 15:14
Ответ принят как подходящий

Как вы можете видеть в выводе ниже, буквы «S» и «T» в слове «STAND» связаны вместе, и я не могу понять, что я сделал. ошибаюсь, буду рад, если вы мне поможете, ребята.

Проблема может быть решена.

Измените iterations=3 в строке 73:

dilated = cv2.dilate(eroded, kernel, iterations=3)  

К:

dilated = cv2.dilate(eroded, kernel, iterations=1) #Change index to 1

Скриншот:

это помогло, можете ли вы объяснить причину изменения? как ты это увидел? и как извлечь область интереса (ROI) из порогового значения двоичного изображения, используя координаты, полученные из ограничивающего прямоугольника. Эта рентабельность инвестиций должна содержать отдельный персонаж

Nuevo 09.05.2024 15:03

Я просто играюсь с итерацией от 3 до 5, а если нет, то уменьшаю с 3 до 1. Только по одному вопросу за раз. Если вы хотите извлечь письмо, отредактируйте другое сообщение.

toyota Supra 09.05.2024 15:12

Другие вопросы по теме