Как определить цветной текст с расстояния 6 метров?

Я использую python, PIL, opencv и numpy для обнаружения одноцветных текстов (т.е. один красный, один зеленый). Я хочу обнаружить этот красочный текст на расстоянии до 6 метров во время прямой трансляции. Я использовал методы определения цвета, но они не работали после 30-50 см. Камера должна быть близка к цветам. В качестве второго метода обнаружения этих текстов я использовал метод ctpn. Хотя он обнаруживает тексты, он не предоставляет координаты этих текстов, так как мне также нужны координатные точки текстов. Я также попробовал метод OCR в Matlab для автоматического обнаружения текста в естественном изображении, но это не удалось, поскольку он находит другие небольшие объекты как текст. Я так застрял в том, что делать.

Скажем, например, на изображении, снятом с расстояния 6 метров, есть два разных текста. Один текст зеленый, другой красный. Ширина этих текстов примерно 40-50 см. Кроме того, это всего лишь два разных слова, а не длинные тексты. Как я могу обнаружить их и указать их местоположение как (x1, y1) и (x2, y2)? Это возможно ? Нужен любой успешный намек?

Образец изображения, снятый с расстояния почти 2-2,5 метра, а ширина текста составляет почти 20 см.

Вывод обнаруженных зеленых пикселей.

import numpy as np
from PIL import Image

# Open image and make RGB and HSV versions
RGBim = Image.open("AdjustedNewMaze3.jpg").convert('RGB')
HSVim = RGBim.convert('HSV')

# Make numpy versions
RGBna = np.array(RGBim)
HSVna = np.array(HSVim)

# Extract Hue
H = HSVna[:,:,0]

# Find all green pixels, i.e. where 100 < Hue < 140
lo,hi = 100,140
# Rescale to 0-255, rather than 0-360 because we are using uint8
lo = int((lo * 255) / 360)
hi = int((hi * 255) / 360)
green = np.where((H>lo) & (H<hi))

# Make all green pixels black in original image
RGBna[green] = [0,0,0]

def find_nearest(array, value):
    array = np.asarray(array)
    idx = (np.abs(array - value)).argmin()
    return array[idx]

value = 120 & 125

green = find_nearest(RGBna, value)
print(green)

count = green[0].size
print("Pixels matched: {}".format(count))
Image.fromarray(green).save('resultgreen.png')

person Ender Ayhan    schedule 08.09.2018    source источник
comment
Фокусное расстояние объектива будет играть важную роль в размере текста на изображениях. Предоставьте образцы изображений.   -  person Mark Setchell    schedule 08.09.2018
comment
Фокусное расстояние @MarkSetchell моей камеры: [1171,02428928540 1170,24715742738]. Я прикрепил к сообщению масштабированное изображение прототипа моей среды.   -  person Ender Ayhan    schedule 08.09.2018
comment
Посмотрите мой ответ здесь для обнаружения пикселей определенного цвета... stackoverflow.com/a/52183666/2836621 Однако обратите внимание, что если вы используете OpenCV, оттенки масштабируются в диапазоне 0-180, а не 0-255, который использует PIL.   -  person Mark Setchell    schedule 08.09.2018
comment
Я попробовал ваш код, он просто нашел букву в слове. Вот почему расстояние является главной проблемой. @МаркСетчелл   -  person Ender Ayhan    schedule 08.09.2018
comment
Вы увидите, что исходное изображение было круглым (потому что есть альфа-канал, делающий углы прозрачными), но это было проигнорировано в первом фрагменте кода, и результат получился квадратным, потому что я его проигнорировал. Во втором примере я сохранил альфа-канал. канал с savedAlpha = im.getchannel('A') и восстановил его в конце с result.putalpha(savedAlpha). Настоящие камеры обычно не создают альфа-каналы — это делают только специалисты по графике :-)   -  person Mark Setchell    schedule 08.09.2018
comment
@MarkSetchell Я тебя понял, спасибо за подсказку и информацию. Хотя ваш код не дает точного решения, до сих пор это лучший источник для меня. спасибо! Еще одна вещь, что вы можете порекомендовать мне для поиска, чтобы я мог получить больше значений красного и зеленого в пикселях издалека?   -  person Ender Ayhan    schedule 08.09.2018
comment
На самом деле вы можете использовать только более длинный объектив, но это даст вам меньшее поле зрения, и вам придется перемещать его, чтобы захватить всю сцену. Не уверен, что вы можете сделать на самом деле.   -  person Mark Setchell    schedule 08.09.2018
comment
все равно спасибо. И последнее, но не менее важное: я увеличил значение контраста, используя clahe на исходном изображении. Теперь он находит больше зеленых пикселей. Однако он также находит зеленые пиксели на красном тексте и где-то рядом. Могу ли я выполнить математическую операцию с координатами зеленого пикселя, чтобы получить реальную зеленую область. Я имею в виду, можно ли использовать numpy для поиска ближайшей и самой большой области зеленых пикселей? так что я могу указать реальную зеленую зону. Я прикрепил выходное изображение в посте. @МаркСетчелл   -  person Ender Ayhan    schedule 08.09.2018
comment
Больше света, жирнее + ярче текст тоже очень поможет. Может быть, вы можете посветить двумя огнями специально на знаки, если у вас есть контроль над этим?   -  person devdob    schedule 08.09.2018
comment
@devdob В реальной ситуации тексты жирнее и ярче. Но световое состояние от меня не зависит. Даже если я смогу сделать то, что вы сказали, код определения цвета все равно будет иметь несколько пикселей в разных местах. Можно ли применить операцию numpy для области с наибольшей плотностью зеленого и красного?   -  person Ender Ayhan    schedule 08.09.2018
comment
Я не эксперт в Numpy, но, возможно, его функция unique() поможет вам лучше найти ваши значения.   -  person devdob    schedule 08.09.2018
comment
Прикрепил код в пост. Я нашел ближайшее значение к значению между зелеными пикселями. Я хочу построить эту точку на исходном изображении. Как я могу это сделать ? @девдоб   -  person Ender Ayhan    schedule 08.09.2018
comment
Используя PIL, вы можете использовать Image.open() и ImageDraw.Draw для управления изображением по своему усмотрению. Проверьте этот небольшой пример здесь effbot.org/imagingbook/imagedraw.htm   -  person devdob    schedule 08.09.2018