当前位置:   article > 正文

(终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测

opencv案例

目录

一、准备阶段

 二、图片处理

​三、生成描述文件

 四、生成.vec文件

  五、生成.xml自定义分类器文件

 六、识别检测


一、准备阶段

正样本集:正样本集为包含“识别物体”的灰度图,一般大于等于2000张,尺寸不能太大,尺寸太大会导致训练时间过长。

负样本集:负样本集为不含“识别物体”的任何图片,一般大于等于5000张,尺寸比正样本集稍大。一般为正样品集的3倍。

在当前文件夹下新建五个文件夹,pos和neg放处理后的图片,ini_pos和ini_neg放原来的图像,xml放以后自定义生成的分类器

将下载的正负样本集分别放入ini_pos和ini_neg文件夹。

我百度图片上下载了船的图片到ini_pos,鱼的图片到ini_neg

注意:好的正训练集最好还是图片中只有你需要的物体,而没有其他物体和背景干扰,百度图片里面有动图gif格式图片,不能通过opencv读取,下载完后看好图片后缀。

下面是初始的俩个样品集

 二、图片处理

样品集需要统一大小和统一改为灰度图

代码:

  1. import cv2 as cv
  2. import matplotlib.pyplot as plt
  3. import os
  4. #解决中文显示问题,固定格式,直接复制下面俩行代码就行
  5. plt.rcParams['font.sans-serif']=['SimHei']
  6. plt.rcParams['axes.unicode_minus']=False
  7. pospath = "./ini_pos"#正样本集文件夹路径
  8. pos = os.listdir(pospath)#读取路径下的所有文件
  9. negpath = "./ini_neg"
  10. neg = os.listdir(negpath)
  11. #图片处理,注意图片不能有gif格式
  12. def picdif():
  13. global pos,neg;
  14. i=1;
  15. for picname in pos:#遍历pos文件数组所有的文件名
  16. #读取灰度图
  17. pic=cv.imread(pospath+"\\"+picname)
  18. pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
  19. #修改尺寸
  20. pic=cv.resize(pic,(40,40))
  21. #保存图片
  22. cv.imwrite("./pos/"+str("%03d"%i)+".jpg",pic)
  23. i+=1
  24. #同理对负样本集进行处理
  25. j = 1;
  26. for picname in neg: # 遍历neg文件数组所有的文件名
  27. #读取灰度图
  28. pic=cv.imread(negpath+"\\"+picname)
  29. pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
  30. #修改尺寸
  31. pic=cv.resize(pic,(50,50))
  32. #重命名,并保存图片
  33. cv.imwrite("./neg/"+str("%03d"%j)+".jpg",pic)
  34. j+=1
  35. if __name__ == '__main__':
  36. # 1.导入文件夹,对图像统一处理,统一尺寸大小,统一灰度图
  37. picdif()

处理后的正负样本集和图片:

三、生成描述文件

正样本描述文件如下:

其中"1"为图片数量(0,0)坐标,(40,40)是正样本集的长宽

负样本描述文件如下:

代码更新:

a_main.py

  1. import cv2 as cv
  2. import os
  3. #解决中文显示问题,固定格式,直接复制下面俩行代码就行
  4. plt.rcParams['font.sans-serif']=['SimHei']
  5. plt.rcParams['axes.unicode_minus']=False
  6. pospath = "./ini_pos"#正样本集文件夹路径
  7. pos = os.listdir(pospath)#读取路径下的所有文件
  8. negpath = "./ini_neg"
  9. neg = os.listdir(negpath)
  10. #图片处理,注意图片不能有gif格式
  11. def picdif():
  12. global pos,neg;
  13. i=1;
  14. for picname in pos:#遍历pos文件数组所有的文件名
  15. #读取灰度图
  16. pic=cv.imread(pospath+"\\"+picname)
  17. pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
  18. #修改尺寸
  19. pic=cv.resize(pic,(40,40))
  20. #保存图片
  21. cv.imwrite("./pos/"+str("%03d"%i)+".jpg",pic)
  22. i+=1
  23. #同理对负样本集进行处理
  24. j = 1;
  25. for picname in neg: # 遍历neg文件数组所有的文件名
  26. #读取灰度图
  27. pic=cv.imread(negpath+"\\"+picname)
  28. pic=cv.cvtColor(pic,cv.COLOR_BGR2GRAY)
  29. #修改尺寸
  30. pic=cv.resize(pic,(50,50))
  31. #重命名,并保存图片
  32. cv.imwrite("./neg/"+str("%03d"%j)+".jpg",pic)
  33. j+=1
  34. # 描述文件生成
  35. def createtxt():
  36. global pos, neg
  37. #正样本描述文件:
  38. for picname in pos:
  39. line ="pos/"+picname+" 1 0 0 40 40"+"\n"#"1"为图片数量(0,0)是坐标,(40,40)是正样本集的w,h
  40. with open('pos.txt', 'a') as f:
  41. f.write(line)
  42. #负样本描述文件:
  43. for picname in neg:
  44. line ="neg/"+picname+"\n"#(0,0)是坐标,(40,40)是正样本集的w,h
  45. with open('neg.txt', 'a') as f:
  46. f.write(line)
  47. if __name__ == '__main__':
  48. # 1.导入文件夹,对图像统一处理,统一尺寸大小,统一灰度图
  49. picdif()
  50. #pos和neg改成处理后的图片文件夹;
  51. pospath = "./pos"#正样本集文件夹路径
  52. pos = os.listdir(pospath)#读取路径下的所有文件
  53. negpath = "./neg"
  54. neg = os.listdir(negpath)
  55. #2.正负样本描述文件的生成
  56. createtxt()

 四、生成.vec文件

获取opencv_createsamples.exe和opencv_traincascade.exe

这两个软件在opencv安装包里是没有的,只有下载opencv以及opencv_contrib源码自己编译才会生成这两个可执行程序

我是直接下载别人的程序,下面是网址

opencv341_bin: 编译opencv以及opencv_contrib以后的bin文件夹,里面包含一些可执行程序https://gitee.com/lizaozao/opencv341_bin注意下载依赖项解压到opencv_createsamples.exe和opencv_traincascade.exe同一目录下

在该主目录文件下打开终端窗口,win11可直接通过右键“在终端打开”

输入

 .\opencv_createsamples.exe -info pos.txt -vec detect_number.vec -bg neg.txt -num 19 -w 40 -h 40

-info 正样本txt

-vec 是你生成vec文件的位置和名称

-bg 负样本txt

-num 正样本数量

-w 正样本宽度

-h 正样本高度

  五、生成.xml自定义分类器文件

当前主目录文件夹终端下输入

./opencv_traincascade.exe -data xml -vec detect_number.vec -bg neg.txt -numPos 19 -numNeg 25 -numStages 20 -featureType HAAR -w 40 -h 40

-data 前面创建好的xml文件夹
-vec 是你之前生成vec文件
-bg 负样本集txt
-numPos 正样本的数量
-numNeg 负样本的数量
-numStages 训练步数
-featureType 特征类型 

训练时,提取图像特征的类型,目前只支持LBP、HOG、Haar三种特征。但是HAAR训练非常非常的慢,而LBP则相对快很多,因为HAAR需要浮点运算,精度自然比LBP更高
-w -h 正样本的宽高

结果:

由于样本较少,训练十秒就完成了

 六、识别检测

上一节课已经说了,直接上代码

[图像识别]12.Opencv案例 超简单人脸检测识别_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客1.原理:我们使用机器学习的方法完成人脸检测,首先需要大量的正样本图像(面部图像)和负样本图像(不含面部的图像)来训练分类器。我们需要从其中提取特征。Haar特征(这个值等于黑色矩形中的像素值之后减去白色矩形中的像素值和。)会被使用,就像我们的卷积核,每一个特征是一个值。Haar特征值反映了图像的灰度变化情况。Haar特征可用于于图像任意位置,大小也可以任意改变,所以矩形特征值是矩形模版类别、矩形位置和矩形大小这三个因素的函数。故类别、大小和位置的变化,使得很小的检测窗口含有非常多的矩形特征。https://blog.csdn.net/qq_54263076/article/details/127155374?spm=1001.2014.3001.5501

main.py文件

  1. import cv2 as cv
  2. import matplotlib.pyplot as plt
  3. #解决中文显示问题,固定格式,直接复制下面俩行代码就行
  4. plt.rcParams['font.sans-serif']=['SimHei']
  5. plt.rcParams['axes.unicode_minus']=False
  6. # 加载分类器
  7. cascade = cv.CascadeClassifier("./xml/cascade.xml")
  8. cascade.load("./xml/cascade.xml")
  9. # 读取灰度图片
  10. pic1 = cv.imread("boat.jpg")
  11. pic2= cv.imread("./ini_neg/0b46f21fbe096b639ef96b67fc926942eaf8ac49.jpeg")
  12. pic1=cv.resize(pic1,(100,100))
  13. pic2=cv.resize(pic2,(400,400))
  14. pic2[200:300,100:200]=pic1
  15. gray = cv.cvtColor(pic2,cv.COLOR_BGR2GRAY)
  16. # 探测图片中的船只
  17. faces = cascade.detectMultiScale(
  18. gray,
  19. scaleFactor = 1.1,
  20. minNeighbors = 150,
  21. minSize = (50,50),
  22. )
  23. #绘制矩形
  24. pic3=pic2.copy()
  25. for (x,y,w,h) in faces:
  26. cv.rectangle(pic3,(x,y),(x+h,y+w),(0,0,255),5)
  27. #绘图
  28. fig,axes=plt.subplots(nrows=1,ncols=2)
  29. axes[0].imshow(pic2[:,:,::-1])
  30. axes[0].set_title("原图")
  31. axes[1].imshow(pic3[:,:,::-1])
  32. axes[1].set_title("识别")
  33. plt.show()
  34. cv.waitKey()

由于所选样本太太太太少,且有些正样本不纯不好,导致结果偏差比较大

根据以上教程,可以不断像文件夹添加样本图片达到上千,生成.vec和.xml文件,完成自己的物品识别,完整代码放在下面,可以自己下载修改

https://download.csdn.net/download/qq_54263076/86736208https://download.csdn.net/download/qq_54263076/86736208

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/765114
推荐阅读
相关标签
  

闽ICP备14008679号