Простое сопоставление шаблонов с python-openCv

Я пытаюсь обнаружить некоторые простые «красные узоры» на изображении. Вот алгоритм, которому я следую: 1) отфильтровать все другие цвета, а не «красный» и создать черно-белое изображение. Я использовал «cvtColor» с соответствующей маской, а затем применил «GaussianBlur», чтобы уменьшить шум. Пока все в порядке.

2) Я использовал функцию «matchTemplate» следующим образом, чтобы обнаружить «стрелку» на изображении.

Проблема: если на фотографии есть шаблон "стрелка", он определяется правильно. Но когда его нет на фото, алгоритм обнаруживает какие-то другие формы, что является ошибкой. Может ли кто-нибудь изменить код, чтобы, когда шаблона стрелки не было на картинке, ничего не обнаруживалось. Вот мой код:

    template = cv2.imread(address,0)
    w, h = template.shape[::-1]
    res = cv2.matchTemplate(self.image['blured'], template, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)
    cv2.rectangle(self.image['blured'],top_left, bottom_right, 255, 2)
    cv2.rectangle(self.image['normal'], top_left, bottom_right, 255,2)

Вот результаты: Обнаружено правильно

введите здесь описание изображения

Неправильные обнаружения: круг определяется как стрелка

введите здесь описание изображения

Мое шаблонное изображение, которое я вырезал точно из основного фото:

введите здесь описание изображения

Кто-нибудь может обнаружить мою ошибку? Я новичок в обработке изображений. Заранее спасибо.


person Danial    schedule 25.11.2015    source источник


Ответы (2)


Вы должны посмотреть на свой max_val и установить для него порог.

Допустим, max_val равно x1, когда изображение содержит стрелку, и x2, когда изображение не содержит стрелки, должно быть x1 > x2. В качестве первого предварительного значения вы можете выбрать threshold=(x1+x2)/2, а затем, если max_val > threshold, то шаблон найден на изображении, иначе шаблон не найден.

Причина в том, что matchTemplate

скользит через image , сравнивает перекрывающиеся фрагменты размером w \times hпротив templ, используя указанный метод, и сохраняет результаты сравнения в result.

и поэтому ваше изображение res всегда будет иметь максимальное значение, независимо от наличия стрелки на изображении.

person Alessandro Jacopson    schedule 25.11.2015

Большое спасибо Алессандро Якопсон. Я изменил код и решил проблему таким образом. Это почти то, что вы предложили:

        template = cv2.imread(address,0)
        w, h = template.shape[::-1]
        res = cv2.matchTemplate(self.image['blured'], template,cv2.TM_CCOEFF_NORMED)
        threshold = 0.9
        loc = np.where( res >= threshold)
        for pt in zip(*loc[::-1]):
           cv2.rectangle(self.image['blured'], pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
           cv2.rectangle(self.image['normal'], pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)

Таким образом, закономерности обнаруживаются достаточно точно. Новая проблема: он чувствителен к направлению и вращению. Он не обнаруживает рисунок, если он повернут, например, на 45 градусов. Есть ли какой-либо параметр, который я могу установить, и заставить алгоритм найти шаблон, даже если он повернут или масштабирован?

person Danial    schedule 25.11.2015
comment
Для Новой проблемы вы должны задать новый вопрос... В любом случае, я думаю, что это будет дубликат этого stackoverflow.com/questions/10666436/ и поэтому, пожалуйста, прежде чем задавать новые вопросы, прочитайте эти ответы. - person Alessandro Jacopson; 25.11.2015