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

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

 

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

 

文末有完整工程链接

 

效果:

 

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

 

vs2017+python+opencv配置请参考https://blog.csdn.net/qq_43440703/article/details/88375609

本文中文乱码问题参考博客https://blog.csdn.net/qq_39622065/article/details/84859629

 

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

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

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

 

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

 

注意:

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

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


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

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

 

 

程序实现:

新建一个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

 

所有参数说明看注释

 

 

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

 

参考博客:

https://blog.csdn.net/qq_32502511/article/details/79010509

 

 

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

本人使用的opencv3.4.0

官网下载:https://opencv.org/releases/page/2/

安装完以后

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

opencv_createsamples.exe和opencv_traincascade.exe

 

以本文为例:

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

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

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

如下图所示:

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第1张图片

 

 

其中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文件

如下图:

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第2张图片

 

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

即移动到上一层目录

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

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

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

然后 按 Ctrl+H

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

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第3张图片

替换完后:

一定要记得保存

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第4张图片

 

 

修改完后,

在回到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 就是正样本的尺寸

如下图:

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第5张图片

 

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

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

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

如下图:

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第6张图片

 

此时右键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启动

OpenCv-Python人脸识别,车辆识别,自定义物体识别,自定义分类器_第7张图片

 

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

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

 

 

工程链接:

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

 

 

你可能感兴趣的:(人脸识别,opencv,python,自定义分类器,人脸识别,人工智能,opencv)