用OpenCV制作一个简易的行人检测器

这件事的背景大概就是室友的MacBook被偷了,恰好在我们寝选择不爆肝的那个晚上。现在手里有监控视频,另一个室友就提议说干脆写一个行人检测好了,我想了想,过了一会试着写了一个出来。

好的回到话题中,怎么样才能写出一个简单的行人检测工具呢?

其实OpenCV是自带了行人检测模型的,如果比较懒的话可以直接调用,本文就是基于这个实现的,核心代码很短。

首先你要有一个视频流,在OpenCV里可以用VideoCapture这个类实现,接数字是从摄像头读入视频流,接文件地址则是从视频文件中读入。

然后,你要有一个执行目标检测方法的类,这个类OpenCV也实现好了,HOGDescriptor。

调用方法就是先声明然后再设置Detector,例如在本次实验中我们要设置一个含有行人检测模型的SVM Detector。

然后就到了标准的逐帧读入环节了,每次读入一帧,交给Detector去找出所有Bounding Box,然后绘制在那一帧上,最后显示出来。

贴一下代码好了。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/ml/ml.hpp>
using namespace cv;
using namespace std;
int main(int argc, const char * argv[]) {
    Mat image;
    namedWindow("People Detection");
    string path = "/Users/DongSky/Downloads/002McDssjx070NDPGeXe05040101mgn00k01.mp4";
    VideoCapture vc = VideoCapture(path);
    double rate = vc.get(CV_CAP_PROP_FPS);
    int delay = 1000 / rate;
    HOGDescriptor hog;
    hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
    while(true){
        if(!vc.read(image))break;
        vector<Rect> found, found_filtered;
        hog.detectMultiScale(image, found, 0, Size(8,8), Size(32,32), 1.05, 2);
        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);
        }
        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(image, r.tl(), r.br(), Scalar(0, 255, 0), 3);
        }
        imshow("detect", image);
        if(waitKey(delay) >= 0)break;
    }
    return 0;
}

2条评论

发表评论

电子邮件地址不会被公开。