【使用OpenCV进行照片人脸检测】------机器学习(附完整代码和数据集)

今天学习的是OpenCV进行照片人脸检测,所有的参考博文、文献、视频、代码都会在文末附上链接或文件压缩包。

本文的目录如下:

一、OpenCV 简介

1.什么.OpenCV

OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,拥有丰富的常用图像处理函数库,采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上,能够快速的实现一些图像处理和识别的任务。此外,OpenCV还提供了Java、python、cuda等的使用接口、机器学习的基础算法调用,从而使得图像处理和图像分析变得更加易于上手,让开发人员更多的精力花在算法的设计上。

2.为什么使用OpenCV?

虽然 python 很强大,而且也有自己的图像处理库 PIL,但是相对于OpenCV 来讲,它还是弱小很多。跟很多开源软件一样 OpenCV 也提供了完善的 python 接口,非常便于调用。它包含了超过 2500 个算法和函数,几乎任何一个能想到的成熟算法都可以通过调用 OpenCV 的函数来实现,超级方便。

二、Opencv 进行照片人脸检测

1、代码

# -*- coding: utf-8 -*-


import cv2 as cv
 
 
def face_detect_demo(img):
    img = cv.resize(img, dsize=(800, 800))
    gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    face_detect = cv.CascadeClassifier("./opencv/sources/data/haarcascades/haarcascade_frontalface_alt2.xml")#haarcascade_frontalface_default.xml")
    face = face_detect.detectMultiScale(gary, 1.004, 28, 6, (60, 60), (70, 70))
    for x, y, w, h in face:
        cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 225), thickness=4)
    cv.imshow("result", img)
    # img.save("result.jpg")  # 保存图片
    cv.imwrite(r"final_result.jpg", img)
 
img = cv.imread("photo.jpg")
face_detect_demo(img)  # 检测单个图片
 
while True:
    if ord("q") == cv.waitKey(1):
        break
cv.destroyAllWindows()

2、代码解释

detectMultiScale()函数 详细解释

1. import cv2 as cv

首先导入我们所需要的必要包opencv,对应指令为import cv2 as cv,这里的as就相当于给这个模块起了个别名。
如果opencv还没有安装的话,可以在终端里面pip install opencv-python。

2. def face_detect_demo(img):

接着,我们定义一个函数face_detect_demo,这个函数有一个参数img,即我们要检测的图片,这是一个形参。

3. img = cv.resize(img, dsize=(800, 800))

调用cv里面的函数resize,改变图片的大小。
resize第一个参数是要处理的图片,第二个参数是你想要改成图片的大小,
这里的(800,800)就是改成800*800的这样一张图片。处理的结果再返回给img。

4. gary = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

接下来更改图片颜色,直接调用cvtColor函数,
同样,第一个参数是要处理的图片,第二个参数是要更改的颜色类型,
这里的颜色类型有很多种,我这里设置的是COLOR_BGR2GRAY类型。

前几步,可以理解为将图片标准化,即传入不同大小,不同颜色的图片可以转化成同一大小,同一颜色类型的图片。这样的操作好处在于后面调参数更容易。

5. face_detect = cv.CascadeClassifier("./opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml")

重头戏来了!=,这是opencv官方已经训练好的一个人脸检测模型,直接调用就可以,非常方便!
文件链接:https://pan.baidu.com/s/1FV3NWT3Vayq3eKq2QsB3mg?pwd=tsvd 提取码:tsvd
文件和代码提取链接,也有一些其他训练好的模型,如果感兴趣的话你也可以试一试其他模型。

6. face = face_detect.detectMultiScale(gary, 1.004, 10, 0, (40, 40), (50, 50))

