QT5+OpenCV团块运动检测&行人检测

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

void detect(Mat mask,Mat img)
{
   SimpleBlobDetector::Params params;

   params.minThreshold = 20;//二值化的起始阈值
   params.maxThreshold = 180;//二值化的终止阈值
   params.thresholdStep = 10;//二值化的阈值步长

   params.minConvexity = 0.5f;//斑点的最小凸度 默认0.95f
   params.minInertiaRatio = 0.03f;//斑点的最小惯性率 默认0.1f
   params.minArea = 120;//斑点的最小面积
   params.maxArea = 5000;//斑点的最大面积
   params.blobColor = 255;//检测白色

//   重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点
//   params.minRepeatability = 2;
//   最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点
//   params.minDistBetweenBlobs = 10;

   Ptr detector = SimpleBlobDetector::create(params);

   vector key_points;

   detector->detect(mask,key_points);

   Mat output_img;

   drawKeypoints( img, key_points, output_img, Scalar(0,0,255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS );

   imshow("SimpleBlobDetector", output_img);
}

int main()
{
    string file = "test.avi";
    string method = "mog2";    //knn or mog2
    VideoCapture cap;

    cap.open(file.c_str());

    if( !cap.isOpened() )
    {
        printf("can not open camera or video file\n");
        return -1;
    }

    namedWindow("image", WINDOW_NORMAL);
    namedWindow("foreground mask", WINDOW_NORMAL);
    namedWindow("SimpleBlobDetector");

    Ptr bg_model = method == "knn" ?
            createBackgroundSubtractorKNN().dynamicCast() :
            createBackgroundSubtractorMOG2().dynamicCast();

    Mat img0, img, fgmask, fgimg;

    for(;;)
    {
        cap >> img0;
        if( img0.empty() )
            break;

        resize(img0, img, Size(600, 600*img0.rows/img0.cols), INTER_LINEAR);

        if( fgimg.empty() )
          fgimg.create(img.size(), img.type());

        //更新模型
        bg_model->apply(img, fgmask,-1);

        // 腐蚀
        erode(fgmask, fgmask, Mat());
        // 膨胀
        dilate(fgmask, fgmask, Mat());

        fgimg = Scalar::all(0);
        img.copyTo(fgimg, fgmask);

        Mat bgimg;
        bg_model->getBackgroundImage(bgimg);

        imshow("image", img);
        detect(fgmask,img);
        imshow("foreground mask", fgmask);

        char k = (char)waitKey(25);
        if( k == 27 ) break;
    }
    return 0;
}


效果如图QT5+OpenCV团块运动检测&行人检测_第1张图片


参考:
OpenCV运动检测跟踪(blob track)框架组成模块详解

Opencv2.4.9源码分析——SimpleBlobDetector




PS:行人检测

#include 
#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
    Mat img;
    VideoCapture videoCap;
    vector found, foundRect;
    namedWindow("peopledetect", CV_WINDOW_AUTOSIZE);

    HOGDescriptor defaultHog;
    //1.设置SVM,默认的可能不一定适用于各种场所,可自行根据场景训练以提高准确率
    defaultHog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());

    //读取图片
    //img = imread("D://people.png");
    //if(!img.data){
        //cout<<"has no picture"<>img;
        if(img.empty())
            return 0;
        //2.调整图像大小,越大检测越慢准确率越高,可自行调整
        cv::resize(img, img, Size(768, 768*img.rows/img.cols), INTER_LINEAR);


        double duration = static_cast(getTickCount());

        //3.对输入的图片img进行多尺度行人检测,可自行调节参数
        //img为输入待检测的图片;found为检测到目标区域列表;参数3为程序内部计算为行人目标的阈值,也就是检测到的特征到SVM分类超平面的距离;
        //参数4为滑动窗口每次移动的距离。它必须是块移动的整数倍;参数5为图像扩充的大小;参数6为比例系数,即测试图片每次尺寸缩放增加的比例;
        //参数7为组阈值,即校正系数,当一个目标被多个窗口检测出来时,该参数此时就起了调节作用,为0时表示不起调节作用。
        defaultHog.detectMultiScale(img, found, 0, Size(8, 8), Size(32, 32), 1.05, 2);

        duration = static_cast(getTickCount()) - duration;
        duration /= getTickFrequency();
        cout <<"运行时间为:" << duration << 's' << endl;

        //遍历found寻找有没有被嵌套的长方形
        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()){
                foundRect.push_back(r);
            }
        }

        //画长方形,圈出行人
        for(int i = 0; i < foundRect.size(); i++){
            Rect r = foundRect[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(img, r.tl(), r.br(), Scalar(0, 0, 255), 3);
        }
        foundRect.clear();

        imshow("peopledetect", img);

        waitKey(50);
    }

    return 0;
}

你可能感兴趣的:(C/C++)