人脸检测,好像用到了深度学习,我觉得很厉害,其实通过opencv可以做一个人脸识别窗口。今天,Runsen将构建一个简单的Python脚本,使用OpenCV库中的两种方法来处理图像中的人脸。首先,我们将使用haar级联分类器,这对初学者来说是一种简单(但不太准确)的方法,也是最方便的。第二种是single-shotmulti-boxdetector(简称SSD),是深度神经网络检测图像中物体的一种方法。使用Haar级联进行人脸检测对于基于haar特征的级联分类器,OpenCV已经为我们提供了一些分类器参数,所以我们不需要训练任何模型,直接使用即可。opencv安装pipinstallopencv-python我们先导入OpenCV:importcv2来测试下面的示例图片,我在学校找到了两个漂亮美女的图片:image=cv2.imread("beauty.jpg")functionimread()Loadsanimagefrom指定的文件并将其作为numpyN维数组返回。在检测图像中的人脸之前,我们首先需要将图像转换为灰度图:下图image_gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY),因为要初始化人脸识别器(默认人脸haarcascade),需要下载相应的参数xml文件,这里选择初始的haarcascade_frontalface_default.xml下面的代码是加载和使用人脸识别器face_cascade=cv2.CascadeClassifier("haarcascade_fontalface_default.xml")现在让我们检测图像中的所有人脸:#DetectintheimageAllfacesoffaces=face_cascade.detectMultiScale(image_gray)print(f"{len(faces)}facesdetectedintheimage.")detectMultiScale()函数以一张图像为参数,检测不同大小的物体为列表的矩形,所以我们绘制矩形,这里也提供了一个矩形方法#为每个面绘制一个蓝色的矩形forx,y,width,heightinfaces:#这里的颜色是蓝黄红,与rgb相反,thickness设置宽度Cv2.rectangle(image,(x,y),(x+width,y+height),color=(255,0,0),thickness=2)最后,让我们保存新图像:cv2.imwrite("beauty_detected.jpg",image)levelbasedonhaarfeatures我们惊讶地发现图1中因为障碍物没有设备。我们惊奇的发现图2设置了两个窗口。Haarcascade结合camera使用Haarcascade做人脸检测可以说是opencv最基础的效果了。接下来我们用相机结合Haar级联,这样就可以达到一开始的效果了。importcv2#新建cam对象cap=cv2.VideoCapture(0)#初始化人脸识别器(默认人脸haarcascade)face_cascade=cv2.CascadeClassifier("haarcascade_fontalface_default.xml")whileTrue:#从摄像头读取图像_,image=cap.read()#转换为灰度image_gray=cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)#检测图像中的所有人脸faces=face_cascade.detectMultiScale(image_gray,1.3,5)#为每个人的脸画一个蓝色矩形forx,y,width,heightinfaces:cv2.rectangle(image,(x,y),(x+width,y+height),color=(255,0,0),thickness=2)cv2.imshow("image",image)ifcv2.waitKey(1)==ord("q"):breakcap.release()cv2.destroyAllWindows()上面使用SSD进行人脸检测的效果已经过时了,但是OpenCV为我们提供了dnn模块包中的cv2,这样可以直接加载预训练的深度学习模型。2015年底,有人提出实时物体检测网络SingleShotMultiBoxDetector,简称SSDSSD物体检测。ModelSSD物体检测网络简单来说可以分为三部分:这里的基础网络(backbone)是VGG16特征提取Neck,构建多尺度特征检测Header——非极大值抑制和输出要开始在OpenCV中使用SSD,需要下载RESNET人脸检测模型及其预训练的权重,然后保存到代码权重工作目录:RESNET人脸检测模型和权重importcv2importnumpyasnp#下载链接:https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy.prototxtprototxt_path="weights/deploy.prototxt.txt"#下载地址:https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_pathiter_140000.caffeweightsmodel1="res10_300x300_ssd_iter_140000_fp16.caffemodel"#加载Caffemodelmodel=cv2.dnn.readNetFromCaffe(prototxt_path,model_path)#读取所需图像image=cv2.imread("beauty.jpg")#获取图片的宽高h,w=image.shape[:2]现在,这个图像需要传递给神经网络,因为下载的模型是(300,300)px。因此,我们需要将图像调整为(300,300)px形状:#Preprocessimage:resizeandperformmeansubtraction。104.0,177.0,123.0代表b通道的值-104,g-177,r-123#在深度学习中,图像归一化是通过减去数字人脸数据集的图像均值而不是当前图像均值,所以这里很难写blob=cv2.dnn.blobFromImage(image,1.0,(300,300),(104.0,177.0,123.0))使用这个blob对象作为神经网络的输入来得到检测到的人脸:#Inputthe图像进入神经网络网络model.setInput(blob)#得到结果output=np.squeeze(model.forward())输出对象output有所有检测到的对象,本例一般是人脸,让我们遍历输出,并在取置信度大于50%的判断条件:font_scale=1.0#output.shape==(200,7)foriinrange(0,output.shape[0]):#confidencedegreeconfidence=output[i,2]#ifConfidenceishigherthan50%,thendrawthesurroundingboxifconfidence>0.5:#之前将图片改为300*300,然后提取检测到的模型的置信度object,我们得到周围的boxoutput[i,3:7],然后将其宽高乘以原图之和,得到正确的box坐标box=output[i,3:7]*np.array([w,h,w,h])#转为整数start_x,start_y,end_x,end_y=box.astype(np.int)#画一个矩形cv2.rectangle(image,(start_x,start_y),(end_x,end_y),color=(255,0,0),thickness=2)#添加文字cv2.putText(image,f"{confidence*100:.2f}%",(start_x,start_y-5),cv2.FONT_HERSHEY_SIMPLEX,font_scale,(255,0,0),2)最后我们展示并保存新图片:cv2.imshow("image",image)cv2.waitKey(0)cv2.imwrite("beauty_detected.jpg",image)下面是完整的代码importcv2importnumpyasnp#下载链接:https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy.prototxtprototxt_path="weights/deploy.prototxt.txt"#下载链接:https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodelmodel_path="weights/res10_300x300_ssd_iter_140000_fp16.caffemodel"model=cv2.dnn.readNetFromCaffe(prototxt_path,model_path)image=cv2.imread("beauty.jpg")h,w=image.shape[:2]blob=cv2.dnn.blobFromImage(image,1.0,(300,300),(104.0,177.0,123.0))model.setInput(blob)output=np.squeeze(model.forward())font_scale=1.0对于iinrange(0,output.shape[0]):confidence=output[i,2]ifconfidence>0.5:box=output[i,3:7]*np.array([w,h,w,h])start_x,start_y,end_x,end_y=box.astype(np.int)cv2.rectangle(image,(start_x,start_y),(end_x,end_y),颜色=(255,0,0),thickness=2)cv2.putText(image,f"{confidence*100:.2f}%",(start_x,start_y-5),cv2.FONT_HERSHEY_SIMPLEX,font_scale,(255,0,0),2)cv2.imshow("image",image)cv2.waitKey(0)cv2.imwrite("beauty_detected.jpg",image)SSD结合摄像头SSD结合摄像头的人脸检测方法更好更准确,但是FPS在每秒传输帧数方面可能会低一些,因为它没有Haarcascade方法快,但这不是什么大问题下面下面ssdssd结合结合的人脸检测检测全部代码importcv2importnumpyasnumpyasnumpyasnumpyasnumpyasnpprotxt_path=“strige.prototxtxt.0)whileTrue:_,image=cap.read()h,w=image.shape[:2]blob=cv2.dnn.blobFromImage(image,1.0,(300,300),(104.0,177.0,123.0))模型。setInput(blob)output=np.squeeze(model.forward())font_scale=1.0foriinrange(0,output.shape[0]):confidence=output[i,2]ifconfidence>0.5:box=output[i,3:7]*np.array([w,h,w,h])start_x,start_y,end_x,end_y=box.astype(np.int)cv2.rectangle(image,(start_x,start_y),(end_x,end_y),color=(255,0,0),thickness=2)cv2.putText(image,f"{confidence*100:.2f}%",(start_x,start_y-5),cv2.FONT_HERSHEY_SIMPLEX,font_scale,(255,0,0),2)cv2.imshow("图像",图像)ifcv2.waitKey(1)==ord("q"):breakcv2.destroyAllWindows()cap.release()
