大佬教程收集整理的这篇文章主要介绍了OpenCV训练自己的物体检测分类器步骤,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
环境:python3.7 OpenCV3.4.3.18
@H_675_1@工具:
opencv_Annotation.exe
opencv_createsamples.exe
opencv_Traincascade.exe
@H_675_1@环境和工具下载安装
OpenCV库在cmd下终端命令 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-contrib-python==3.4.3.18 包括了OpenCV主要模块以及OpenCV贡献库 工具在GitHub上下载 https://github.com/opencv/opencv/releases?after=3.4.3
安装openCV后在以下目录
@H_801_28@
一、准备阶段
文件模板
@H_801_28@
positive_images放置正样本图片、negative_image放置负样本图片、xml为训练好的分类器文件
样本收集
正样本:我们想要正确分类出的类别所对应的样本c;例如c;我们要对一张图片进行分类c;以确定其是否属于菠萝c;那么在训练的时候c;菠萝的图片则为正样本。
负样本:不是我们想要的分类对应的样本c;就是除了菠萝的图片
样本数据越多检测效果越好c;正样本的特征越明显越好c;负样本背景越复杂越好。
1、去www.kaggle.com下载想要的数据集或者使用scrapy+SELEnium批量爬取图片
2、自己拍摄想要检测物体的图片
二、预处理
图像的注水处理:通过自动对图像的旋转、平移、缩放从而增加样本数量
比如:通过旋转
@H_607_85@"path是图片路径c;执行后c;会在同一目录下生成11张依次旋转30度的图片"
def spin(path):
retval=cv2.imread(path)
he,we=retval.shape[:2]
for x in range(1,12):
M=cv2.getRotationMatrix2D(center=(we/2,he/2),angle=x*30,scale=1)
M=cv2.warpAffine(retval,M,(we,hE))
new_path=path[:-3]+'-spin'+str(X)+'.jpg'
#print(new_path)
cv2.imwrite(new_path,M)
调节亮度:
@H_607_85@"path是图片路径c;执行后会在同一目录下生成五张亮度依次递增的图片"
def light(path):
retval=cv2.imread(path)
img_hsv = cv2.cvtColor(retval, cv2.COLOR_BGR2HSV)
darker_hsv = img_hsv.copy()
for y in range(1,6):
darker_hsv[:, :, 2] = darker_hsv2[:, :, 2]+2*y
darker_img = cv2.cvtColor(darker_hsv, cv2.COLOR_HSV2BGR)
new_path=path[:-3]+'-light+'+str(X)+'ipg'
cv2.imwrite(new_path, darker_img)
图像大小统一处理(40*40):
批量重命名文件夹中的图片文件
@H_607_85@import os
from PIL import Image
class BatchR@R_696_8371@():
def __init__(self):
self.path = r'.positive_images'
def r@R_696_8371@(self):
filelist = os.listdir(self.path)
@R_862_10586@l_num = len(filelist)
i = 0
for item in filelist:
if item.endswith('.jpg'):
src = os.path.join(os.path.abspath(self.path), item)
print(srC)
dst = os.path.join(os.path.abspath(self.path), str(i) + '.jpg')
try:
os.r@R_696_8371@(src, dst)
print ('converTing %s to %s ...' % (src, dst))
i = i + 1
except :
conTinue
print ('@R_862_10586@l %d to r@R_696_8371@ & converted %d jpgs' % (@R_862_10586@l_num, i))
if __name__ == '__main__':
demo = BatchR@R_696_8371@()
demo.r@R_696_8371@()
pass
执行后
@H_801_28@
批量修改图片尺寸
@H_607_85@from PIL import Image
import os.path
import glob
def convertjpg(jpgfile,outdir,width=40,height=40):
img=Image.open(jpgfilE)
try:
new_img=img.resize((width,height),Image.bILINEAR)
new_img.save(os.path.join(outdir,os.path.bas@R_696_8371@(jpgfilE)))
except Exception as e:
print(E)
for jpgfile in glob.glob(r".positive_images*.jpg"):
#像素修改后存入images文件
convertjpg(jpgfile,r".positive_images")
三、生成样本描述文件
生成正样本描述文件可以利用标注工具opencv_Annotation.exe
opencv_Annotation.exe的使用,在当前目录cmd下输入opencv_Annotation.exe可以看到是使用说明
@H_801_28@
比如:opencv_Annotation.exe -a=生成的pos.txt路径 -i=正样本文件夹路径
@H_801_28@
用鼠标左键标记进行矩形框选想要识别的物体
英文下c;’c'是确认框选c;'d'删除所选的框c;'n'是下一张c;'esc'是停止。
如果图片中只有一个物体c;可直接生成描述文件(尽量自己用opencv_Annotation标注c;效果更好)
@H_607_85@file_dir=os.getcwd()
print(file_dir)
file_dir=r'.positive_images'
L=[]
i=0
with open(r".pos.txt","w+") as f:
for root, dirs, files in os.walk(file_dir):
for file in files:
if os.path.splitext(filE)[1] == '.jpg':
l.append(os.path.join(root, filE))
f.write(L[i]+' 1'+' 0'+' 0'+' 40'+' 40'+'n')
i+=1
生成pos.txt
@H_801_28@
生成负样本描述文件(不用进行标注)
@H_607_85@file_dir=r'.negative_image'
L=[]
i=0
with open(r".neg.txt","w+") as f:
for root, dirs, files in os.walk(file_dir):
for file in files:
if os.path.splitext(filE)[1] == '.jpg':
l.append(os.path.join(root, filE))
f.write(L[i]+'n')
i+=1
print("ok")
生成neg.txt
@H_801_28@
四、 合成样本vec文件
这里只需要合成正样本vec文件c;负样本不需要c;这里使用opencv_createsamples.exe
opencv_createsamples.exe的使用,在当前目录cmd下输入opencv_createsamples.exe可以看到是使用说明
@H_801_28@
比如opencv_createsamples.exe -vec pos.vec -info pos.txt -num 50 -w 40 -h 40
-vec 参数代表.vec文件的存储位置;
-info 代表生成的Annotation的位置;
-num 生成的正样本的数目
-w 窗口的宽度;-h 窗口的高度;
@H_801_28@
结束之后在当前目录下生成pos.vec文件
五、训练模型
训练模型使用opencv_Traincascade.exe
opencv_Traincascade.exe的使用,在当前目录cmd下输入opencv_Traincascade.exe可以看到是使用说明
@H_801_28@
-data:指定保存训练结果的文件夹;
-vec:指定正样本集;
-bg:指定负样本的描述文件夹;
-numPos:指定每一级参与训练的正样本的数目(要小于正样本总数);
-numNeg:指定每一级参与训练的负样本的数目(可以大于负样本图片的总数);
-numStage:训练的级数;
-w:正样本的宽;-h:正样本的高;(必须与opencv_createsample中使用的-w和-h值一致)
-minHitRate:每一级需要达到的命中率(一般取值0.95-0.995);
-maxfalseAlarmRate:每一级所允许的最大误检率;
-mode:使用Haar-like特征时使用c;可选BASIC、CORE或者ALL;(ALL使用垂直和45度角旋转特征。)
(这个截图是训练好模型后c;再次运行opencv_Traincascade.exe的结果)
@H_801_28@
训练好分类器的文件在xml文件夹下@H_801_28@
六、测试模型
@H_607_85@import numpy as np
import cv2
#加载级联器
pineapple_cascade = cv2.CascadeClassifier(r'xmlcascade.xml')
#检测
def detect(imagE):
#将图像转变为灰度图像
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
#调用级联器
pineapples = face_cascade.detectMultiScale(gray,
scaleFactor=1.15,
minNeighbors=5,
minSize=(10, 10))
print(pineapples)
print("发现{0}个菠萝!".format(len(pineapples)))
#绘制出菠萝区域
for (x, y, w, h) in pineapples:
cv2.circle(image, (int((x + x + w) / 2), int((y + y + h) / 2)),
int(w / 2), (0, 255, 0), 2)
return image
retval=cv2.imread(r'test.jpg')
image=detect(retval)
cv2.imwrite('detect.jpg',imagE)
运行后生成检测后的图片detect.jpg(这里只是个展示c;样本少c;效果不是很好)
@H_801_28@
以上是大佬教程为你收集整理的OpenCV训练自己的物体检测分类器步骤全部内容,希望文章能够帮你解决OpenCV训练自己的物体检测分类器步骤所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。