Ошибка при попытке использовать размытие с Haarcascades

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

import matplotlib.pyplot as plt
import numpy as np
import cv2

people = cv2.imread('Computer-Vision-with-Python/DATA/people.jpg',0)
people2 = cv2.imread('Computer-Vision-with-Python/DATA/people2.jpg')

def display(img, cmap='gray'):
    fig=plt.figure(figsize=(12,10))
    ax = fig.add_subplot(111)
    ax.imshow(img,cmap='gray')

eye_cascade = cv2.CascadeClassifier('Computer-Vision-with-Python/DATA/haarcascades/haarcascade_eye.xml')

def detect_eye(img):
    face_img = img.copy()

    face_rects = eye_cascade.detectMultiScale(face_img,scaleFactor=1.2,minNeighbors=6)

    for (x,y,w,h) in face_rects:
        cv2.rectangle(face_img,(x,y),(x+w,y+h),(255,255,255),10)

    return face_img

def detect_and_blur_eye(img):

    eye_img = img.copy()
    roi = img.copy()

    eye_rects = eye_cascade.detectMultiScale(eye_img,scaleFactor=1.2, minNeighbors=6) 

    for (x,y,w,h) in eye_rects: 
        print (x,y,w,h)
        roi = roi[y:y+h,x:x+w]
        blurred_roi = cv2.medianBlur(roi,7)

        eye_img[y:y+h,x:x+w] = blurred_roi

    return eye_img

results = detect_and_blur_eye(people)

После этого я получаю эту ошибку:


TypeError                                 Traceback (most recent call last)
<ipython-input-259-f561e117d7f8> in <module>
----> 1 results = detect_and_blur_eye(people)

<ipython-input-258-2ab32e080f88> in detect_and_blur_eye(img)
     12         blurred_roi = cv2.medianBlur(roi,7)
     13 
---> 14         eye_img[y:y+h,x:x+w] = blurred_roi
     15 
     16     return eye_img

TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

Я не знаю, что происходит! Пожалуйста, направьте меня в этой ситуации. Заранее спасибо.

ИЗМЕНИТЬ

Я смог обнаружить что-то, что может привести меня к решению проблемы. Я изменил функцию, чтобы получить некоторые значения.

def detect_and_blur_eye(img):

    eye_img = img.copy()
    roi = img.copy()

    eye_rects = eye_cascade.detectMultiScale(eye_img,scaleFactor=1.2, minNeighbors=6) 

    for (x,y,w,h) in eye_rects: 
        print (type(eye_rects))
        print (x,y,w,h)
        roi = roi[y:y+h,x:x+w]
        print(roi.shape)
        #blurred_roi = cv2.medianBlur(roi,7)

        #eye_img[y:y+h,x:x+w] = blurred_roi

    return eye_img

results = detect_and_blur_eye(people)

И это возвращает мне это:

<class 'numpy.ndarray'>
1182 414 45 45
(45, 45)
<class 'numpy.ndarray'>
595 427 56 56
(0, 0)
<class 'numpy.ndarray'>
512 430 57 57
(0, 0)
<class 'numpy.ndarray'>
270 470 60 60
(0, 0)
<class 'numpy.ndarray'>
349 475 56 56
(0, 0)
<class 'numpy.ndarray'>
981 375 62 62
(0, 0)
<class 'numpy.ndarray'>
842 389 50 50
(0, 0)
<class 'numpy.ndarray'>
762 391 50 50
(0, 0)
<class 'numpy.ndarray'>
1072 390 54 54
(0, 0)
<class 'numpy.ndarray'>
1238 399 48 48
(0, 0)

Итак, по какой-то причине моя форма (0,0)


person Arthur Marqueze Batista    schedule 05.05.2020    source источник
comment
Хороший проект! Что произойдет, если вы напечатаете (x, y, w, h) - возможно, лицо не найдено (в некоторых кадрах), поэтому eye_rects равно None, поэтому x, y, w, h (которые должны быть целыми числами для среза roi) имеют неправильный тип. Таким образом, вам, возможно/вероятно, просто нужно обрабатывать эти исключительные случаи.   -  person jtlz2    schedule 05.05.2020
comment
Вы можете опубликовать два образца изображений?   -  person jtlz2    schedule 05.05.2020
comment
Это изображения: p2prh.com.br/wp -content/uploads/2018/07/p2p-talents.jpg и rollingstone.uol.com.br/media/_versions/   -  person Arthur Marqueze Batista    schedule 05.05.2020


Ответы (2)


Да, ваша проблема, как сказал @jtlz2, связана с тем, что глаза не найдены на изображениях и, следовательно, не имеют никакого типа, который, когда вы пытаетесь его назначить, вызывает ошибку. Здесь может быть два обходных пути: либо вы используете лучший классификатор, который заполняет глаза, но затем, если вы хотите использовать его для видео, вам понадобится режим реального времени и вы не сможете использовать CNN. Альтернативой могут быть dlib лицевые ключевые точки. Кроме этого, если вы хотите продолжить работу только с хаар-каскадами, вы можете сделать это:

try:
    print (x,y,w,h)
    roi = roi[y:y+h,x:x+w]
    blurred_roi = cv2.medianBlur(roi,7)

    eye_img[y:y+h,x:x+w] = blurred_roi
except:
    pass

Таким образом, если есть какие-либо ошибки, ваши глаза не будут размыты, но программа не выдаст ошибку.

person Vardan Agarwal    schedule 05.05.2020
comment
Мне жаль, что я не понял, что вы пытались сказать. - person Vardan Agarwal; 05.05.2020
comment
Я только что отредактировал сообщение с некоторой полезной информацией, возможно, это может помочь! Спасибо за ваше время - person Arthur Marqueze Batista; 05.05.2020
comment
Вам действительно не следует использовать голый оператор, кроме - возможно, по крайней мере, напечатать предупреждение? :) - person jtlz2; 06.05.2020

Я смог обнаружить проблему. В функции мне нужно сбросить ROI, прежде чем получить другое значение, а я этого не делал.

def detect_and_blur_eye(img):

    eye_img = img.copy()
    roi = img.copy()

    eye_rects = eye_cascade.detectMultiScale(eye_img,scaleFactor=1.2, minNeighbors=6,minSize=(5,5)) 

    for (x,y,w,h) in eye_rects:
        roi = img.copy()
        print (type(eye_rects))
        print (x,y,w,h)
        roi = roi[y:y+h,x:x+w]
        print(roi.shape)
        blurred_roi = cv2.medianBlur(roi,21)
        eye_img[y:y+h,x:x+w] = blurred_roi

    return eye_img

Это работает!

person Arthur Marqueze Batista    schedule 05.05.2020
comment
А если на изображении (кадре) нет глаз - что тогда? Этот случай обязательно произойдет, когда вы начнете применять это к видео. - person jtlz2; 06.05.2020
comment
Почему бы просто не сделать roi = img[y:y+h,x:x+w] ? Вы также можете передать img непосредственно в детектор, а не делать копию каждый раз - person jtlz2; 06.05.2020