接着,我们检测图片中的人脸,face_detect.detectMultiScale,就是调用模型里的detectMultiScale。
detectMultiScale(image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]) -> objects
第一个参数 image是要处理的图片,一般为灰度图像加快检测速度;
第二个参数 scaleFactor是表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%;比例越小,迭代的次数越多。
Haar cascade的工作原理是一种“滑动窗口”的方法,通过在图像中不断的“滑动检测窗口”来匹配人脸。
因为图像的像素有大有小,图像中的人脸因为远近不同也会有大有小,所以需要通过scaleFactor参数设置一个缩小的比例,对图像进行逐步缩小来检测,这个参数设置的越大,计算速度越快,但可能会错过了某个大小的人脸。
其实可以根据图像的像素值来设置此参数,像素大缩小的速度就可以快一点,通常在1~1.5之间。
那么,经过多次的迭代,实际会检测出很多很多个人脸,这一点可以通过把minNeighbors 设为0来验证。
第三个参数 minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框。
这里有点不太好理解,相邻矩形指的是对于同一张候选人脸(尚未确定)多次迭代后识别到的框,只有这个相邻框的个数大于自己设定的minneighbor,才会确定这个候选人脸框是正确的。
下面举例说明:
minNeighbors=0可以理解为每个人像只要被识别到一次就可以,因为一次对应一个方框。比如,参考博文中的这些图人脸检测,下图最右上角李斯被识别出1次,这个方框邻居数为0。

在这里插入图片描述
但假如minNeighbors=1,至少有一个邻居方框,那就意味着被识别出来至少两次。下图李斯没识别出来,因为她的识别结果中没有“邻居”;
在这里插入图片描述
minNeighbors=3,至少有3个邻居方框,那就意味着被识别出来至少4次。下图孟佳也没有识别出来,因为她的识别结果中只有1个“邻居”。
在这里插入图片描述
第四个参数 flag参数与旧的级联方法cvHaarDetectObjects中一样,新的级联中不用。(没用到这个参数)取任意值都可。但不能直接删掉。会报错。

error: OpenCV(4.7.0) :-1: error: (-5:Bad argument) in function 'detectMultiScale'
> Overload resolution failed:
>  - Argument 'flags' is required to be an integer
>  - Argument 'flags' is required to be an integer

第五个参数 minSize是最小矩形框大小,
第六个参数 maxSize是最大矩形框大小。这六个参数需要自己去调,以求最佳匹配。
detectMultiScale方法会直接用该模型检测图片,并返回多个x,y,w,h。(x,y)是左顶点的坐标,w是矩形框的宽度,h是矩形框的高度。

7. for x, y, w, h in face:
    cv.rectangle(img, (x, y), (x + w, y + h), color=(0, 0, 225), thickness=4)
   cv.imshow("result", img)
   cv.imwrite(r"final_result.jpg", img)

for循环的功能就是在原来的图片上面绘制矩形框啦,对应的函数是cv.rectangle,这里面的参数很简单就不一一介绍了。
cv.imshow进行展示,cv.imwrite进行保存,注意imwrite保存图片时,命名要加上.jpg

函数到此结束,接下来是调用函数:

8. img = cv.imread("photo.jpg")
   face_detect_demo(img)  # 检测单个图片

首先读取图片,把程序和图片放在一个文件夹,可以直接用名字去读,如果你没有放在一个文件家里面,要用绝对路径去读取。
调用上面写好的函数去检验人脸。

9. while True:
       if ord("q") == cv.waitKey(1):
           break
   cv.destroyAllWindows()

最后做一个键盘的关联事件退出,,按下键盘q键会退出循环,程序结束。cv.destroyAllWindows销毁所有窗口。

3、效果分析

找了前几天微博之夜的图片,正面对镜头基本都能准确检测到人脸的位置。
![在这里插入图片描述](https://img-blog.csdnimg.cn/6cd9a107e8d34ca9a4d3702ff32036c3.png
但侧面对镜头未能准确检测到,那可是神仙姐姐啊!!! 有大神知道怎么调参数欢迎评论区指教!!!!
我这里用的是: face = face_detect.detectMultiScale(gary, 1.029, 3, 6, (90, 90), (120, 120))
在这里插入图片描述

参考博客及代码

detectMultiScale参数
基于opencv的人脸检测(图片、视频、摄像头)
基于opencv的人脸检测

opencv 官方开源代码链接:https://pan.baidu.com/s/1FV3NWT3Vayq3eKq2QsB3mg?pwd=tsvd 提取码:tsvd

最后,感谢各位前辈的分享,本文先写到这里,欢迎大家批评指正!

猜你喜欢

转载自blog.csdn.net/weixin_47296493/article/details/129899832