如何提高Viola-Jones算法进行人脸检测的准确性

问题描述

我正在使用Viola-Jones算法进行面部识别,是带有网络摄像头的Raspberry Pi。 我正在为此使用opencv的haar级联文件(https://github.com/opencv/opencv/blob/master/data/haarcascades/haarcascade_frontalface_default.xml) 该系统不准确,无法在多种光照条件下或发生任何遮挡的情况下工作。

如何提高准确性?

解决方法

建议#1


您尝试使用python的face-recognition库吗?

  • 该识别正在处理两个样本图像作为输入:

    enter image description here enter image description here

  • 从提取的训练图像的面部编码中预测下一幅图像。

    enter image description here

  • 结果如下:

    enter image description here

  • 代码:

import face_recognition
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image,ImageDraw

# Load a sample picture and learn how to recognize it.
first_image = face_recognition.load_image_file("images/ex.jpg")
first_face_encoding = face_recognition.face_encodings(first_image)[0]

# Load a second sample picture and learn how to recognize it.
second_image = face_recognition.load_image_file("images/index.jpg")
sec_face_encoding = face_recognition.face_encodings(second_image)[0]

# Create arrays of known face encodings and their names
known_face_encodings = [
    first_face_encoding,sec_face_encoding
]

print('Learned encoding for',len(known_face_encodings),'images.')

# Load an image with an unknown face
unknown_image = face_recognition.load_image_file("images/girlszz.jpg")

# Find all the faces and face encodings in the unknown image
face_locations = face_recognition.face_locations(unknown_image)
face_encodings = face_recognition.face_encodings(unknown_image,face_locations)

# Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
# See http://pillow.readthedocs.io/ for more about PIL/Pillow
pil_image = Image.fromarray(unknown_image)
# Create a Pillow ImageDraw Draw instance to draw with
draw = ImageDraw.Draw(pil_image)

# Loop through each face found in the unknown image
for (top,right,bottom,left),face_encoding in zip(face_locations,face_encodings):
    matches = face_recognition.compare_faces(known_face_encodings,face_encoding)
    face_distances = face_recognition.face_distance(known_face_encodings,face_encoding)
    best_match_index = np.argmin(face_distances)
    draw.rectangle(((left,top),(right,bottom)),outline=(0,255),width=5)

# Remove the drawing library from memory as per the Pillow docs
del draw

# Display the resulting image
plt.imshow(pil_image)
plt.show()  

建议#2


  • 使用GaussianBlur消除闪电效果。

示例图片:

enter image description here

Haar特征在上图中很难找到人脸。

应用GaussianBlur

enter image description here

现在应用类似Haar的功能

enter image description here

  • 代码
import numpy as np
import cv2

# read the image
img = cv2.imread('yaleB13_P00_Ambient.pgm')

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# blur
smooth = cv2.GaussianBlur(gray,(95,95),0)

# divide gray by morphology image
division = cv2.divide(gray,smooth,scale=192)

# save results
cv2.imwrite('face_shaded_division.jpg',division)

# read the image
img = cv2.imread('face_shaded_division.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
face_cascade = cv2.CascadeClassifier('/Users/ahmettavli/Downloads/opencv/data/haarcascades/haarcascade_frontalface_default.xml')

faces = face_cascade.detectMultiScale(img,1.3,5)
for (x,y,w,h) in faces:
    img = cv2.rectangle(img,(x,y),(x+w,y+h),(255,0),2)
    roi_gray = gray[y:y+h,x:x+w]
    roi_color = img[y:y+h,x:x+w]
cv2.imwrite('output.png',img)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

我认为第二个建议比第一个建议更具成本效益。

注意:

  • 我实现了cv2.imread两次,您不必这样做。一次读取图像就足够了。例如:

    # read the image
    img = cv2.imread('yaleB13_P00_Ambient.pgm')
    .
    .
    cv2.imwrite('face_shaded_division.jpg',division)
    # You don't have to write the image,instead 
    # Comment the below statement
    faces = face_cascade.detectMultiScale(img,5)
    
    # And use `division` 
    faces = face_cascade.detectMultiScale(division,5)
    
,

我建议您采用ResNet SSD(单发多盒检测器)代替haar级联。因为这在后台使用了基于深度学习的方法。它的结果比haar-cascade更准确,并且执行速度更快。

此外,OpenCV包含了haar级联和SSD方法。

先决条件:deploy.prototxtres10_300x300_ssd_iter_140000.caffemodel

detector = cv2.dnn.readNetFromCaffe("deploy.prototxt","res10_300x300_ssd_iter_140000.caffemodel")
detector.setInput(imageBlob) #imageBlob should be (1,3,300,300) shaped array
detections = detector.forward()

然后检测将返回7列数组。它的第3列是置信度得分,第4到第7列是检测到的脸部坐标。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...