OpenCV-Python人脸识别,车辆识别,自定义物体识别,自定义分类器

本文将使用opencv-python识别自定义物体,能够区分识别到的物体,如果用作人脸识别,则能够区分出不同的人脸id,也就是能够分得清张三,李四,王二麻子

(这方案已经很老了,去学 Tensorflow2或者Pytorch 吧)

本文提供的所有资源仅供学习使用,不可商用

文末有完整工程链接

效果:

识别出局座,大紧,大众和沃尔沃

vs2017+python+opencv配置请参考vs2017+python+opencv配置_qq_43440703的博客-CSDN博客

本文中文乱码问题参考博客CV2 puttext不能显示中文问题_天上飞下一毛雪的博客-CSDN博客_cv2.puttext 显示中文

为什么能让程序识别出我们想要让它识别的物体,程序怎么能认得哪个是我们想要识别的物体

此时我们需要事先训练程序,我们需要事先告诉它,哪个人是局座,哪个人是大紧,哪个车是沃尔沃,哪个车是大众

如何训练程序去认识这些人和物,我们在本文最后去讲

本教程中出现的所有的训练数据文件都包含在文末的工程文件中,下载后可直接运行

注意:

本教程只使用了少量的样本训练,精度一般,主要是了解思想

本教程中对应物体的训练数据仅对本视频文件有较好的识别概率,其他场景效果不行


如果需要在任何场景中都能识别局座或者其他人和物,需要重新使用大量到的样本数据去训练,需要成千上万个样本,本程序只是一个示例教程

掌握了思想,就可以自己去准备样本去训练

程序实现:

新建一个Python应用程序

安装opencv-python

from PIL import Image, ImageDraw, ImageFont
import cv2
import numpy as np
import time


 #由于直接用opencv显示中文会乱码,所以先将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式 
def change_cv2_draw(image,strs,local,sizes,colour):   
    cv2img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    pilimg = Image.fromarray(cv2img)
    draw = ImageDraw.Draw(pilimg) 
    font = ImageFont.truetype("SIMYOU.TTF",sizes, encoding="utf-8")  #SIMYOU.TTF为字体文件
    draw.text(local, strs, colour, font=font)
    image = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
    return image



#src为输入的图像
#classifier为对应识别物体的分类器
#strs为识别出的物体的中文说明
#colors表示框的颜色
#minSize为识别物体的最小尺寸,当识别的物体尺寸低于这个尺寸,则不检测,就当没识别到
#minSize为识别物体的最大尺寸,当大于该尺寸时不识别
def myClassifier(src,classifier,strs,colors,minSize,maxSize):
    gray=cv2.cvtColor(src,cv2.COLOR_BGR2GRAY)
    #detectMultiScale()方法里面的参数在另一篇博客中有详解:https://blog.csdn.net/GottaYiWanLiu/article/details/90442274
    obj = classifier.detectMultiScale(gray,scaleFactor = 1.15, minNeighbors = 5,minSize=minSize,maxSize=maxSize) 
    for (x,y,w,h) in obj:
        cv2.rectangle(src,(x,y),(x+w,y+w),colors,2) #画框,(x,y)为识别物体的左上角顶点,(w,h)为宽和高
        src=change_cv2_draw(src,strs,(x,y-20),20,colors)#显示中文
    return src


#读取视频文件 若 cap=cv2.VideoCapture(0),则为获取摄像头画面
cap=cv2.VideoCapture("001.mp4")

#读取对应物体的训练数据,  注意,以下这些训练数据仅对本视频文件有较好的识别概率,其他场景不行
#其他场景中,需要重新使用大量到的样本数据去训练,本程序只是一个示例教程

juzuo=cv2.CascadeClassifier("juzuo.xml")   #局座人脸的训练数据
dajin=cv2.CascadeClassifier("dajin.xml")   #大紧人类的训练数据
volvo=cv2.CascadeClassifier("volvo.xml")   #沃尔沃汽车的训练数据
volkswagen=cv2.CascadeClassifier("volkswagen.xml") #大众汽车的训练数据

while True:
    _,frame=cap.read()
    frame=myClassifier(frame,juzuo,"局座",(0,0,255),(40,40),(60,60))
    frame=myClassifier(frame,dajin,"大紧",(0,255,0),(40,40),(70,70))
    frame=myClassifier(frame,volvo,"沃尔沃",(255,0,0),(35,35),(70,70))
    frame=myClassifier(frame,volkswagen,"大众",(0,255,255),(40,40),(70,70))

    cv2.imshow("frame",frame)
    cv2.waitKey(30)

如果想按Esc键退出程序

将最后一行改为:

c=cv2.waitKey(30)

if c==27:

   cv2.destroyAllWindows()

   break

所有参数说明看注释

如何训练我们想要识别的物体?

参考博客:

opencv3.3版本训练自己的物体分类器_刘延林 | 梦陆的博客-CSDN博客

首先我们需要安装3.0以上4.0以下的opencv

本人使用的opencv3.4.0

官网下载:Releases - OpenCV

安装完以后

在路径opencv\build\x64\vc14\bin\下有我们需要的训练程序

opencv_createsamples.exe和opencv_traincascade.exe

以本文为例:

首先新建一个文件夹取名 JuZuo

然后将opencv\build\x64\vc14\bin\下的所有文件复制到该文件夹下

然后在此文件夹下再新建一个pos文件夹,一个neg文件夹,一个xml文件夹

如下图所示:

