摘要:负样本不是我们想要的分类对应的样本,就是除了菠萝的图片样本数据越多检测效果越好,正样本的特征越明显越好,负样本背景越复杂越好。
环境:python3.7 OpenCV3.4.3.18
工具:
opencv_annotation.exe
opencv_createsamples.exe
opencv_traincascade.exe
环境和工具下载安装
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后在以下目录
一、准备阶段
文件模板
positive_images放置正样本图片、negative_image放置负样本图片、xml为训练好的分类器文件
样本收集
正样本:我们想要正确分类出的类别所对应的样本,例如,我们要对一张图片进行分类,以确定其是否属于菠萝,那么在训练的时候,菠萝的图片则为正样本。
负样本:不是我们想要的分类对应的样本,就是除了菠萝的图片
样本数据越多检测效果越好,正样本的特征越明显越好,负样本背景越复杂越好。
1、去www.kaggle.com下载想要的数据集或者使用scrapy+selenium批量爬取图片
2、自己拍摄想要检测物体的图片
二、预处理
图像的注水处理:通过自动对图像的旋转、平移、缩放从而增加样本数量
比如:通过旋转
"path是图片路径,执行后,会在同一目录下生成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)
调节亮度:
"path是图片路径,执行后会在同一目录下生成五张亮度依次递增的图片"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):
批量重命名文件夹中的图片文件
import osfrom PIL import Imageclass BatchRename(): def __init__(self): self.path = r"./positive_images" def rename(self): filelist = os.listdir(self.path) total_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.rename(src, dst) print ("converting %s to %s ..." % (src, dst)) i = i + 1 except : continue print ("total %d to rename & converted %d jpgs" % (total_num, i)) if __name__ == "__main__": demo = BatchRename() demo.rename() pass
执行后
批量修改图片尺寸
from PIL import Imageimport os.pathimport globdef 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.basename(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可以看到是使用说明
比如:opencv_annotation.exe -a=生成的pos.txt路径 -i=正样本文件夹路径
用鼠标左键标记进行矩形框选想要识别的物体
英文下,’c"是确认框选,"d"删除所选的框,"n"是下一张,"esc"是停止。
如果图片中只有一个物体,可直接生成描述文件(尽量自己用opencv_annotation标注,效果更好)
file_dir=os.getcwd()print(file_dir)file_dir=r"./positive_images"L=[]i=0with 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
生成负样本描述文件(不用进行标注)
file_dir=r"./negative_image"L=[]i=0with 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+=1print("ok")
生成neg.txt
四、 合成样本vec文件
这里只需要合成正样本vec文件,负样本不需要,这里使用opencv_createsamples.exe
opencv_createsamples.exe的使用,在当前目录cmd下输入opencv_createsamples.exe可以看到是使用说明
比如opencv_createsamples.exe -vec pos.vec -info pos.txt -num 50 -w 40 -h 40
-vec 参数代表.vec文件的存储位置;
-info 代表生成的annotation的位置;
-num 生成的正样本的数目
-w 窗口的宽度;-h 窗口的高度;
结束之后在当前目录下生成pos.vec文件
五、训练模型
训练模型使用opencv_traincascade.exe
opencv_traincascade.exe的使用,在当前目录cmd下输入opencv_traincascade.exe可以看到是使用说明
比如:opencv_traincascade.exe -data xml -vec pos.vec -bg neg.txt -numPos 10 -numNeg 2000 -numStages 15 -w 40 -h 40 -minHitRate 0.999 -maxFalseAlarmRate 0.5 -mode ALL
-data:指定保存训练结果的文件夹;
-vec:指定正样本集;
-bg:指定负样本的描述文件夹;
-numPos:指定每一级参与训练的正样本的数目(要小于正样本总数);
-numNeg:指定每一级参与训练的负样本的数目(可以大于负样本图片的总数);
-numStage:训练的级数;
-w:正样本的宽;-h:正样本的高;(必须与opencv_createsample中使用的-w和-h值一致)
-minHitRate:每一级需要达到的命中率(一般取值0.95-0.995);
-maxFalseAlarmRate:每一级所允许的最大误检率;
-mode:使用Haar-like特征时使用,可选BASIC、CORE或者ALL;(ALL使用垂直和45度角旋转特征。)
(这个截图是训练好模型后,再次运行opencv_traincascade.exe的结果)
训练好分类器的文件在xml文件夹下
六、测试模型
import numpy as npimport cv2#加载级联器pineapple_cascade = cv2.CascadeClassifier(r"xml/cascade.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 imageretval=cv2.imread(r"test.jpg")image=detect(retval)cv2.imwrite("detect.jpg",image)
运行后生成检测后的图片detect.jpg(这里只是个展示,样本少,效果不是很好)
以上只是一个简单的训练步骤展示,供参考学习使用
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/121823.html
摘要:工作原理以前的检测系统通过重复利用分类器和定位器来实现目标识别。修改检测阈值缺省情况下,只显示信心大于的对象。用法如下这个,呵呵,不完美把白马识别成绵羊了,把黑狗识别成奶牛了,但确实很快。 原标题:YOLO: Real-Time Object Detection英文原文:https://pjreddie.com/darknet/... 强烈推荐(TED视频):https://www....
摘要:工作原理以前的检测系统通过重复利用分类器和定位器来实现目标识别。修改检测阈值缺省情况下,只显示信心大于的对象。用法如下这个,呵呵,不完美把白马识别成绵羊了,把黑狗识别成奶牛了,但确实很快。 原标题:YOLO: Real-Time Object Detection英文原文:https://pjreddie.com/darknet/... 强烈推荐(TED视频):https://www....
摘要:知道目标检测的定义。目标检测框的中心点坐标。提取分类的目标检测框架。 文章目录 商品目标检测1. 目标检测概述1.1.项目演示介绍学习目标1.1.1 项目演示1....
摘要:但是他们对于实时监测来说,还是有点慢。上图是我们用于物体检测的训练数据集的示例。分类器在每个步骤中应用于检测对象。 卷积神经网络(CNN)在物体识别中由于其他的神经网络架构,所以研究人员很快对 CNN 进行了改进以使得它们能更好的对物体进行定位和检测,这种神经网络架构就被称为 R-CNN(Region-CNN)。R-CNN 的输出是具有矩形框的图像,以下是 R-CNN 如何工作的步骤:使用称...
摘要:只使用右上特征,使用所有右上特征及度旋转特征使用特征的前提下,否则不使用此参数在中生成即为成功 1.vsc步骤 win+R com进入dos打开生成vas的exe文件 (1)E: (2)cd Python Pycharm (3)cd opencv (4)cd my_xml (5)openc...
阅读 2991·2021-11-22 15:22
阅读 849·2021-11-11 16:55
阅读 1360·2021-10-08 10:16
阅读 1956·2021-10-08 10:05
阅读 967·2021-09-26 10:20
阅读 3383·2021-09-01 10:47
阅读 2324·2019-08-30 15:52
阅读 2560·2019-08-30 13:18