程序是用opencv的dnn模块加载CenterFace的onnx文件做人脸检测的,程序源码在github地址是 https://github.com/hpc203/CenterFace-opencv-dnn-problem
文件夹里有2幅图片,运行 python problem.py,其中problem.py的源码如下
import cv2
from centerface import CenterFace
if __name__ == '__main__':
frame = cv2.imread('1.jpg')
h, w = frame.shape[:2]
landmarks = True
centerface = CenterFace(landmarks=landmarks)
if landmarks:
dets, lms = centerface(frame, h, w, threshold=0.35)
else:
dets = centerface(frame, threshold=0.35)
for det in dets:
boxes, score = det[:4], det[4]
cv2.rectangle(frame, (int(boxes[0]), int(boxes[1])), (int(boxes[2]), int(boxes[3])), (2, 255, 0), 1)
if landmarks:
for lm in lms:
for i in range(0, 5):
cv2.circle(frame, (int(lm[i * 2]), int(lm[i * 2 + 1])), 2, (0, 0, 255), -1)
cv2.namedWindow('out', cv2.WINDOW_NORMAL)
cv2.imshow('out', frame)
# cv2.waitKey(0)
landmarks = True
centerface = CenterFace(landmarks=landmarks)
for i in range(2):
frame = cv2.imread(str(i)+'.jpg')
h, w = frame.shape[:2]
# landmarks = True
# centerface = CenterFace(landmarks=landmarks)
if landmarks:
dets, lms = centerface(frame, h, w, threshold=0.35)
else:
dets = centerface(frame, threshold=0.35)
for det in dets:
boxes, score = det[:4], det[4]
cv2.rectangle(frame, (int(boxes[0]), int(boxes[1])), (int(boxes[2]), int(boxes[3])), (2, 255, 0), 1)
if landmarks:
for lm in lms:
for i in range(0, 5):
cv2.circle(frame, (int(lm[i * 2]), int(lm[i * 2 + 1])), 2, (0, 0, 255), -1)
# cv2.namedWindow('problem', cv2.WINDOW_NORMAL)
# cv2.imshow('problem', frame)
# cv2.waitKey(0)
cv2.namedWindow('problem', cv2.WINDOW_NORMAL)
cv2.imshow('problem', frame)
cv2.waitKey(0)
cv2.destroyAllWindows()
程序先会读取第2张图片,进入centerface做人脸检测,接下来是for循环读取第1张图片做人脸检测,然后读取第2张图片做人脸检测,最后可视化窗口展示第2张图片的人脸检测结果。结果如下
可以看到同一幅图片,只对单张图片做人脸检测和for循环里做人脸检测之后的结果是不一样的。我尝试过把 for循环之前的centerface = CenterFace(landmarks=landmarks)这句话改写在for循环内,也就是说在for循环遍历每张图片的时候,都会重新初始化网络。改成这样之后,人脸检测结果就是一样的了。按理来说,模型初始化只需要做一次,在for循环之前做模型的初始化的,可这样做的结果就不对了,这是什么原因呢?
因此,当读取批量图片或者读取视频做人脸检测时,每张图片在做人脸检测的时候要重新初始化网络。