其中neg文件夹保存我们的负样本

pos文件夹保存我们的正样本,

正负样本都是图片文件

正样本就是我们需要识别的物体的图片,而负样本中不能出现正样本

负样本下载(本人花积分从csdn上下载的):

我推荐自己去网上搜,尊重别人劳动成果,我本来想把我下载的博主的链接粘贴过来,结果找了半天没找到

先用这个吧

链接:https://pan.baidu.com/s/1ahJA6BsY4oVL20oY3GSQjg 
提取码:2o95 

负样本的尺寸没有具体要求,只要比正样本大就行

而正样本,尺寸需要统一,为了保准训练的速度,本文正样本图片尺寸统一20x20

需要使用ps或者其他软件裁剪一下

局座正样本下载(本人一点一点的裁的):

链接:https://pan.baidu.com/s/1Erwm59tzfdDHL3HTnu4QpA 
提取码:gi7p 
 

然后将负样本所有图片放到neg文件夹下

将局座的所有正样本图片放到pos文件夹下

然后win+r   输入cmd,打开cmd

比如本人的JuZuo文件夹在D盘

则输入 d:   然后回车

然后来到我们的负样本文件夹

输入:cd D:\JuZuo\neg  回车

此时我们已经进入neg文件夹

输入:dir /b/s/p/w *.jpg > neg.txt  回车

此时会在neg文件末尾生成一个neg.txt文件

然后我们进入pos文件夹

输入 cd D:\JuZuo\pos  回车

此时我们输入:dir /b/s/p/w *.jpg > pos.txt  回车

此时会在pos文件末尾生成一个pos.txt文件

如下图:

此时我们将neg.txt和pos.txt文件都移动到D:\JuZuo\路径下

即移动到上一层目录

此时我们需要修改一下pos.txt

此时我们借助Notepad++程序,百度Notepad++下载

右键pos.txt,使用Notepad++打开

然后 按 Ctrl+H

将所有的jpg替换成jpg 1 0 0 20 20

替换完后:

一定要记得保存

修改完后,

在回到D:\JuZuo\文件夹下

在cmd 命令提示符里输入: cd D:\JuZuo 回车

然后输入:opencv_createsamples.exe -vec pos.vec -info pos.txt -num 200 -w 20 -h 20 回车

其中-num 后面的200,是正样本的数量,比如有300个正样本,不一定要用满,比如我用200个,后面两个20 就是正样本的尺寸

如下图:

此时会在JiuZuo文件夹下创建一个pos.vec文件

此时我们新建一个文本文档

命名任意,但是需要将后缀名改为bat,比如start.bat

如下图:

此时右键start.bat,编辑

opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 200 -numNeg 400 -numStages 15 -w 20 -h 20 -maxFalseAlarmRate 0.4 -precalcValBufSize 2048 -precalcIdxBufSize 2048 -mode ALL

pause

将这一段话复制进去保存

numPos为正样本数量,numNeg为负样本数量,numStages为分类器的级数,w和h为正样本的宽和高,maxFalseAlarmRate为最大误报率,precalcValBufSize为缓存大小,用于存储预先计算的特征值单位为MB,precalcIdxBufSize为缓存大小,用于存储预先计算的特征索引(feature indices),单位为MB。内存越大,训练时间越短。

具体参数说明请参考官方文档:

https://www.baidu.com/link?url=qZmbQOIgAdjLrWTy0-JAZW5UvMbHYuPDA0sDtGEPvJTLh2hPc56dccEq_9q6yYtSvBBciUE9cQrUYN8iTlec7a3lAPAlaBQd3X60WHvPm7qJcMPTNcwSuVcfQHdrJRoF&wd=&eqid=8cd1a75100010c7b000000055ce60780

然后双击start.bat启动

然后会在xml中生成cascade.xml文件,此文件就是训练后的文件

我们只需在代码中读取此文件即可

工程链接:

链接:https://pan.baidu.com/s/1cK19bZkNFwnQDBxAo9UDfg 
提取码:fosm 

要使用OpenCV-Python进行人脸识别,需要先安装OpenCV-Python和其他必要的库。然后,你需要使用Haar Cascades分类器进行人脸检测,然后使用LBPH(Local Binary Patterns Histograms)算法或Eigenfaces算法进行人脸识别。 以下是一个基本的OpenCV-Python人脸识别代码示例: ```python import cv2 # 加载分类器 face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 加载训练数据 recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read("trainer.yml") # 打开摄像头 cap = cv2.VideoCapture(0) while True: # 读取帧 ret, img = cap.read() # 转换为灰度图像 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 检测人脸 faces = face_cascade.detectMultiScale(gray, 1.3, 5) # 对于每个检测到的人脸 for (x, y, w, h) in faces: # 绘制矩形框 cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) # 识别人脸 id_, confidence = recognizer.predict(gray[y:y+h, x:x+w]) if confidence > 50: # 如果置信度大于50,显示识别结果 cv2.putText(img, str(id_), (x+5, y-5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) else: # 如果置信度小于50,显示未知 cv2.putText(img, "Unknown", (x+5, y-5), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) # 显示帧 cv2.imshow('camera', img) # 按q退出 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放摄像头 cap.release() # 关闭所有窗口 cv2.destroyAllWindows() ``` 在运行代码之前,请确保已经下载了Haar Cascades分类器,并将其保存在与代码相同的目录中。你还需要训练你的识别器并将其保存为“trainer.yml”文件。
评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值