python opencv 人体/人脸识别 简易demo
Posted Love丶伊卡洛斯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python opencv 人体/人脸识别 简易demo相关的知识,希望对你有一定的参考价值。
前言
参考文章:
pythonopencv检测行人_【图像处理】使用OpenCV实现人脸和行人检测
Python如何实现行人识别-人体识别
本文主要讲述关于opencv官方提供的现成模型,采取Hog特征和SVM分类器的方式,实现对图片、视频进行人体/人脸的识别,并用不同颜色框出识别的矩形区域。
ps:测试图片源于网络,如有侵权,可私聊立删。
开发环境:pycharm-2020.1.5, python-3.8.5,opencv-python-4.5.4.58,opencv-4.2.0-vc14_vc15
cascade的xml数据路径:opencv\\sources\\data\\haarcascades
相关数据用途可参考:使用OpenCV,Haar级联检测器进行面部、眼睛、嘴部检测
效果图
视频素材来自:https://wedistill.io/categories/people
相关函数解释
参考文档:
https://docs.opencv.org/2.4/modules/core/doc/intro.html#api-concepts
https://docs.opencv.org/4.1.2/d7/dbd/group__imgproc.html
HOG::detectMultiScale
HOGDescriptor::setSVMDetector
CascadeClassifier::CascadeClassifier
CascadeClassifier::detectMultiScale
VideoCapture::isOpened
VideoCapture::read
源码
import cv2
import sys, os
# 判断框中框
def is_inside(o, i):
ox, oy, ow, oh = o
ix, iy, iw, ih = i
return ox > ix and oy > iy and ox + ow < ix + iw and oy + oh < iy + ih
# 框出人 传入图片 矩形参数 BGR
def draw_person(image, person, bgr):
x, y, w, h = person
cv2.rectangle(image, (x, y), (x + w, y + h), bgr, 2)
# 筛选识别出的人矩形数据
def screen_found(found):
for ri, r in enumerate(found):
for qi, q, in enumerate(found):
if ri != qi and is_inside(r, q):
break
else:
found_filtered.append(r)
# 等比缩放 参考:https://blog.csdn.net/JulyLi2019/article/details/120720752
def resize_keep_aspectratio(image_src, dst_size):
src_h, src_w = image_src.shape[:2]
# print(src_h, src_w)
dst_h, dst_w = dst_size
# 判断应该按哪个边做等比缩放
h = dst_w * (float(src_h) / src_w) # 按照w做等比缩放
w = dst_h * (float(src_w) / src_h) # 按照h做等比缩放
h = int(h)
w = int(w)
if h <= dst_h:
image_dst = cv2.resize(image_src, (dst_w, int(h)))
else:
image_dst = cv2.resize(image_src, (int(w), dst_h))
h_, w_ = image_dst.shape[:2]
# print(h_, w_)
print('等比缩放完毕')
return image_dst
# cascade图片人体识别和绘制边框 参数 需要识别的图片 输出绘制的图片 xml路径 bgr颜色 目标的最小尺寸 目标的最大尺寸
def cascade_img_person_detect_draw(src_img, dst_img, xml_path, bgr, min_size, max_size):
detector = cv2.CascadeClassifier(xml_path)
# image表示的是要检测的输入图像
# objects表示检测到的人脸目标序列
# scaleFactor表示每次图像尺寸减小的比例
# minNeighbors表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大小都可以检测到人脸)
# flag 对于旧级联具有与函数cvHaarDetectObjects相同的含义。它不用于新的级联。
# minSize为目标的最小尺寸
# maxSize为目标的最大尺寸
# found = detector.detectMultiScale(src_img)
found = detector.detectMultiScale(src_img, 1.1, 3, cv2.CASCADE_SCALE_IMAGE, (0, 0), (500, 500))
# 筛选识别出的人矩形数据
screen_found(found)
for person in found_filtered:
draw_person(dst_img, person, bgr)
found_filtered.clear()
print(xml_path + " 识别出:" + str(len(found)) + "个结果。")
# 参考文章:https://blog.csdn.net/www_16302_com/article/details/103817612
# cascade视频人体识别和绘制边框 参数 需要识别的视频路径 xml路径 bgr颜色 目标的最小尺寸 目标的最大尺寸
# 按 Q 键退出函数
def cascade_video_person_detect_draw(video_path, xml_path, bgr, min_size, max_size):
cap = cv2.VideoCapture(video_path)
# 告诉OpenCV使用什么识别分类器
classfier = cv2.CascadeClassifier(xml_path)
while cap.isOpened():
# 读取一帧数据
ret, frame = cap.read()
# 抓取不到视频帧,则退出循环
if not ret:
break
# 显示方向
frame = cv2.flip(frame, 1)
# 将当前帧转换成灰度图像
grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 检测结果
# 第一个参数是灰度图像
# 第而个参数scaleFactor表示每次图像尺寸减小的比例
# 第三个参数是人脸检测次数,设置越高,误检率越低,但是对于迷糊图片,我们设置越高,越不易检测出来
# minSize为目标的最小尺寸
# maxSize为目标的最大尺寸
found = classfier.detectMultiScale(grey, scaleFactor=1.1, minNeighbors=4, minSize=min_size, maxSize=max_size)
# 框出识别结果
if len(found) > 0:
for foundRect in found:
x, y, w, h = foundRect
cv2.rectangle(frame, (x - 10, y - 10), (x + w + 10, y + h + 10), bgr, 1)
# 显示图像
cv2.imshow('person detection', frame)
# 键盘Q键结束
c = cv2.waitKey(10)
if c & 0xFF == ord('q'):
break
# 释放摄像头并销毁所有窗口
cap.release()
cv2.destroyAllWindows()
print("视频识别结束。")
# 读取图片,修改为自己的路径即可
img = cv2.imread("img/people_detection/4.jpg")
# 等比缩放至500*500
img = resize_keep_aspectratio(img, [500, 500])
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 存储所有识别出的坐标集
found_filtered = []
hog = cv2.HOGDescriptor()
# 加载SVM模型 行人识别
hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
# 对图像进行多尺度目标检测 返回检测到区域的坐标
found, w = hog.detectMultiScale(gray)
# print(found)
# 筛选识别出的人矩形数据
screen_found(found)
# 在原图上绘出识别出的所有矩形 蓝色
for person in found_filtered:
draw_person(img, person, (255, 0, 0))
# 清空列表
found_filtered.clear()
print("HOGDescriptor_getDefaultPeopleDetector 识别出:" + str(len(found)) + "个结果。")
# 正脸识别 绿色
cascade_img_person_detect_draw(gray, img, "data/haarcascade_frontalface_default.xml", (0, 255, 0), (0, 0), (500, 500))
# 侧脸识别 红色
cascade_img_person_detect_draw(gray, img, "data/haarcascade_profileface.xml", (0, 0, 255), (0, 0), (500, 500))
# 全身识别 青色
cascade_img_person_detect_draw(gray, img, "data/haarcascade_fullbody.xml", (255, 255, 0), (0, 0), (500, 500))
# 上半身识别 洋红
cascade_img_person_detect_draw(gray, img, "data/haarcascade_upperbody.xml", (255, 0, 255), (0, 0), (500, 500))
# 下半身识别 黄色
cascade_img_person_detect_draw(gray, img, "data/haarcascade_lowerbody.xml", (0, 255, 255), (0, 0), (500, 500))
cv2.imshow("people detection", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 视频素材来自:https://wedistill.io/categories/people
# 参数 需要识别的视频路径 xml路径 bgr颜色 目标的最小尺寸 目标的最大尺寸
cascade_video_person_detect_draw("video/1.mp4", "data/haarcascade_upperbody.xml", (0, 255, 0), (50, 50), (1000, 3000))
以上是关于python opencv 人体/人脸识别 简易demo的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV人脸识别--detectMultiScale函数