精华内容
下载资源
问答
  • 行人检测训练

    热门讨论 2016-12-14 14:44:23
    行人检测训练库,负样本12000,正样本2400.
  • DSOD训练行人检测数据

    千次阅读 热门讨论 2018-11-01 21:23:44
    (五)训练行人检测数据 在example下新建文件dsod_train,将example/dsod中的文件复制到dsod_train中。 在data下新建文件dsod_trian,将VOC0712中的内容复制到dsod_train中。 # mkdir dsod_train # cp -rf ...

    版权声明:原创博客未经允许请勿转载!https://mp.csdn.net/postedit/83615211

    (一)系统版本:

    1. GPU型号:
    # nvidia-smi
    Thu Nov  1 01:29:23 2018       
    +-----------------------------------------------------------------------------+
    | NVIDIA-SMI 390.87                 Driver Version: 390.87                    |
    |-------------------------------+----------------------+----------------------+
    | GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
    | Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
    |===============================+======================+======================|
    |   0  TITAN Xp            Off  | 00000000:06:00.0  On |                  N/A |
    | 36%   59C    P2   161W / 250W |   4726MiB / 12195MiB |     51%      Default |
    +-------------------------------+----------------------+----------------------+
    |   1  TITAN Xp            Off  | 00000000:84:00.0 Off |                  N/A |
    | 23%   23C    P8    16W / 250W |     12MiB / 12196MiB |      0%      Default |
    +-------------------------------+----------------------+----------------------+
                                                                                   
    +-----------------------------------------------------------------------------+
    | Processes:                                                       GPU Memory |
    |  GPU       PID   Type   Process name                             Usage      |
    |=============================================================================|
    +-----------------------------------------------------------------------------+
    

             2.cuda与cudnn版本:

    # cat /usr/local/cuda/version.txt
    CUDA Version 8.0.44
    # cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2
    #define CUDNN_MAJOR      5
    #define CUDNN_MINOR      1
    #define CUDNN_PATCHLEVEL 10
    --
    #define CUDNN_VERSION    (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL)
    
    #include "driver_types.h"
    

             3.系统版本

    #cat /proc/version
    Linux version 3.10.0-693.el7.x86_64 (builder@kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) ) #1 SMP Tue Aug 22 21:09:27 UTC 2017
    

    (二)安装SSD,源代码:https://github.com/weiliu89/caffe/tree/ssd

    (三)复现SSD论文实验后面填坑。

    (四)安装DSOD

    1. 需要在SSD可以运行的基础上新建文件然后复制,具体过程:
    Create a subfolder dsod under example/, add files DSOD300_pascal.py, DSOD300_pascal++.py, DSOD300_coco.py, score_DSOD300_pascal.py and DSOD300_detection_demo.py to the folder example/dsod/.
    
    Create a subfolder grp_dsod under example/, add files GRP_DSOD320_pascal.py and score_GRP_DSOD320_pascal.py to the folder example/grp_dsod/.
    
    Replace the file model_libs.py in the folder python/caffe/ with ours.

          2.具体代码详见:https://github.com/szq0214/DSOD

          3.训练

    Train a DSOD model on VOC 07+12:
    
    python examples/dsod/DSOD300_pascal.py
    Train a DSOD model on VOC 07++12:
    
    python examples/dsod/DSOD300_pascal++.py
    Train a DSOD model on COCO trainval:
    
    python examples/dsod/DSOD300_coco.py

         4.问题

    Check failed: mdb_status == 0 (2 vs. 0) No such file or directory

    因为显卡内存小,有说可能是因为batch_size设置的过大的原因

    源码:batch_size = 32

    accum_batch_size = 128

    /home/caffe-ssd/examples/dsod +273

    修改为:batch_size =4# 32

    accum_batch_size =16# 128

    Check failed: error == cudaSuccess (10 vs. 0)  invalid device ordinal

    这是由于GPU数量不匹配造成的,需要将solver.prototxt文件中的device_id项改为自己的GPU块数,一块就是0,两块就是1,以此类推。

    example/dsod/DSOD300_pascal.py +278    gpus = "0,1,2,3,4,5,6,7" 改为gpus = "0” 

    (五)训练行人检测数据

    1. 在example下新建文件dsod_train,将example/dsod中的文件复制到dsod_train中。
    2. 在data下新建文件dsod_trian,将VOC0712中的内容复制到dsod_train中。
    # mkdir dsod_train
    # cp -rf /home/caffe-ssd/data/VOC0712/* /home/caffe-ssd/data/dsod_train/
    

         3. 在data下新建文件sample,在sample下新建dsod_train与mydatasets。

         4. 准备数据,行人数据是标准的VOC数据格式,传输数据到mydatasets中,有以下几个方法:

    • 下载xftp,安装好之后在xshell中打开xftp(ctrl+Alt+F),可以实现本地电脑与服务器之间的文件互传。
    • 安装FileZilla软件,它是免费开源的FTP软件,网上教程很多。

    • 使用sz,rz。Linux/Unix同Windows进行ZModem文件传输的命令行工具。(与直接拖文件进入效果一样)

      安装方法:

    #apt-get install lrzsz

    从服务端发送文件到客户端:sz后回车弹出选择的文件。 

    • 如果没有安装xftp,点击后选择取消,会弹出一个页面,在页面中用put的方法也可以实现文件传输,个人理解这就是没界面的xftp。不会用可以看看help,里面写的很清楚。
    #sftp:/home/caffe-ssd/data/sample/mydatasets> put Z:\深度学习\Annotations /home/caffe-ssd/data/sample/mydatasets/

           5. 准备好了数据,解压后开始转成LMDB的格式。首先修改data/dsod/creat_list.sh,代码如下:

    #!/bin/bash
    
    #root_dir=/home/caffe-ssd/data/VOCdevkit/
    root_dir=/home/caffe-ssd/data/sample/
    sub_dir=ImageSets/Main
    bash_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
    for dataset in trainval test
    do
      dst_file=$bash_dir/$dataset.txt
      if [ -f $dst_file ]
      then
        rm -f $dst_file
      fi
      #for name in VOC2007 VOC2012
      for name in mydatasets
      do
       # if [[ $dataset == "test" && $name == "VOC2012" ]]
       # then
       #   continue
       # fi
        echo "Create list for $name $dataset..."
        dataset_file=$root_dir/$name/$sub_dir/$dataset.txt
    
        img_file=$bash_dir/$dataset"_img.txt"
        cp $dataset_file $img_file
        sed -i "s/^/$name\/JPEGImages\//g" $img_file
        sed -i "s/$/.jpg/g" $img_file
    
        label_file=$bash_dir/$dataset"_label.txt"
        cp $dataset_file $label_file
        sed -i "s/^/$name\/Annotations\//g" $label_file
        sed -i "s/$/.xml/g" $label_file
    
        paste -d' ' $img_file $label_file >> $dst_file
    
        rm -f $label_file
        rm -f $img_file
      done
    
      # Generate image name and size infomation.
      if [ $dataset == "test" ]
      then
        $bash_dir/../../build/tools/get_image_size $root_dir $dst_file $bash_dir/$dataset"_name_size.txt"
      fi
    
      # Shuffle trainval file.
      if [ $dataset == "trainval" ]
      then
        rand_file=$dst_file.random
        cat $dst_file | perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' > $rand_file
        mv $rand_file $dst_file
      fi
    done
    ~                                                                                                                                                                                    
    ~                                                                                                                                                                                    
    ~                                                

     运行./create_list.sh 

    /home/caffe-ssd/data/dsod_train
    Create list for mydatasets trainval...
    Create list for mydatasets test...
    I1101 11:48:46.939064  3113 get_image_size.cpp:61] A total of 2171 images.
    I1101 11:48:51.158903  3113 get_image_size.cpp:100] Processed 1000 files.
    I1101 11:48:55.381808  3113 get_image_size.cpp:100] Processed 2000 files.
    I1101 11:48:56.103267  3113 get_image_size.cpp:105] Processed 2171 files.
    

    在data/dsod_train里面会重新生成三个文件(以前的不用删,运行程序会直接覆盖以前的) 

    -rw-r--r--. 1 root root 140915 Nov  1 04:01 test.txt
    -rw-r--r--. 1 root root  38978 Nov  1 04:02 test_name_size.txt
    -rw-r--r--. 1 root root 563089 Nov  1 04:01 trainval.txt
    
    root@8606b1e08332:/home/caffe-ssd/data/train_sample# vim test.txt 
    
    sample/JPEGImages/03_245525.jpg sample/Annotations/03_245525.xml
    sample/JPEGImages/01_77660.jpg sample/Annotations/01_77660.xml
    sample/JPEGImages/02_211004.jpg sample/Annotations/02_211004.xml
    sample/JPEGImages/02_468307.jpg sample/Annotations/02_468307.xml
    sample/JPEGImages/03_831804.jpg sample/Annotations/03_831804.xml
    sample/JPEGImages/04_796466.jpg sample/Annotations/04_796466.xml
    sample/JPEGImages/03_2584905.jpg sample/Annotations/03_2584905.xml
    sample/JPEGImages/03_260282.jpg sample/Annotations/03_260282.xml
    sample/JPEGImages/03_2277306.jpg sample/Annotations/03_2277306.xml
    
    root@8606b1e08332:/home/caffe-ssd/data/train_sample# vim trainval.txt 
    
    sample/JPEGImages/03_1164425.jpg sample/Annotations/03_1164425.xml
    sample/JPEGImages/04_41943.jpg sample/Annotations/04_41943.xml
    sample/JPEGImages/01_277407.jpg sample/Annotations/01_277407.xml
    sample/JPEGImages/01_223079.jpg sample/Annotations/01_223079.xml
    sample/JPEGImages/01_69969.jpg sample/Annotations/01_69969.xml
    sample/JPEGImages/01_371695.jpg sample/Annotations/01_371695.xml
    sample/JPEGImages/03_123987.jpg sample/Annotations/03_123987.xml
    sample/JPEGImages/02_185663.jpg sample/Annotations/02_185663.xml
    sample/JPEGImages/04_31490.jpg sample/Annotations/04_31490.xml
    sample/JPEGImages/01_208821.jpg sample/Annotations/01_208821.xml
    
    root@8606b1e08332:/home/caffe-ssd/data/train_sample# vim test_name_size.txt 
    
    03_245525 480 640
    01_77660 480 640
    02_211004 480 640
    02_468307 480 640
    03_831804 480 640
    04_796466 480 640
    03_2584905 480 640
    03_260282 480 640
    

     修改caffe-ssd/data/train_sample/labelmap_voc.prototxt 除了background之外改成自己的类别,我的是两类。

    # vim labelmap_voc.prototxt 
    
    item {
      name: "none_of_the_above"
      label: 0
      display_name: "background"
    }
    item {
      name: "headshoulder"
      label: 1
      display_name: "headshoulder"
    }
    item {
      name: "ignore"
      label: 2
      display_name: "ignore"
    }
    

       6. 修改data/dsod_train/creat_data.sh  

    ur_dir=$(cd $( dirname ${BASH_SOURCE[0]} ) && pwd )
    root_dir=$cur_dir/../..
    
    cd $root_dir
    
    redo=1
    data_root_dir="/home/caffe-ssd/data/sample"
    dataset_name="dsod_train"
    mapfile="$root_dir/data/$dataset_name/labelmap_voc.prototxt"
    anno_type="detection"
    db="lmdb"
    min_dim=0
    max_dim=0
    width=0
    height=0
    
    extra_cmd="--encode-type=jpg --encoded"
    if [ $redo ]
    then
      extra_cmd="$extra_cmd --redo"
    fi
    for subset in test trainval
    do
      python $root_dir/scripts/create_annoset.py --anno-type=$anno_type --label-map-file=$mapfile --min-dim=$min_dim --max-dim=$max_dim --resize-width=$width --resize-height=$height --check-label $extra_cmd $data_root_dir $root_dir/data/$dataset_name/$subset.txt $data_root_dir/$dataset_name/$db/$dataset_name"_"$subset"_"$db examples/$dataset_name
    done
    

    修改完后运行./creat_data.sh 。在example/train_sample中生成两个lmdb链接;在/data/sample/dsod_train/lmdb会生成转化好的lmdb文件。

       7. 修改example/dsod_train/DSOD300_pascal.py文件

       8. 训练  python ./example/dsod_train/DSOD300_pascal.py

    明天记录结果和测试效果。

    展开全文
  • 基于CUHK行人检测数据制作的人头数据,7000+正样本 ,该数据大小为60*60,可用于Hog特征提取,进一步用于训练人体分类模型用于监控系统中的行人检测
  • 行人检测数据

    万次阅读 2017-04-21 19:14:55
    MIT数据库 该数据库为较早公开的行人数据库,共924张行人图片(ppm格式,宽高为64×128),肩到脚的距离约...该数据库是目前使用最多的静态行人检测数据库,提供原始图片及相应的标注文件。训练集有正样本614张(包

    MIT数据库

    数据库为较早公开的行人数据库,共924张行人图片(ppm格式,宽高为64×128),肩到脚的距离约80象素。该数据库只含正面和背面两个视角,无负样本,未区分训练集和测试集。Dalal等采用“HOG+SVM”,在该数据库上的检测准确率接近100%。

    INRIA数据库

    该数据库是目前使用最多的静态行人检测数据库,提供原始图片及相应的标注文件。训练集有正样本614张(包含2416个行人),负样本1218张;测试集有正样本288张(包含1126个行人),负样本453张。图片中人体大部分为站立姿势且高度大于100个象素,部分标注可能不正确。图片主要来源于GRAZ-01、个人照片及google,因此图片的清晰度较高。在XP操作系统下部分训练或者测试图片无法看清楚,但可用OpenCV正常读取和显示。

    Daimler行人数据库

    该数据库采用车载摄像机获取,分为检测和分类两个数据集。检测数据集的训练样本集有正样本大小为18×36和48×96的图片各15560(3915×4)张,行人的最小高度为72个象素;负样本6744张(大小为640×480或360×288)。测试集为一段27分钟左右的视频(分辨率为640×480),共21790张图片,包含56492个行人。分类数据库有三个训练集和两个测试集,每个数据集有4800张行人图片,5000张非行人图片,大小均为18×36,另外还有3个辅助的非行人图片集,各1200张图片。

    Caltech行人数据库

    该数据库是目前规模较大的行人数据库,采用车载摄像头拍摄,约10个小时左右,视频的分辨率为640×480,30帧/秒。标注了约250,000帧(约137分钟),350000个矩形框,2300个行人,另外还对矩形框之间的时间对应关系及其遮挡的情况进行标注。数据集分为set00~set10,其中set00~set05为训练集,set06~set10为测试集(标注信息尚未公开)。性能评估方法有以下三种:(1)用外部数据进行训练,在set06~set10进行测试;(2)6-fold交叉验证,选择其中的5个做训练,另外一个做测试,调整参数,最后给出训练集上的性能;(3)用set00~set05训练,set06~set10做测试。由于测试集的标注信息没有公开,需要提交给Pitor Dollar。结果提交方法为每30帧做一个测试,将结果保存在txt文档中(文件的命名方式为I00029.txt I00059.txt ……),每个txt文件中的每行表示检测到一个行人,格式为“[left, top,width, height, score]”。如果没有检测到任何行人,则txt文档为空。该数据库还提供了相应的Matlab工具包,包括视频标注信息的读取、画ROC(Receiver Operatingcharacteristic Curve)曲线图和非极大值抑制等工具。

    TUD行人数据库

    TUD行人数据库为评估运动信息在行人检测中的作用,提供图像对以便计算光流信息。训练集的正样本为1092对图像(图片大小为720×576,包含1776个行人);负样本为192对非行人图像(手持摄像机85对,车载摄像机107对);另外还提供26对车载摄像机拍摄的图像(包含183个行人)作为附加训练集。测试集有508对图像(图像对的时间间隔为1秒,分辨率为640×480),共有1326个行人。Andriluka等也构建了一个数据库用于验证他们提出的检测与跟踪相结合的行人检测技术。该数据集的训练集提供了行人的矩形框信息、分割掩膜及其各部位(脚、小腿、大腿、躯干和头部)的大小和位置信息。测试集为250张图片(包含311个完全可见的行人)用于测试检测器的性能,2个视频序列(TUD-Campus和TUD-Crossing)用于评估跟踪器的性能。

    NICTA行人数据库

    该数据库是目前规模较大的静态图像行人数据库,25551张含单人的图片,5207张高分辨率非行人图片,数据库中已分好训练集和测试集,方便不同分类器的比较。Overett等用“RealBoost+Haar”评估训练样本的平移、旋转和宽高比等各种因素对分类性能的影响:(1)行人高度至少要大于40个象素;(2)在低分辨率下,对于Haar特征来说,增加样本宽度的性能好于增加样本高度的性能;(3)训练图片的大小要大于行人的实际大小,即背景信息有助于提高性能;(4)对训练样本进行平移提高检测性能,旋转对性能的提高影响不大。以上的结论对于构建行人数据库具有很好的指导意义。

    ETH行人数据库

    Ess等构建了基于双目视觉的行人数据库用于多人的行人检测与跟踪研究。该数据库采用一对车载的AVT Marlins F033C摄像头进行拍摄,分辨率为640×480,帧率13-14fps,给出标定信息和行人标注信息,深度信息采用置信度传播方法获取。

    CVC行人数据库

    该数据库目前包含三个数据集(CVC-01、CVC-02和CVC-Virtual),主要用于车辆辅助驾驶中的行人检测研究。CVC-01[Geronimo,2007]有1000个行人样本,6175个非行人样本(来自于图片中公路区域中的非行人图片,不像有的行人数据库非行人样本为天空、沙滩和树木等自然图像)。CVC-02包含三个子数据集(CVC-02-CG、CVC-02-Classification和CVC-02-System),分别针对行人检测的三个不同任务:感兴趣区域的产生、分类和系统性能评估。图像的采集采用Bumblebee2立体彩色视觉系统,分辨率640×480,焦距6mm,对距离摄像头0~50m的行人进行标注,最小的行人图片为12×24。CVC-02-CG主要针对候选区域的产生,有100张彩色图像,包含深度和3D点信息;CVC-02-Classification主要针对行人分类,训练集有1016张正样本,7650张负样本,测试集分为基于切割窗口的分类(570张行人,7500张非行人)和整张图片的检测(250张包含行人的图片,共587个行人);CVC-02-System主要用于系统的性能评估,包含15个视频序列(4364帧),7983个行人。CVC-Virtual是通过Half-Life 2图像引擎产生的虚拟行人数据集,共包含1678虚拟行人,2048个非行人图片用于测试。

    USC行人数据库

    该数据库包含三组数据集(USC-A、USC-B和USC-C),以XML格式提供标注信息。USC-A[Wu, 2005]的图片来自于网络,共205张图片,313个站立的行人,行人间不存在相互遮挡,拍摄角度为正面或者背面;USC-B的图片主要来自于CAVIAR视频库,包括各种视角的行人,行人之间有的相互遮挡,共54张图片,271个行人;USC-C有100张图片来自网络的图片,232个行人(多角度),行人之间无相互遮挡。

    展开全文
  • 计算机视觉相关算法研究,把之前用过的数据库下载进行上传 ,以方便更多的人下载。
  • WiderPerson行人检测数据

    千次阅读 2019-10-26 15:24:46
    WiderPerson数据是比较拥挤场景的行人检测基准数据,其图像是从多种场景中选择的,不再局限于交通场景。 选择13382张图像,并用各种遮挡标记约40万个注释。 我们随机选择8000/1000/4382图像作为训练,验证和测试...

    1. 简介

    WiderPerson数据集是比较拥挤场景的行人检测基准数据集,其图像是从多种场景中选择的,不再局限于交通场景。 选择13382张图像,并用各种遮挡标记约40万个注释。 我们随机选择8000/1000/4382图像作为训练,验证和测试集。 与CityPersons和WIDER FACE数据集相似,不发布测试图像的标注文件。 

    可以在官网上进行下载:http://www.cbsr.ia.ac.cn/users/sfzhang/WiderPerson/

    2. 标注详解

    随便打开一个标注文件如下所示:

    1. 第一行代表了标注框的数目,从第二行开始才是真正的标注框

    2. 从第二行开始,第一列代表了这个标注框的类别,后面分别是xmin ymin xmax ymax也就是左上角右下角坐标

    [class_label, xmin, ymin, xmax, ymax]

    写了个可视化程序进行查看:

    import os
    import cv2
    
    
    if __name__ == '__main__':
        path = '../WiderPerson/trainval.txt'
        with open(path, 'r') as f:
            img_ids = [x for x in f.read().splitlines()]
    
        for img_id in img_ids: # '000040'
            img_path = '../WiderPerson/images/' + img_id + '.jpg'
            img = cv2.imread(img_path)
    
            im_h = img.shape[0]
            im_w = img.shape[1]
    
            label_path = img_path.replace('images', 'Annotations') + '.txt'
    
            with open(label_path) as file:
                line = file.readline()
                count = int(line.split('\n')[0]) # 里面行人个数
                line = file.readline()
                while line:
                    cls = int(line.split(' ')[0])
                    # < class_label =1: pedestrians > 行人
                    # < class_label =2: riders >      骑车的
                    # < class_label =3: partially-visible persons > 遮挡的部分行人
                    # < class_label =4: ignore regions > 一些假人,比如图画上的人
                    # < class_label =5: crowd > 拥挤人群,直接大框覆盖了
                    if cls == 1 or cls == 2 or cls == 3:
                        xmin = float(line.split(' ')[1])
                        ymin = float(line.split(' ')[2])
                        xmax = float(line.split(' ')[3])
                        ymax = float(line.split(' ')[4].split('\n')[0])
                        img = cv2.rectangle(img, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (0, 255, 0), 2)
                    line = file.readline()
            cv2.imshow('result', img)
            cv2.waitKey(0)

    可以看到都是一些比较拥挤场景的行人图片,不过跟实际比较贴切一些,不像其他一些数据集都是在国外开奔驰的场景,感觉对自己的实际场景应该会有帮助:

    需要注意000040.jpg.txt貌似有问题,自己删掉就好了

    3. 类别解析

    官网是这么说的,但是自己还是有点不理解,就自己绘制看看了

    ...
    < class_label =1: pedestrians >
    < class_label =2: riders >
    < class_label =3: partially-visible persons >
    < class_label =4: ignore regions >
    < class_label =5: crowd >
    ...

     类别 1:pedestrians 行人

    根据自己的可视化代码,cls == 1的时候绘制出来。可以看到都是比较完整的行人图片,这个比较好理解

     

    类别 2:riders 骑车的人

    这个很好理解

    类别 3:partially-visible persons 被挡住了一部分的人

    这个也比较好理解,就是遮挡嘛,不过有些时候遮挡严重都快看不出来是个人了。。

    类别 4:ignore regions

    这个是重点了,一开始有点懵,不知道啥意思,绘制出来如下(这是“假人”,自己实际应用并不需要这样的假人,不过VOC COCO数据集都标注为person了):

    类别 5:crowd

    拥挤人群直接大框笼罩了,COCO 数据集很多也这样而且还标成person了

     

    4 数据集转换

    转成VOC格式

    import os
    import numpy as np
    import scipy.io as sio
    import shutil
    from lxml.etree import Element, SubElement, tostring
    from xml.dom.minidom import parseString
    import cv2
    
    def make_voc_dir():
        # labels 目录若不存在,创建labels目录。若存在,则清空目录
        if not os.path.exists('../VOC2007/Annotations'):
            os.makedirs('../VOC2007/Annotations')
        if not os.path.exists('../VOC2007/ImageSets'):
            os.makedirs('../VOC2007/ImageSets')
            os.makedirs('../VOC2007/ImageSets/Main')
        if not os.path.exists('../VOC2007/JPEGImages'):
            os.makedirs('../VOC2007/JPEGImages')
    
    if __name__ == '__main__':
        classes = {'1': 'pedestrians',
                   '2': 'riders',
                   '3': 'partially',
                   '4': 'ignore',
                   '5': 'crowd'}
        VOCRoot = '../VOC2007'
        widerDir = '../WiderPerson'  # 数据集所在的路径
        wider_path = '../WiderPerson/trainval.txt'
        make_voc_dir()
        with open(wider_path, 'r') as f:
            imgIds = [x for x in f.read().splitlines()]
    
        for imgId in imgIds:
            objCount = 0  # 一个标志位,用来判断该img是否包含我们需要的标注
            filename = imgId + '.jpg'
            img_path = '../WiderPerson/images/' + filename
            print('Img :%s' % img_path)
            img = cv2.imread(img_path)
            width = img.shape[1]  # 获取图片尺寸
            height = img.shape[0]  # 获取图片尺寸 360
    
            node_root = Element('annotation')
            node_folder = SubElement(node_root, 'folder')
            node_folder.text = 'JPEGImages'
            node_filename = SubElement(node_root, 'filename')
            node_filename.text = 'VOC2007/JPEGImages/%s' % filename
            node_size = SubElement(node_root, 'size')
            node_width = SubElement(node_size, 'width')
            node_width.text = '%s' % width
            node_height = SubElement(node_size, 'height')
            node_height.text = '%s' % height
            node_depth = SubElement(node_size, 'depth')
            node_depth.text = '3'
    
            label_path = img_path.replace('images', 'Annotations') + '.txt'
            with open(label_path) as file:
                line = file.readline()
                count = int(line.split('\n')[0])  # 里面行人个数
                line = file.readline()
                while line:
                    cls_id = line.split(' ')[0]
                    xmin = int(line.split(' ')[1]) + 1
                    ymin = int(line.split(' ')[2]) + 1
                    xmax = int(line.split(' ')[3]) + 1
                    ymax = int(line.split(' ')[4].split('\n')[0]) + 1
                    line = file.readline()
    
                    cls_name = classes[cls_id]
    
                    obj_width = xmax - xmin
                    obj_height = ymax - ymin
    
                    difficult = 0
                    if obj_height <= 6 or obj_width <= 6:
                        difficult = 1
    
                    node_object = SubElement(node_root, 'object')
                    node_name = SubElement(node_object, 'name')
                    node_name.text = cls_name
                    node_difficult = SubElement(node_object, 'difficult')
                    node_difficult.text = '%s' % difficult
                    node_bndbox = SubElement(node_object, 'bndbox')
                    node_xmin = SubElement(node_bndbox, 'xmin')
                    node_xmin.text = '%s' % xmin
                    node_ymin = SubElement(node_bndbox, 'ymin')
                    node_ymin.text = '%s' % ymin
                    node_xmax = SubElement(node_bndbox, 'xmax')
                    node_xmax.text = '%s' % xmax
                    node_ymax = SubElement(node_bndbox, 'ymax')
                    node_ymax.text = '%s' % ymax
                    node_name = SubElement(node_object, 'pose')
                    node_name.text = 'Unspecified'
                    node_name = SubElement(node_object, 'truncated')
                    node_name.text = '0'
    
            image_path = VOCRoot + '/JPEGImages/' + filename
            xml = tostring(node_root, pretty_print=True)  # 'annotation'
            dom = parseString(xml)
            xml_name = filename.replace('.jpg', '.xml')
            xml_path = VOCRoot + '/Annotations/' + xml_name
            with open(xml_path, 'wb') as f:
                f.write(xml)
            # widerDir = '../WiderPerson'  # 数据集所在的路径
            shutil.copy(img_path, '../VOC2007/JPEGImages/' + filename)
    
    

    转成YOLO格式

     

    5. 数据集清洗

    这么大数据集而且又是密集场景,难免错标漏标,而且类别为crowd拥挤场景和ignore‘假人’对于自己实际用也是不需要的

    展开全文
  • 行人检测分类器的训练训练完可测试效果如何,注意样本的路径问题 行人检测分类器的训练训练完可测试效果如何,注意样本的路径问题
  • opencv训练SVM进行行人检测
  • 9. 对于难例的处理, 所谓的难例就是第一次训练出的分类器负样本原图中检测到的有行人的样本, 这些误报使得行人检测的分类器不是那么准确, 所以可以将误报的矩形框保存为新的负样本, 对新的负样本进行二次训练, 实现...

    目录

    1.训练过程(即代码流程)

    2.模型及结果优缺点分析

    3.模型建立中发现的问题及改进方法

    4.行人检测OpenCv 代码(C++)


    1.训练过程(即代码流程)

    1. 准备训练样本集合: 包括正样本集合和负样本集合. 
    2. 对训练样本进行处理, 根据法国国家信息与自动化研究所行人数据库(INRIA Person DataBase)给出的样本集和图像信息, 进行样本采集.(Tools类中的 ImgCut() 函数)(这里进行处理的主要作用是对样本进行归一化, 将其归一到一个尺度(64*120)) 
    3. 提取正样本的HOG特征. 
    4. 提取负样本的HOG特征. 
    5. 对正负样本进行标记, 正样本为1, 负样本为0. 
    6. 将正负样本的HOG特征及正负样本的标签输入 SVM 进行训练. 
    7. 训练后SVM 的结果保存在 Pedestrian.xml文件中. 
    8. 对得到的Pedestrian.xml文件输入进SVM得到行人检测分类器, 进行行人检测, 行人检测的主要会应用于智能交通, 此程序不仅可以对图片处理,还可以对视频进行处理, 并且是一个可视化的过程, 这里的视频数据来自加州理工行人检测基准数据(Caltech Pedestrian Detection Benchmark). 
    9. 对于难例的处理, 所谓的难例就是第一次训练出的分类器负样本原图中检测到的有行人的样本, 这些误报使得行人检测的分类器不是那么准确, 所以可以将误报的矩形框保存为新的负样本, 对新的负样本进行二次训练, 实现难例的处理. 
    注: 训练和测试数据集见附录, 结果见附件.

    2.模型及结果优缺点分析

    (1)此HOG + SVM进行行人检测的模型的分辨特征有以下几个: 
    1. 对于特征明显行人分辨能力强. 
    2. 目标单一时分辨能力强. 
    3. 干扰较少时分辨能力强. 
    (2)不足: 
    对于人群较多的图片和人物特征不明显的图片分辨能力较差. 
    (3)对于不足的改进: 
    1. 使用更多的样本进行训练. 
    2. 对于分辨错误的难例进行二次训练.

    3.模型建立中发现的问题及改进方法

    在进行HOG + SVM进行行人检测时, 时间消耗较长.对于训练的2416个正样本和12180个负样本进行两次训练共使用了595.919秒. 
    改进方法可以是进行CPU 并行优化, 可以分为三个线程, 确保每一个CPU核心都是满载. 
    1. 图像的预处理. 
    2. 提取HOG特征. 
    3. 使用SVM训练.

    4.行人检测OpenCv 代码(C++)

    1.ToolS类(处理负样本图片,把每张负样本随机裁剪十张没有人的图片并转换成jpg格式)
    #include "opencv2/core/core.hpp"    
    #include "opencv2/objdetect.hpp"  
    #include "opencv2/core/cuda.hpp"  
    #include "opencv2/highgui/highgui.hpp"    
    #include "opencv2/imgproc/imgproc.hpp"    
    #include "opencv2/video/video.hpp"    
    #include "opencv2/ml.hpp"  
    #include "opencv2/opencv.hpp"  
    #include <opencv2/objdetect/objdetect.hpp>    
    #include <opencv2/imgcodecs.hpp>  
    #include <stdlib.h>  
    #include <time.h>  
    #include <algorithm>  
    #include <math.h>  
    #include <iostream>    
    #include <vector>  
    #include <fstream>  
    #include <cstdlib>
    using namespace std;
    using namespace cv;
    using namespace cv::ml;
    
    class Tools
    {
    public:
    	Tools();
    	int CropImageCount = 0; //裁剪出来的负样本图片个数    
    	void ImgCut()
    	{
    		Mat src;
    		string ImgName;
    
    		char saveName[256];//裁剪出来的负样本图片文件名    
    		ifstream fin("E:\\INRIAPerson\\Train\\neg.lst");//打开原始负样本图片文件列表    
    
    														//一行一行读取文件列表    
    		while (getline(fin, ImgName))
    		{
    			cout << "处理:" << ImgName << endl;
    			ImgName = "E:\\INRIAPerson\\" + ImgName;
    
    			src = imread(ImgName, 1);//读取图片    
    									 //cout<<"宽:"<<src.cols<<",高:"<<src.rows<<endl;    
    									 //图片大小应该能能至少包含一个64*128的窗口    
    			if (src.cols >= 64 && src.rows >= 128)
    			{
    				srand(time(NULL));//设置随机数种子  time(NULL)表示当前系统时间  
    
    								  //从每张图片中随机采样10个64*128大小的不包含人的负样本    
    				for (int i = 0; i<10; i++)
    				{
    					int x = (rand() % (src.cols - 64)); //左上角x坐标    
    					int y = (rand() % (src.rows - 128)); //左上角y坐标    
    														 //cout<<x<<","<<y<<endl;    
    					Mat imgROI = src(Rect(x, y, 64, 128));
    					sprintf_s(saveName, "E:\\INRIAPerson\\negphoto\\noperson%06d.jpg", ++CropImageCount);//生成裁剪出的负样本图片的文件名    
    					imwrite(saveName, imgROI);//保存文件    
    				}
    			}
    		}
    	}
    	~Tools();
    };
    
    
    2._Pedestrian类(行人检测)
    主要包括以下函数:
    (1) 取得SVM分类器
    void get_svm_detector(const Ptr< SVM >& svm, vector< float > & hog_detector)
    (2) 转化OpenCv机器学习算法所使用的训练和样本集
    void convert_to_ml(const vector< Mat > & train_samples, Mat& trainData)
    (3) 载入目录的图片样本
    void load_images(const String &namefile,const String & dirname, vector< Mat > & img_lst, bool showImages = false)
    (4) 计算HOG特征
    void computeHOGs(const Size wsize, const vector< Mat > & img_lst, vector< Mat > & gradient_lst)
    (5) 测试已经训练的分类器
    int test_trained_detector(String obj_det_filename, String test_dir, String test_name_file,String videofilename)
    #include "opencv2/core/core.hpp"    
    #include "opencv2/objdetect.hpp"  
    #include "opencv2/core/cuda.hpp"  
    #include "opencv2/highgui/highgui.hpp"    
    #include "opencv2/imgproc/imgproc.hpp"    
    #include "opencv2/video/video.hpp"    
    #include "opencv2/ml.hpp"  
    #include "opencv2/opencv.hpp"  
    #include <opencv2/objdetect/objdetect.hpp>    
    #include <opencv2/imgcodecs.hpp>  
    #include <stdlib.h>  
    #include <time.h>  
    #include <algorithm>  
    #include <math.h>  
    #include <iostream>    
    #include <vector>  
    #include <fstream>  
    #include <cstdlib>
    
    
    using namespace std;
    using namespace cv;
    using namespace cv::ml;
    class _Pedestrain
    {
    public:
    	_Pedestrain();
    	//函数声明  
    	void get_svm_detector(const Ptr< SVM >& svm, vector< float > & hog_detector)
    	{
    		// get the support vectors  
    		Mat sv = svm->getSupportVectors();
    		const int sv_total = sv.rows;
    		// get the decision function  
    		Mat alpha, svidx;
    		double rho = svm->getDecisionFunction(0, alpha, svidx);
    
    		CV_Assert(alpha.total() == 1 && svidx.total() == 1 && sv_total == 1);   //括号中的条件不满足时,返回错误  
    		CV_Assert((alpha.type() == CV_64F && alpha.at<double>(0) == 1.) ||
    			(alpha.type() == CV_32F && alpha.at<float>(0) == 1.f));
    		CV_Assert(sv.type() == CV_32F);
    		hog_detector.clear();
    
    		hog_detector.resize(sv.cols + 1);
    		memcpy(&hog_detector[0], sv.ptr(), sv.cols * sizeof(hog_detector[0]));  //memcpy指的是c和c++使用的内存拷贝函数,memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。  
    		hog_detector[sv.cols] = (float)-rho;
    	}
    
    	/*
    	* Convert training/testing set to be used by OpenCV Machine Learning algorithms.
    	* TrainData is a matrix of size (#samples x max(#cols,#rows) per samples), in 32FC1.
    	* Transposition of samples are made if needed.
    	*/
    	void convert_to_ml(const vector< Mat > & train_samples, Mat& trainData)
    	{
    		//--Convert data  
    		const int rows = (int)train_samples.size(); //行数等于训练样本个数  
    		const int cols = (int)std::max(train_samples[0].cols, train_samples[0].rows);   //列数取样本图片中宽度与高度中较大的那一个  
    		Mat tmp(1, cols, CV_32FC1); //< used for transposition if needed  
    		trainData = Mat(rows, cols, CV_32FC1);
    
    		for (size_t i = 0; i < train_samples.size(); ++i)
    		{
    			CV_Assert(train_samples[i].cols == 1 || train_samples[i].rows == 1);
    
    			if (train_samples[i].cols == 1)
    			{
    				transpose(train_samples[i], tmp);
    				tmp.copyTo(trainData.row((int)i));
    			}
    			else if (train_samples[i].rows == 1)
    			{
    				train_samples[i].copyTo(trainData.row((int)i));
    			}
    		}
    	}
    
    	void load_images(const String &namefile,const String & dirname, vector< Mat > & img_lst, bool showImages = false)
    	{   //载入目录下的图片样本  
    		/*vector< String > files;
    		glob(dirname, files);       //返回一个包含有匹配文件/目录的数组。出错则返回false  
    
    		for (size_t i = 0; i < files.size(); ++i)
    		{
    			Mat img = imread(files[i]); // load the image  
    			if (img.empty())            // invalid image, skip it.  
    			{
    				cout << files[i] << " is invalid!" << endl;
    				continue;
    			}
    
    			if (showImages)
    			{
    				imshow("image", img);
    				waitKey(1);
    			}
    			img_lst.push_back(img);//将Img压入img_lst  
    		}*/
    
    		
    		string ImgName;
    		ifstream fin(namefile);//打开原始负样本图片文件列表    
    		//一行一行读取文件列表    
    		while (getline(fin, ImgName))
    		{
    			ImgName = dirname + "\\" + ImgName;
    			Mat src = imread(ImgName);//读取图片
    			img_lst.push_back(src);//将Img压入img_lst
    		}
    	}
    	void sample_neg(const vector< Mat > & full_neg_lst, vector< Mat > & neg_lst, const Size & size)
    	{   //该函数对每一个负样本采样出一个随机的64*128尺寸的样本,由于之前已经采样过了,所以main函数中没有使用该函数  
    		Rect box;
    		box.width = size.width; //等于检测器宽度  
    		box.height = size.height;   //等于检测器高度  
    
    		const int size_x = box.width;
    		const int size_y = box.height;
    
    		srand((unsigned int)time(NULL));        //生成随机数种子  
    
    		for (size_t i = 0; i < full_neg_lst.size(); i++)
    		{   //对每个负样本进行裁剪,随机指定x,y,裁剪一个尺寸为检测器大小的负样本  
    			box.x = rand() % (full_neg_lst[i].cols - size_x);
    			box.y = rand() % (full_neg_lst[i].rows - size_y);
    			Mat roi = full_neg_lst[i](box);
    			neg_lst.push_back(roi.clone());
    		}
    	}
    
    	void computeHOGs(const Size wsize, const vector< Mat > & img_lst, vector< Mat > & gradient_lst)
    	{   //计算HOG特征  
    		HOGDescriptor hog;
    		hog.winSize = wsize;
    
    		Rect r = Rect(0, 0, wsize.width, wsize.height);
    		r.x += (img_lst[0].cols - r.width) / 2; //正样本图片的尺寸减去检测器的尺寸,再除以2  
    		r.y += (img_lst[0].rows - r.height) / 2;
    
    		Mat gray;
    		vector< float > descriptors;
    
    		for (size_t i = 0; i< img_lst.size(); i++)
    		{
    			cvtColor(img_lst[i](r), gray, COLOR_BGR2GRAY);
    			hog.compute(gray, descriptors, Size(8, 8), Size(0, 0)); //Size(8,8)为窗口移动步长,  
    			gradient_lst.push_back(Mat(descriptors).clone());
    		}
    	}
    
    	int test_trained_detector(String obj_det_filename, String test_dir, String test_name_file,String videofilename)
    	{   //当videofilename为空,则只检测图片中的行人  
    		cout << "Testing trained detector..." << endl;
    		HOGDescriptor hog;
    		hog.load(obj_det_filename);
    
    		//vector< String > files;
    		//glob(test_dir, files);
    
    		int delay = 0;
    		VideoCapture cap;
    
    		if (videofilename != "")
    		{
    			cap.open(videofilename);
    		}
    
    		obj_det_filename = "testing " + obj_det_filename;
    		namedWindow(obj_det_filename, WINDOW_NORMAL);
    
    		/*for (size_t i = 0;; i++)
    		{
    			Mat img;
    
    			if (cap.isOpened())
    			{
    				cap >> img;
    				delay = 1;
    			}
    			else if (i < files.size())
    			{
    				img = imread(files[i]);
    			}
    			if (img.empty())
    			{
    				return 0;
    			}
    
    			vector< Rect > detections;
    			vector< double > foundWeights;
    
    			hog.detectMultiScale(img, detections, foundWeights);
    			for (size_t j = 0; j < detections.size(); j++)
    			{
    				if (foundWeights[j] < 0.5) continue; //清楚权值较小的检测窗口  
    				Scalar color = Scalar(0, foundWeights[j] * foundWeights[j] * 200, 0);
    				rectangle(img, detections[j], color, img.cols / 400 + 1);
    			}
    
    			imshow(obj_det_filename, img);
    
    			if (27 == waitKey(delay))
    			{
    				return 0;
    			}
    		}*/
    		Mat img;
    		string ImgName;
    		ifstream fin(test_name_file);//打开原始负样本图片文件列表    
    									 //一行一行读取文件列表    
    		while (getline(fin, ImgName))
    		{
    			ImgName = test_dir + "\\" + ImgName;
    			img = imread(ImgName);//读取图片
    			vector< Rect > detections;
    			vector< double > foundWeights;
    
    			hog.detectMultiScale(img, detections, foundWeights);
    			for (size_t j = 0; j < detections.size(); j++)
    			{
    				if (foundWeights[j] < 0.5) continue; //清楚权值较小的检测窗口  
    				Scalar color = Scalar(0, foundWeights[j] * foundWeights[j] * 200, 0);
    				rectangle(img, detections[j], color, img.cols / 400 + 1);
    			}
    
    			imshow(obj_det_filename, img);
    
    			if (27 == waitKey(delay))
    			{
    				return 0;
    			}
    		}
    		return 0;
    	}
    	int trainAndTest(int argc, char** argv, const char* keys)
    	{
    		CommandLineParser parser(argc, argv, keys); //命令行函数,读取keys中的字符, 其中key的格式为:名字 简称| 内容 |提示字符。  
    
    		if (parser.has("help"))
    		{
    			parser.printMessage();
    			exit(0);
    		}
    
    		String pos_dir = parser.get< String >("pd");  //正样本目录 
    		String pos_name_file = parser.get< String >("pdlst"); //正样本文件名列表
    		String neg_dir = parser.get< String >("nd");  //负样本目录  
    		String neg_name_file = parser.get< String >("ndlst");  //负样本文件名列表
    		String test_dir = parser.get< String >("td"); //测试样本目录  
    		String test_name_file = parser.get< String >("tdlst"); //测试样本文件列表 
    		String obj_det_filename = parser.get< String >("fn"); //训练好的SVM检测器文件名  
    		String videofilename = parser.get< String >("tv");    //测试视频  
    		int detector_width = parser.get< int >("dw"); //检测器宽度   
    		int detector_height = parser.get< int >("dh");    //检测器高度  
    		bool test_detector = parser.get< bool >("t"); //测试训练好的检测器  
    		bool train_twice = parser.get< bool >("d");       //训练两次  
    		bool visualization = parser.get< bool >("v"); //训练过程可视化(建议false,不然爆炸)  
    
    		if (test_detector)  //若为true,测对测试集进行测试  
    		{
    			test_trained_detector(obj_det_filename, test_dir, test_name_file, videofilename);
    			exit(0);
    		}
    
    		if (pos_dir.empty() || neg_dir.empty()) //检测非空  
    		{
    			parser.printMessage();
    			cout << "Wrong number of parameters.\n\n"
    				<< "Example command line:\n" << argv[0] << " -pd=/INRIAPerson/96X160H96/Train/pos -nd=/INRIAPerson/neg -td=/INRIAPerson/Test/pos -fn=HOGpedestrian96x160.xml -d\n"
    				<< "\nExample command line for testing trained detector:\n" << argv[0] << " -t -dw=96 -dh=160 -fn=HOGpedestrian96x160.xml -td=/INRIAPerson/Test/pos";
    			exit(1);
    		}
    
    		vector< Mat > pos_lst,      //正样本图片向量  
    			full_neg_lst,           //负样本图片向量  
    			neg_lst,                //采样后的负样本图片向量  
    			gradient_lst;           //HOG描述符存入到该梯度信息里面  
    		vector< int > labels;       //标签向量  
    
    		clog << "Positive images are being loaded...";
    		load_images(pos_name_file,pos_dir, pos_lst, visualization);   //加载图片 pos正样本的尺寸为96*160  
    		if (pos_lst.size() > 0)
    		{
    			clog << "...[done]" << endl;
    		}
    		else
    		{
    			clog << "no image in " << pos_dir << endl;
    			return 1;
    		}
    
    		Size pos_image_size = pos_lst[0].size(); //令尺寸变量pos_image_size=正样本尺寸  
    		cout << "pis = " << pos_image_size << endl;
    		//检测所有正样本是否具有相同尺寸  
    		/*for (size_t i = 0; i < pos_lst.size(); ++i)
    		{
    			if (pos_lst[i].size() != pos_image_size)
    			{
    				cout << "All positive images should be same size!" << endl;
    				exit(1);
    			}
    		}*/
    
    		pos_image_size = pos_image_size / 8 * 8;
    
    		//令pos_image_size的尺寸为检测器的尺寸  
    		if (detector_width && detector_height)
    		{
    			pos_image_size = Size(detector_width, detector_height);
    		}
    
    		labels.assign(pos_lst.size(), +1);              //assign()为labels分配pos_lst.size()大小的容器,用+1填充 表示为正样本  
    		const unsigned int old = (unsigned int)labels.size();   //旧标签大小  
    
    		clog << "Negative images are being loaded...";
    		load_images(neg_name_file,neg_dir, neg_lst, false);   //加载负样本图片  
    												//sample_neg(full_neg_lst, neg_lst, pos_image_size);    
    		clog << "...[done]" << endl;
    
    		labels.insert(labels.end(), neg_lst.size(), -1);    //在labels向量的尾部添加neg_lst.size()大小的容器,用-1填充 表示为负样本  
    		CV_Assert(old < labels.size());      //CV_Assert()作用:CV_Assert()若括号中的表达式值为false,则返回一个错误信息。  
    
    		clog << "Histogram of Gradients are being calculated for positive images...";
    		computeHOGs(pos_image_size, pos_lst, gradient_lst); //计算正样本图片的HOG特征  
    		clog << "...[done]" << endl;
    
    		clog << "Histogram of Gradients are being calculated for negative images...";
    		computeHOGs(pos_image_size, neg_lst, gradient_lst); //计算负样本图片的HOG特征  
    		clog << "...[done]" << endl;
    
    		Mat train_data;
    		convert_to_ml(gradient_lst, train_data);    //转化为ml所需的训练数据形式  
    
    		clog << "Training SVM...";
    		Ptr< SVM > svm = SVM::create();
    		/* Default values to train SVM */
    		svm->setCoef0(0.0);
    		svm->setDegree(3);
    		svm->setTermCriteria(TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 1000, 1e-3));
    		svm->setGamma(0);
    		svm->setKernel(SVM::LINEAR); //采用线性核函,其他的sigmoid 和RBF 可自行设置,其值由0-5。  
    		svm->setNu(0.5);
    		svm->setP(0.1); // for EPSILON_SVR, epsilon in loss function?  
    		svm->setC(0.01); // From paper, soft classifier  
    		svm->setType(SVM::EPS_SVR); // C_SVC; // EPSILON_SVR; // may be also NU_SVR; // do regression task  
    		svm->train(train_data, ROW_SAMPLE, Mat(labels));
    		clog << "...[done]" << endl;
    
    		//训练两次  
    		if (train_twice)
    		{
    			clog << "Testing trained detector on negative images. This may take a few minutes...";
    			HOGDescriptor my_hog;
    			my_hog.winSize = pos_image_size;
    
    			// Set the trained svm to my_hog  
    			vector< float > hog_detector;
    			get_svm_detector(svm, hog_detector);
    			my_hog.setSVMDetector(hog_detector);
    
    			vector< Rect > detections;
    			vector< double > foundWeights;
    
    			for (size_t i = 0; i < full_neg_lst.size(); i++)
    			{
    				my_hog.detectMultiScale(full_neg_lst[i], detections, foundWeights);
    				for (size_t j = 0; j < detections.size(); j++)
    				{
    					Mat detection = full_neg_lst[i](detections[j]).clone();
    					resize(detection, detection, pos_image_size);
    					neg_lst.push_back(detection);
    				}
    				if (visualization)
    				{
    					for (size_t j = 0; j < detections.size(); j++)
    					{
    						rectangle(full_neg_lst[i], detections[j], Scalar(0, 255, 0), 2);
    					}
    					imshow("testing trained detector on negative images", full_neg_lst[i]);
    					waitKey(5);
    				}
    			}
    			clog << "...[done]" << endl;
    
    			labels.clear();
    			labels.assign(pos_lst.size(), +1);
    			labels.insert(labels.end(), neg_lst.size(), -1);
    
    			gradient_lst.clear();
    			clog << "Histogram of Gradients are being calculated for positive images...";
    			computeHOGs(pos_image_size, pos_lst, gradient_lst);
    			clog << "...[done]" << endl;
    
    			clog << "Histogram of Gradients are being calculated for negative images...";
    			computeHOGs(pos_image_size, neg_lst, gradient_lst);
    			clog << "...[done]" << endl;
    
    			clog << "Training SVM again...";
    			convert_to_ml(gradient_lst, train_data);
    			svm->train(train_data, ROW_SAMPLE, Mat(labels));
    			clog << "...[done]" << endl;
    		}
    
    		//-------------------------------------------------------------------
    		vector< float > hog_detector; //定义hog检测器  
    		get_svm_detector(svm, hog_detector);    //得到训练好的检测器  
    		HOGDescriptor hog;
    		hog.winSize = pos_image_size;   //窗口大小  
    		hog.setSVMDetector(hog_detector);
    		hog.save(obj_det_filename);     //保存分类器  
    
    		test_trained_detector(obj_det_filename, test_dir, test_name_file, videofilename);   //检测训练集  
    
    		return 0;
    	}
    
    	~_Pedestrain();
    };
    3.主类
    #include "Tools.h"
    #include "_Pedestrain.h"
    using namespace std;
    using namespace cv;
    using namespace cv::ml;
    
    //vedio_dir |  J:\\Download\\SEQ\\set01\\V003.seq
    const char* keys =
    {
    	"{help h|     | show help message}"
    	"{pd    |  E:\\INRIAPerson\\96X160H96\\Train\\pos       | path of directory contains possitive images}"
    	"{pdlst |  E:\\INRIAPerson\\96X160H96\\Train\\pos.lst   |  possitive images name }"
    	"{nd    |  E:\\INRIAPerson\\negphoto       | path of directory contains negative images}"
    	"{ndlst |  E:\\INRIAPerson\\negphoto.lst   |  negative images name }"
    	"{td    |  E:\\INRIAPerson\\Test\\pos        | path of directory contains test images}"
    	"{tdlst |  E:\\INRIAPerson\\Test\\pos\\pos.lst    | test images name }"
    	"{tv    |    | test video file name}"
    	"{dw    |  64   | width of the detector}"
    	"{dh    |  128   | height of the detector}"
    	"{d     |true| train twice}"
    	"{t     |false| test a trained detector}"
    	"{v     |false| visualize training steps}"
    	"{fn    |E:\\Pedestrain.xml| file name of trained SVM}"
    };
    
    string obj_det_filename = "E:\\Pedestrain.xml";
    string test_dir = "E:\\INRIAPerson\\Test\\pos";
    string vediofilename = "";
    
    int main(int argc, char** argv)
    {
    	//数据预处理
    	Tools tool;
    	tool.ImgCut();
    	cout << tool.CropImageCount << endl;
    
    
    	//训练并测试数据
    	_Pedestrain pt;
    	pt.trainAndTest(argc, argv, keys);
    
    	//测试数据
    	//pt.test_trained_detector(obj_det_filename, test_dir, vediofilename);
    	return 0;
    }

    5.训练训练结果

     

    6.注意事项

    1.训练集图片最好采用jpg格式,png格式会报错,需要使用png格式可以自行引入zlib,libpng库,或者是用格式工厂把png转换成jpg.

    2.代码中的图片路径自己对应

    3.项目要配置opencv库

     

    参考文章:https://blog.csdn.net/qq_37753409/article/details/79047063

    INRIAPerson训练集下载:ftp://ftp.inrialpes.fr/pub/lear/douze/data/INRIAPerson.tar

    展开全文
  • 深度学习实践经验:用Faster R-CNN训练行人检测数据Caltech——准备工作原创 2017年02月18日 21:16:35标签:深度学习/FasterRCNN/经验前言Faster R-CNN是Ross Girshick大神在Fast R-CNN基础上提出的又一个更加快速...
  • 使用YOLOv3 训练行人检测模型

    万次阅读 热门讨论 2018-04-22 14:32:29
    使用YOLO进行目标检测在保证速度的前提下能有较好的准确性,这篇文章是在yolov3的代码基础上进行修改为行人检测,由原来的20个分类改为识别person,使用tiny-yolo的进行训练和检测,最后能达到还不错的效果。...
  • 行人检测——Caltech Pedestrian Dataset 数据的使用

    万次阅读 多人点赞 2015-05-20 18:06:20
    行人检测数据Caltech Pedestrian Dataset 的使用方法
  • 自己训练SVM分类器进行HOG行人检测

    千次下载 热门讨论 2013-11-13 22:25:40
    自己训练SVM分类器进行HOG行人检测. 环境为VS2010 + OpenCV2.4.4. 使用时请自行修改工程的include目录和lib目录配置。 正样本来源是INRIA数据集中的96*160大小的人体图片,使用时上下左右都去掉16个像素,截取中间的...
  • 数据由两组序列组成。 这些序列称为昼夜设置,这... 用于白天训练3695张图像,夜间训练3390张图像,每个序列带有大约1500条强制行人注释。 用于测试两个序列的约700张图像,白天约有2000名行人,晚上约有1500名行人
  • 行人检测0-00:LFFD-史上最新无死角详细解读:https://blog.csdn.net/weixin_43013761/article/details/102592374 数据准备 我这里要讲解的是行人数据的制作,怎么制作呢?我们先根据作者的流程走一遍,后面我们就...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,239
精华内容 3,295
关键字:

行人检测训练集