Как отметить особенности, которые присутствуют в обоих массивах в OpenCV? - PullRequest
2 голосов
/ 08 июля 2019

Я пытаюсь написать скрипт Python 3.7 для обнаружения лиц и объектов с помощью файлов классификатора OpenCV Haar, в которых изображения хранятся в виде n-мерных массивов Numpy. Сейчас я работаю только с двумя функциями: - все лицо - Глаза Оба из них получены с использованием двух разных классификаторов. Код обнаруживает наличие обеих этих функций на изображении, а затем помечает их прямоугольником с помощью функции cv2.rectangle () внутри цикла for для каждой функции, т.е. одной для обнаруженных лиц и одной для обнаруженных глаз.

Я хочу, чтобы скрипт отмечал прямоугольники глаз ТОЛЬКО, если эти точки были найдены как в массиве лиц, так и в массиве глаз. numpy.intersect1d () находит пересечение только в одномерных массивах.

Я даже пытался

for x,y,w,h in eyes and x,y,w,h in faces:

и все, что он делает, возвращает это сообщение об ошибке:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Любая помощь будет принята с благодарностью.

Это делается в 64-разрядной версии Windows 10, код написан на Pycharm 2019, OpenCV импортируется как CV2.

# Creating the cascade classifier objects.
face_cascade = 
cv2.CascadeClassifier("haarcascade_frontalface_default.xml")
eye_cascade = cv2.CascadeClassifier("haarcascade_eye.xml")

# Entering and displaying the original image.
img = cv2.imread("filename.jpg", 1)
cv2.imshow("Original Images",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# Convert the image to Black and White and store in a variable.
gry_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 8)
eyes = eye_cascade.detectMultiScale(gry_img, scaleFactor = 1.30, minNeighbors = 12)

# Now, we mark the detected features with a rectangle on the original image.
for x,y,w,h in faces:
    img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 21, 21), 3) # Blue.


for x,y,w,h in eyes:
    img = cv2.rectangle(img, (x,y), (x+w, y+h), (255, 255, 24), 3) # Cyan.

cv2.imshow("Detected Faces and Eyes",img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

О, мальчик, я чувствую себя глупо сейчас.Ну вот и все:

Как сказал ZdaR, документация OpenCV действительно дает прекрасный пример того, как достичь требуемого результата, суть которого:

for x,y,w,h in faces:
    face_img = gry_img[y:y+h, x:x+w]
    # Now detect the eyes in this `face_img` only.
    eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)

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

Код, который наконец заработал:

faces = face_cascade.detectMultiScale(gry_img, scaleFactor = 1.05, minNeighbors = 10)
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y),(x + w, y + h), (255, 0, 0), 3)
    gry_eye = gry_img[y:y+h, x:x+w]
    eye_img = img[y:y + h, x:x + w]
    eyes = eye_cascade.detectMultiScale(gry_eye, scaleFactor = 1.05, minNeighbors = 5)
    for (x, y, w, h) in eyes:
        cv2.rectangle(eye_img, (x, y), (x + w, y + h), (255, 255, 24), 3)

Ну, это был опыт обучения.Спасибо ZdaR за помощь!

0 голосов
/ 08 июля 2019

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

for x,y,w,h in faces:
    face_img = gry_img[y:y+h, x:x+w]
    # Now detect the eyes in this `face_img` only.
    eyes = eye_cascade.detectMultiScale(face_img, scaleFactor = 1.30, minNeighbors = 12)
...