HOG+SVM静态图像检测并制作视频

1,原理

就是把一张张连续的静态视频进行检测后,写入videos中。

2,代码

//
// Created by MacBook Pro on 2019-06-10.
//


#include <stdio.h>
#include <iostream>
#include <fstream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>

using namespace std;
using namespace cv;
using namespace cv::ml;

//定义HOGxml文件
#define SvmLisrFile "/Users/macbookpro/CLionProjects/pedestrian_detection/data/SVM_HOG_1.xml"
//定义读入图片的文件名
#define ImgListFile "/Users/macbookpro/CLionProjects/pedestrian_detection/img_dir/seq.txt"
//存储的视频路径以及视频名称
#define VideoFile "/Users/macbookpro/CLionProjects/pedestrian_detection/data/Seq8.avi"
//读入图片所在的路径
#define ImgFile "/Users/macbookpro/CLionProjects/pedestrian_detection/normalized_images/seq4/"

int main() {
    Mat src;
    string ImgName;//图片文件名
    //ifstream fin("Seq4List.txt");//打开图片序列的文件列表
    ifstream fin(ImgListFile);

    namedWindow("ImageSeq", 0);

    VideoWriter videoWriter;//视频写入器
    videoWriter.open(VideoFile, CAP_OPENCV_MJPEG, 25, Size(1292, 964));//注意若图片尺寸与写入器的尺寸不同的话可能失败
    if (!videoWriter.isOpened()) cout << "创建VideoWriter失败" << endl;

//    HOGDescriptor people_detect_hog; //HOG特征检测器
//    //采用默认的已经训练好了的SVM系数作为检测的模型
//    people_detect_hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    HOGDescriptor hog(Size(64,128),Size(16,16),Size(8,8),Size(8,8),9);
//    int DescriptorDim;//HOG描述子的维数,由图片大小、检测窗口大小、块大小、细胞单元中直方图bin个数决定
    Ptr<SVM> svm = SVM::create();// 创建分类器

    svm = SVM::load(SvmLisrFile);

    int svdim = svm ->getVarCount();//特征向量的维数,即HOG描述子的维数
    //支持向量的个数
    Mat svecsmat = svm ->getSupportVectors();//svecsmat元素的数据类型为float
    int numofsv = svecsmat.rows;

    // Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);//alphamat和svindex必须初始化,否则getDecisionFunction()函数会报错
    Mat alphamat = Mat::zeros(numofsv, svdim, CV_32F);
    Mat svindex = Mat::zeros(1, numofsv,CV_64F);
    cout << "after initialize the value of alphamat is  " << alphamat.size()  << endl;

    Mat Result;
    double rho = svm ->getDecisionFunction(0, alphamat, svindex);

//    cout << "the value of rho is  " << rho << endl;
    alphamat.convertTo(alphamat, CV_32F);//将alphamat元素的数据类型重新转成CV_32F
//    cout << "the value of alphamat is  " << alphamat << endl;
//    cout << "the size of alphamat is  " << alphamat.size() << endl;
//    cout << "the size of svecsmat is  " << svecsmat.size() << endl;

    //计算-(alphaMat * supportVectorMat),结果放到resultMat中
    Result = -1 * alphamat * svecsmat;//float

//    cout << "the value of svdim is  " << svdim << endl;

    //得到最终的setSVMDetector(const vector<float>& detector)参数中可用的检测子
    vector<float> vec;
    //将resultMat中的数据复制到数组vec中
    for (int i = 0; i < svdim; ++i)
    {
        vec.push_back(Result.at<float>(0, i));
    }
    vec.push_back(rho);

    HOGDescriptor hog_test;
    hog_test.setSVMDetector(vec);


    while (getline(fin, ImgName)) {
        cout << "处理:" << ImgName << endl;
        string fullName = ImgFile + ImgName;//加上路径名,"\\"表示转义字符"\"
        src = imread(fullName);

        vector<Rect> found, found_filtered; //矩形框数组
        //对输入的图片进行多尺度行人检测,检测窗口移动步长为(8,8)
        hog_test.detectMultiScale(src, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);
        //找出所有没有嵌套的矩形框r,并放入found_filtered中,如果有嵌套的话,则取外面最大的那个矩形框放入found_filtered中
        for (int i = 0; i < found.size(); i++) {
            Rect r = found[i];
            int j = 0;
            for (; j < found.size(); j++)
                if (j != i && (r & found[j]) == r)
                    break;
            if (j == found.size())
                found_filtered.push_back(r);
        }

        //画矩形框,因为hog检测出的矩形框比实际人体框要稍微大些,所以这里需要做一些调整
        for (int i = 0; i < found_filtered.size(); i++) {
            Rect r = found_filtered[i];
            r.x += cvRound(r.width * 0.1);
            r.width = cvRound(r.width * 0.8);
            r.y += cvRound(r.height * 0.07);
            r.height = cvRound(r.height * 0.8);
            rectangle(src, r.tl(), r.br(), Scalar(0, 255, 0), 3);
        }

        videoWriter << src;//写入一帧到文件

        imshow("ImageSeq", src);
        waitKey(50);//注意:imshow之后必须有waitKey(),否则无法显示图像
    }

    videoWriter.release();
    //system("pause");
    return 0;
}

3,效果

4、视频源文件

附带检测图片以及SVM的xml文件

链接: https://pan.baidu.com/s/1RTi_j-5omh8VCojZwrbAgw  密码: ppuf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星蓝雨

如果觉得文章不错,可以请喝咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值