Объединение перекрывающегося прямоугольника с opencv

Я использую два каскадных алгоритма Хаара (фронтальный и профиль) с OpenCV одновременно, чтобы улучшить распознавание лиц.

К сожалению, обнаружение работает некорректно, и я не знаю, как это исправить. Возвращаемое значение - 2 (на картинке с 5 лицами, обычно обнаруженными), и все прямоугольники исчезли.

Это ожидаемый результат (без перекрывающихся прямоугольников):

image

Это исходное изображение (а также файл result.jpg), если вы хотите провести свой собственный тест.

Это код:

import cv2
import numpy as np

image=cv2.imread("/home/pi/Downloads/test.jpg")
face_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt.xml")
profil_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_profileface_alt.xml")

gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
face=face_cascade.detectMultiScale(gray, 1.06, 5)
profil=profil_cascade.detectMultiScale(gray, 1.1, 5)

combined_array=np.append(face, profil, axis=0)
combined_list=combined_array.tolist()
result=cv2.groupRectangles(combined_list,2)

print("I've found "+str(len(result))+ " face(s)")

for (x,y,w,h) in result[0]:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)

cv2.imwrite("/home/pi/Download/result.jpg", image)

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

Daneel R. 13.09.2018 20:14

Спасибо за предложение, я сделал это :)

user10010413 13.09.2018 20:25

Код все еще не воспроизводится, потому что CascadeClassifier('filepath') пытается загрузить классификатор из файла, который недоступен для пользователей SO. Кроме того, вы можете загрузить образ result.jpg, который появляется после выполнения, чтобы показать сравнение с тем, которое вы хотите. В любом случае вполне возможно, что вы используете предварительно обученную модель, которая не так эффективна, как вы думаете.

Daneel R. 13.09.2018 20:41

Вы правы, я внес изменения. Я не думал об этом, потому что я использую классические алгоритмы haarcascade, которые интегрированы с OpenCV, но это хороший момент, чтобы добавить эту информацию.

user10010413 13.09.2018 21:06

Я имел в виду, что весьма вероятно, что неожиданный результат, который вы получите, зависит от модели, которую вы загружаете. У нас нет доступа к "/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontal‌​face_alt.xml", поэтому мы не можем тестировать / отлаживать ваш код. Вам нужно будет либо опубликовать его и позволить нам загрузить его таким образом, либо найти веб-сайт, на котором он доступен, и позволить нам загрузить его оттуда. В противном случае проблема не может быть воспроизведена.

Daneel R. 13.09.2018 21:43

Найдите NMS.

Kinght 金 14.09.2018 02:10

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

user10010413 14.09.2018 11:21
1
7
4 135
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

После долгих исследований я частично решил проблему.

Я изменил Порог и EPS для result=cv2.groupRectangles, а также сделал вычитание в функции print между общим количеством обнаруженных лиц (в комбинированный_лист) и количеством обнаруженных перекрытий (возвращается результат)

Вот новый код:

import cv2
import numpy as np

image=cv2.imread("/home/pi/Downloads/test.jpg")
face_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_frontalface_alt.xml")
profil_cascade=cv2.CascadeClassifier("/home/pi/opencv-3.4.0/data/haarcascades/haarcascade_profileface_alt.xml")

gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
face=face_cascade.detectMultiScale(gray, 1.06, 5)
profil=profil_cascade.detectMultiScale(gray, 1.1, 5)

combined_array=np.append(face, profil, axis=0)
combined_list=combined_array.tolist()
result=cv2.groupRectangles(combined_list,1,0.85)

print("I've found "+str(len(combined_list)-str(len(result[1]))+ " face(s)")

for (x,y,w,h) in result[0]:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),2)

cv2.imwrite("/home/pi/Download/result.jpg", image)

Перекрывающиеся прямоугольники исчезли ... но также и другие прямоугольники!

Наконец, программа выдала мне правильный номер лица (5) и перерисовала перекрывающийся прямоугольник (это хорошая новость), но неперекрывающиеся прямоугольники исчезли ...

Я попытался решить эту проблему, используя np.subtract между координатами из комбинированный_лист и результат, затем нарисовал недостающий прямоугольник с помощью for (x,y,w,h) in np.subtract[0], но это не сработало. Причина в том, что координатная точка перекрывающегося прямоугольника пересчитывается напрямую, поэтому я не могу выполнить вычитание с исходными координатными точками.

Если у кого-то есть идея решить эту проблему, не сомневайтесь :)

Для функции groupRectangles openCV требуется 3 входа.

1) rectList: вектор прямоугольников

2) групповой порог: Минимально возможное количество прямоугольников минус 1

3) eps: относительная разница между сторонами прямоугольников, чтобы объединить их в группу.

Ваш код:

   result=cv2.groupRectangles(combined_list,1,0.85)

Из вашего кода вы установили параметр groupthreshold как 1, который отклоняет все кластеры с одним прямоугольником. Установите для этого параметра значение 0, и вы должны получить желаемый результат.

Решение:

   result=cv2.groupRectangles(combined_list,0,0.85)

Подробное объяснение приведено ниже: (https://docs.opencv.org/3.4/d5/d54/group__objdetect.html#ga3dba897ade8aa8227edda66508e16ab9)

Спасибо за ваш совет, который имеет смысл, но, к сожалению, он не работает: o Когда я вношу изменения, у меня есть весь прямоугольник (но также и перекрывающийся прямоугольник)

user10010413 14.09.2018 14:45

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

yapws87 15.09.2018 04:43

Алгоритм Non Maximum Suppression используется для решения проблемы перекрытия результатов обнаружения. У Pyimagesearch есть очень хорошая статья и код, который поможет вам двигаться в правильном направлении.

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