Как убрать ложное распознавание лиц в python OpenCV - PullRequest
0 голосов
/ 07 апреля 2020

Я делаю face detection, используя python opencv. Для этого я использую caffe model. Ниже приведен код:

import numpy as np
import imutils
import cv2

protoPath = "<path_to_file>\\deploy.prototxt"
modelPath = "<path_to_file>\\res10_300x300_ssd_iter_140000.caffemodel"
detector = cv2.dnn.readNetFromCaffe(protoPath, modelPath)

image = cv2.imread('test.jpg')
image = imutils.resize(image, width=600)

(h, w) = image.shape[:2]

imageBlob = cv2.dnn.blobFromImage(cv2.resize(image, (300, 300)), 1.0, (300, 300), (104.0, 177.0, 123.0), swapRB=False, crop=False)

detector.setInput(imageBlob)
detections = detector.forward()

if len(detections) > 0:
    i = np.argmax(detections[0, 0, :, 2])
    confidence = detections[0, 0, i, 2]

    if confidence > 0.5:
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")

        cv2.rectangle(image, (startX, startY), (endX, endY), (0, 0, 255), 2)

cv2.imshow("Image", image)
cv2.waitKey(0)

Приведенный выше код прекрасно работает практически для всех изображений. Например, ниже:

enter image description here

Как видно, лицо распознается с уверенностью 96%. Но во многих случаях код обнаруживает ложные лица, как показано ниже:

enter image description here

Вышеуказанное лицо обнаруживается, но также имеет ложные обнаружения и шокирует то, что доверие к обоим обнаружениям было больше, чем 90%

Когда бы у меня не было такого рода ложных обнаружений, я использую какой-нибудь онлайн-детектор лица для быстрой проверки, например этот и результаты выглядят хорошо:

enter image description here

и из-за этого я иногда чувствую, что модель, которую я использую для face detection, достаточно хороша или нет.

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

РЕДАКТИРОВАТЬ:

Даже после выполнения не максимального подавления, кажется, что он не работает:

def non_max_suppression_fast(self, boxes, overlapThresh):
    try:
        self.dummy = ''
        if len(boxes) == 0:
            return []

        if boxes.dtype.kind == "i":
            boxes = boxes.astype("float")

        pick = []

        x1 = boxes[:, 0]
        y1 = boxes[:, 1]
        x2 = boxes[:, 2]
        y2 = boxes[:, 3]

        area = (x2 - x1 + 1) * (y2 - y1 + 1)
        idxs = np.argsort(y2)

        while len(idxs) > 0:
            last = len(idxs) - 1
            i = idxs[last]
            pick.append(i)

            xx1 = np.maximum(x1[i], x1[idxs[:last]])
            yy1 = np.maximum(y1[i], y1[idxs[:last]])
            xx2 = np.minimum(x2[i], x2[idxs[:last]])
            yy2 = np.minimum(y2[i], y2[idxs[:last]])

            w = np.maximum(0, xx2 - xx1 + 1)
            h = np.maximum(0, yy2 - yy1 + 1)

            overlap = (w * h) / area[idxs[:last]]

            idxs = np.delete(idxs, np.concatenate(([last],
                                                   np.where(overlap > overlapThresh)[0])))

        return boxes[pick].astype("int")
    except Exception as e:
        print("Exception occurred in non_max_suppression : {}".format(e))

###
SOME CODE
###

rects = []
for i in range(0, detections.shape[2]):

    confidence = detections[0, 0, i, 2]

    if confidence > 0.5:
        box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
        (startX, startY, endX, endY) = box.astype("int")

        rects.append(box)

boundingboxes = np.array(rects)
boundingboxes = boundingboxes.astype(int)
rects = non_max_suppression_fast(boundingboxes, 0.3)

boundingBoxes до прохождения non_max_suppression_fast равно [[311 280 644 719], [131 114 419 475]], а после подавления все равно rects = [[311 280 644 719], [131 114 419 475]]

Ответы [ 2 ]

0 голосов
/ 08 апреля 2020

Я решил это. Хотя подход, который я использовал, дал мне 99% точности, но я не уверен, правильный ли подход или нет.

Поэтому всякий раз, когда я получаю ложные определения на изображениях лиц, как показано ниже:

enter image description here

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

res = check_false_detections(h, w, startX, startY, endX, endY)
if not res:
    print("Got false detection")
    continue

, а вот код для check_false_detections:

def check_false_detections(ih, iw, fsx, fsy, fex, fey):
    if ih > iw:
        if fsx > ih:
            return False
        elif fsy > ih:
            return False
        elif fex > ih:
            return False
        elif fey > ih:
            return False
        else:
            return True
    else:
        if fsx > iw:
            return False
        elif fsy > iw:
            return False
        elif fex > iw:
            return False
        elif fey > iw:
            return False
        else:
            return True

Это отлично работает для моего варианта использования. Я проверил более 150 изображений. Это может не сработать ни для кого, но стоит попробовать.

Спасибо

0 голосов
/ 07 апреля 2020

вы должны предоставить больше наборов данных, это единственное решение

...