用OpenCV3级联分类器自制自己的分类器详细过程

博主分享训练自定义分类器的详细过程。先对图片进行灰度化和归一化处理,接着生成可描述文件,制作正样本,随后进行级联分类器训练,介绍了训练参数设置,训练结束后得到cascade.xml文件用于目标检测,还给出测试示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近在做一个小项目,要训练自己的分类器,网上找了很多资料,但是没有很详细的,这里我将我做的过程,详细的总结一下,一来给大家总结经验,二来日后好查阅,原理我就不赘述,直接讲一下如何训练

一:图片的处理

做训练的图片要是灰度图,而且要统一大小,所以我就用python做了灰度化和归一化处理,代码如下:

from skimage import io,transform,color
import numpy as np
def convert_gray(f,**args):#图片处理与格式化的函数
      rgb=io.imread(f) #读取图片 
      gray=color.rgb2gray(rgb) #将彩色图片转换为灰度图片
      dst=transform.resize(gray,(40,40)) #调整大小,图像分辨率为40*40   
      return dst
datapath='D:/Face_Program/neg/' #图片所在的路径
str=datapath+'/*.jpg' #识别.jpg的图像
coll = io.ImageCollection(str,load_func=convert_gray)#批处理 
for i in range(len(coll)):

   io.imsave(r'D:/Face_Program/neg1//'+np.str(i)+'.jpg',coll[i]) #保存图片在d:/daate/date/人;

 

处理好图片后,我们就要开始训练了

 

二   生成可描述文件

在opencv的安装目录中的bin文件夹下有两个可执行文件opencv_createsamples.exe和opencv_traincascade.exe。将这两个文件拷贝到训练文件夹下,并将正、负样本的文件夹和描述文件——positive_samples.txt和negative_samples.txt也拷贝到这个文件夹下。同时,新建两个.bat文件——create_positive_samples.bat和traincascade.bat,新建一个文件夹data,data文件夹是用于存放之后训练完的数据。这样,训练目录如下:

我会把这个opencv文件放在后面,需要的自己下载

 

 


1。制作正样本,生成可描述文件

  • 打开window下的命令窗口,进入指定正样本数据目录下  输入:dir /b>positive_samples.txt 生成正样本的可描述文件

 

 

  • 然后使用editplus打开生成的文本文件positive_samples.txt 使用快捷键Ctrl+H打开Replace
             1.在行首填充所需字符

     

这里说明一下,图像处理成多少尺寸,生成描述文件的时候就是多少尺寸,我之间生成的是64*64的,但是训练的时候很慢我就改成40/840的了,正样本要有尺寸信息,负样本不需要。上面步骤是做的笔记现在保存退出,制作正样本

三  制作正样本

然后右键create_positive_samples.bat文件

其中,-info字段填写正样本描述文件;-vec用于保存制作的正样本;-num制定正样本的数目;-w和-h分别指定正样本的宽和高。

保存,双击这个文件,开始制作正样本:

 

最后结果

 

这样,正样本制作完成了

 四  级联分类器训练

 

下面进行级联分类器的训练,在traincascade.bat中输入如下内容

 

字段说明如下:

 

-data:指定保存训练结果的文件夹;

-vec:指定正样本集;

-bg:指定负样本的描述文件夹;

-numPos:指定每一级参与训练的正样本的数目(要小于正样本总数);

-numNeg:指定每一级参与训练的负样本的数目(可以大于负样本图片的总数);

-numStage:训练的级数;

-w:正样本的宽;

-h:正样本的高;

-minHitRate:每一级需要达到的命中率(一般取值0.95-0.995);

-maxFalseAlarmRate:每一级所允许的最大误检率;

-mode:使用Haar-like特征时使用,可选BASIC、CORE或者ALL;

numPos和numNeg要满足1:2.5-1:3之间,这个我自己也把握不好,只有自己慢慢试了,numStage一般在15-20之间,具体还是得靠自己把握,由于样本数不够或者内存等其他原因,训练层数达不到我们的结果,训练到一半就完成了,此时分类器还是可以用的,只是效果可能不太好,比如我自己最多只训练到第八层

另外,还可指定以下字段:

-featureType:可选HAAR或LBP,默认为HAAR;

其他字段将不再说明。


保存,双击执行,开始漫长的训练过程(训练可中断,中断后再执行,会继续中断前的训练

训练结束后,data文件夹下会生成如下训练结果

cascade.xml文件即为最终的训练结果,即可拿来进行目标检测,通过上述方法,可以训练自己的分类器哦

 

测试如下,在一段视频中检测目标

 
 
import cv2
import sys
from PIL import Image
 
def CatchUsbVideo(window_name, camera_idx):
    cv2.namedWindow(window_name)
    
    #视频来源,可以来自一段已存好的视频,也可以直接来自USB摄像头
    cap = cv2.VideoCapture(camera_idx)                
    
    #告诉OpenCV使用人脸识别分类器
    classfier = cv2.CascadeClassifier("D:\\Face_Program\\data4_8\\cascade.xml")
    
    #识别出人脸后要画的边框的颜色,RGB格式
    color = (0, 255, 0)
        
    while cap.isOpened():
        ok, frame = cap.read() #读取一帧数据
        if not ok:            
            break  
 
        #将当前帧转换成灰度图像
        grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)                 
        
        #人脸检测,1.2和3分别为图片缩放比例和需要检测的有效点数
        faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize= (40,40))
        if len(faceRects) > 0:            #大于0则检测到                                   
            for faceRect in faceRects:  #单独框出每一张
                x, y, w, h = faceRect        
                cv2.rectangle(frame, (x - 20, y - 20), (x + w + 10, y + h + 10), color, 2)
                        
        #显示图像
        cv2.imshow(window_name, frame)        
        c = cv2.waitKey(10)
        if c & 0xFF == ord('q'):
            break        

    #释放摄像头并销毁所有窗口
    cap.release()
    cv2.destroyAllWindows() 
    
if __name__ == '__main__':
    if len(sys.argv) != 1:
        print("Usage:%s camera_id\r\n" % (sys.argv[0]))
    else:
        CatchUsbVideo(" recognition region", 0)

希望能对大家有所帮助,有所启发

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值