课程来源:一天搞定人脸识别项目!学不会up直接下跪!(python+opencv)_哔哩哔哩_bilibili
图片来源:感谢王鹤棣先生友情出镜~
环境配置详见:
在conda虚拟环境中安装OpenCv并在pycharm中使用_conda虚拟环境安装opencv_好喜欢吃红柚子的博客-CSDN博客
一、读取图片
1.1 代码实现
#导入cv模块
import cv2 as cv
#读取图片
img = cv.imread('1.png')
#显示图片
cv.imshow('showFace',img)
#等待delay
cv.waitKey(0)
#释放内存
cv.destroyAllWindows()
1.2 效果展示
二、图片灰度化
2.1 图片灰度化作用
图像处理时为什么灰度化_图像灰度化处理的目的_whaosoft143的博客-CSDN博客
为什么做图片识别要将彩色图像灰度化呢?
图像灰度化的目的是为了简化矩阵,提高运算速度。
彩色图像中的每个像素颜色由R、G、B三个分量来决定,而每个分量的取值范围都在0-255之间,这样对计算机来说,彩色图像的一个像素点就会有256*256*256=16777216种颜色的变化范围!
而灰度图像是R、G、B分量相同的一种特殊彩色图像,对计算机来说,一个像素点的变化范围只有0-255这256种。
彩色图片的信息含量过大,而进行图片识别时,其实只需要使用灰度图像里的信息就足够了,所以图像灰度化的目的就是为了提高运算速度。
当然,有时图片进行了灰度处理后还是很大,也有可能会采用二值化图像(即像素值只能为0或1)。
2.2 所需方法
2.2.1 设置灰度方法
cvtColor()
2.2.2 保存图片方法
imwrite()
2.3 代码实现
#导入模块
import cv2 as cv
#读取图片
img = cv.imread("face1.png")
#灰度转换
gray_img = cv.cvtColor(img,cv.COLOR_BGRA2GRAY)
#显示灰度
cv.imshow("greyImg",gray_img)
#保存灰度图片
cv.imwrite('gray_face1.png',gray_img)
#等待
cv.waitKey(0)
#释放内存
cv.destroyAllWindows()
2.4 效果展示
2.4.1 显示灰度图片
2.4.2 保存灰度图片
在关闭显示的灰度图片后,会将该图片进行保存
三、尺寸转换
3.1 尺寸转换方法
resize()
3.2 代码展示
import cv2 as cv
#读取图片
img = cv.imread("face1.png")
#修改尺寸
img_resized = cv.resize(img,(200,200))
#显示原图
cv.imshow("face01",img)
#显示修改尺寸后的图
cv.imshow("face01_resized",img_resized)
#打印原图和修改图的尺寸
print("原图大小:",img.shape,"\n修改后大小:",img_resized.shape)
#保存修改大小后的图片
cv.imwrite("resize_face1.png",img_resized)
#等待
cv.waitKey(0)
#释放内存
cv.destroyAllWindows()
3.3 效果展示
3.3.1 显示修改后的图片
3.3.2 保存图片
3.3.3 输出图片的大小
3为彩色图片的通道数。
3.4 按下英文输入法中的m键后退出程序
import cv2 as cv
#读取图片
img = cv.imread("face1.png")
#修改尺寸
img_resized = cv.resize(img,(200,200))
#显示原图
cv.imshow("face01",img)
#显示修改尺寸后的图
cv.imshow("face01_resized",img_resized)
#打印原图和修改图的尺寸
print("原图大小:",img.shape,"\n修改后大小:",img_resized.shape)
#按下m键时退出程序
while True:
if ord('m') == cv.waitKey(0):
break
#释放内存
cv.destroyAllWindows()
四、绘制矩形和圆形框
4.1 绘制矩形
cv2.rectangle(img, pt1, pt2, color, thickness=None, lineType=None, shift=None)
参数介绍:
python版opencv函数学习笔记-cv.rectangle()全参数理解_风一样的夏天001的博客-CSDN博客
作用:根据给定的左上顶点和右下顶点画矩形
参数说明:
- img:指定一张图片,在这张图片的基础上进行绘制;
- pt1: 矩形的一个顶点;
- pt2: 与pt1在对角线上相对的矩形的顶点;
- color:指定边框的颜色,由(B,G,R)组成,当为(255,0,0)时为绿色,可以自由设定;
- thinkness:线条的粗细值,为正值时代表线条的粗细(以像素为单位),为负值时边框实心;
4.2 绘制圆形
cv2.circle(img, center, radius, color, thickness=None, lineType=None, shift=None):
作用:根据给定的圆心和半径等画圆
参数说明:
- img:输入的图片data
- center:圆心位置
- radius:圆的半径
- color:圆的颜色
- thickness:圆形轮廓的粗细(如果为正)。负厚度表示要绘制实心圆。
4.3 代码实现
import cv2 as cv
x,y,w,h = 100,100,100,100
#读取图片
img = cv.imread("face1.png")
#绘制矩形
cv.rectangle(img,pt1=(x,y),pt2=(x+w,y+h),color=(0,0,255),thickness=1)
#绘制圆形
cv.circle(img,center=(x,y),radius=100,color=(255,0,0),thickness=2)
#显示图片
cv.imshow("draw_face1",img)
while True:
if ord('m')==cv.waitKey(0):
break
cv.destroyAllWindows()
4.4 效果展示
五、人脸检测
5.1 OpenCV自带的分类器
在下图的路径中,我们可以看到需要xml文件,这些都是OpenCV中自带的分类器,根据文件名我们可以看到有识别眼睛的,身体的,脸的,等等。
使用cv.CascadeClassifier(参数:分类器所在路径)方法定义一个分类器对象。
我的分类器所在位置:
- OpenCV分类器路径:G:\conda\envs\testOpencv\Lib\site-packages\cv2\data
- 本次使用的分类器文件名:haarcascade_frontalface_alt2.xml
- 在代码中输入的完整路径(需要把右下划线改为左下划线): G:/conda/envs/testOpencv/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml
5.2 detectMultiScale方法
opencv人脸检测--detectMultiScale函数_walker lee的博客-CSDN博客_detectmultiscale
detectMultiScale
(self,
image: Any,
scaleFactor: Any = None,
minNeighbors: Any = None,
flags: Any = None,
minSize: Any = None,
maxSize: Any = None)
作用:
它可以检测出图片中所有的人脸,并将人脸用vector保存各个人脸的坐标、大小,用矩形Rect类表示,函数由分类器对象调用。
参数介绍:
- image: 待检测图片,一般为灰度图像加快检测速度;
- scaleFactor:表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口依次扩大10%; scale_factor参数可以决定两个不同大小的窗口扫描之间有多大的跳跃,这个参数设置的大,则意味着计算会变快,但如果窗口错过了某个大小的人脸,则可能丢失物体
- minNeighbors:默认值为3,表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸),
- flags:一般使用默认值0;
- minSize和maxSize用来限制得到的目标区域的最大/最小尺寸。
5.3 代码
import cv2 as cv
def face_detect_methed():
# 图片灰度化
grey_img = cv.cvtColor(img,cv.COLOR_BGRA2GRAY)
# 定义分类器,使用OpenCV自带的分类器
face_detector = cv.CascadeClassifier('G:/conda/envs/testOpencv/Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml')
# 使用分类器
face = face_detector.detectMultiScale(grey_img)
# 在图片中对人脸画矩阵
for x,y,w,h in face:
cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
cv.imshow('result',img)
#读取图像
img = cv.imread("face1.png")
#调用检测函数
face_detect_methed()
while True:
if ord('m') == cv.waitKey(0):
break
cv.destroyAllWindows()
5.4 效果展示
此时为没有设定参数,可以看到图片识别人脸出现了失误,把背景中的海浪也识别为了人脸。
在调整了参数后可以看到,人脸识别正确,识别出了一个人脸
六、检测多个人脸
此次可以识别多个人脸,与识别一个人脸的代码基本相同,这次换了一个分类器,即OpenCV自带的默认人脸识别分类器,调整了一下detectMultiScale的参数,识别结果较为准确,但是有一个人脸未识别出来。
6.1 代码实现
import cv2 as cv
def face_detect_methed():
# 图片灰度化
grey_img = cv.cvtColor(img,cv.COLOR_BGRA2GRAY)
# 定义分类器,使用OpenCV自带的分类器
face_detector = cv.CascadeClassifier('G:/conda/envs/testOpencv/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
# 使用分类器
face = face_detector.detectMultiScale(grey_img,1.1,5,0,(10,10),(200,200))
# 在图片中对人脸画矩阵
for x,y,w,h in face:
cv.rectangle(img,(x,y),(x+w,y+h),color=(0,0,255),thickness=2)
cv.imshow('result',img)
#读取图像
img = cv.imread("faceMorePeople.png")
#调用检测函数
face_detect_methed()
while True:
if ord('m') == cv.waitKey(0):
break
cv.destroyAllWindows()
6.2 效果展示
可以看到识别的不算准确,c位的人脸没有被识别出来,我挑了很多次参数也换了分类器还是不行,就这样吧那~