cvBlob 使用

注意事項

1)添加命名空間

using namespace cvb;

2)

//     unique_ptr<IplImage, void(*)(IplImage*)> labelImg(cvCreateImage(cvSize(width, height), IPL_DEPTH_LABEL, 1), 

//       [](IplImage* p){ cvReleaseImage(&p); });

錯誤

無法從“`anonymous-namespace'::<lambda0>”轉換爲“void (__cdecl *const )

暫時不使用C11的語言特性

3)

需要將使用的庫函數導出來,使用如下的宏定義:

__declspec(dllexport)


源碼

#include <SDKDDKVer.h>

#include <stdio.h>

#include <tchar.h>

#include<iostream>

#include "cv.h"

#include "cvblob.h"

#include "highgui.h"

#include<opencv2\opencv.hpp>

#include<opencv2\video\background_segm.hpp>


using namespace cv;

using namespace cvb;

using namespace std;


//對輪廓按面積降序排序,目的是去除那些小輪廓目標

bool descSort(vector<Point> p1, vector<Point> p2) {

  return contourArea(p1) > contourArea(p2);

}


void processVideo(char* videoFilename)

{

  Mat frame; // current frame

  Mat fgMaskMOG2; // fg mask fg mask generated by MOG2 method

  Mat bgImg; // background

  Ptr<BackgroundSubtractorMOG2> pMOG2 = createBackgroundSubtractorMOG2(200, 36.0, false); // MOG2 Background subtractor


  while (true)

  {

    VideoCapture capture(videoFilename);

    if (!capture.isOpened())

    {

      cerr << "Unable to open video file: " << videoFilename << endl;

      return;

    }


    int width = (int)capture.get(CV_CAP_PROP_FRAME_WIDTH);

    int height = (int)capture.get(CV_CAP_PROP_FRAME_HEIGHT);


//     unique_ptr<IplImage, void(*)(IplImage*)> labelImg(cvCreateImage(cvSize(width, height), IPL_DEPTH_LABEL, 1), 

//       [](IplImage* p){ cvReleaseImage(&p); });

    IplImage* labelImg = cvCreateImage(cvSize(width, height), IPL_DEPTH_LABEL, 1);

    CvBlobs blobs;

    CvTracks tracks;


    while (true)

    {

      // read input data. ESC or 'q' for quitting

      int key = waitKey(1);

      if (key == 'q' || key == 27)

        return;

      if (!capture.read(frame))

        break;


      // update background

      pMOG2->apply(frame, fgMaskMOG2);

      pMOG2->getBackgroundImage(bgImg);

      imshow("BG", bgImg);

      imshow("Original mask", fgMaskMOG2);


      // post process

      medianBlur(fgMaskMOG2, fgMaskMOG2, 5);

      imshow("medianBlur", fgMaskMOG2);

      morphologyEx(fgMaskMOG2, fgMaskMOG2, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(5, 5))); // fill black holes

      morphologyEx(fgMaskMOG2, fgMaskMOG2, MORPH_OPEN, getStructuringElement(MORPH_RECT, Size(5, 5))); // fill white holes

      imshow("morphologyEx", fgMaskMOG2);


      // track

      cvLabel(&IplImage(fgMaskMOG2), labelImg, blobs);

      cvFilterByArea(blobs, 64, 10000);

      cvUpdateTracks(blobs, tracks, 10, 90, 30);

      cvRenderTracks(tracks, &IplImage(frame), &IplImage(frame));


      // show

      imshow("Frame", frame);


      key = waitKey(30);

    }

  }

}




int main() {


  processVideo("E:/smoky-cars/positive/大慶東路與水機路交叉口(東北)_冀BU0157_02_141502_01_3_50.wh264");

  return 0;

  //讀入視頻

  VideoCapture capture("E:/smoky-cars/positive/大慶東路與水機路交叉口(東北)_冀BU0157_02_141502_01_3_50.wh264");

  //定義一個Mat變量,用於存儲每一幀的圖像

  Mat frame;

  //前景

  Mat mask;

  //連通分量

  Mat srcImage;

  //結果

  Mat result;


  //用混合高斯模型訓練背景圖像

  Ptr<BackgroundSubtractorMOG2> bgsubtractor = createBackgroundSubtractorMOG2();

  bgsubtractor->setVarThreshold(20);


  //for (int  k = 0; k < 100; k++)

  //{

  //    //讀取當前幀

  //    capture >> frame;

  //    //若視頻播放完成,退出循環

  //    if (frame.empty())

  //    {

  //        break;

  //    }

  //    bgsubtractor->apply(frame, mask, 0.2);

  //}

  //imshow("前景訓練結果", mask);


  //循環顯示每一幀

  while (true)

  {


    //讀取當前幀

    capture >> frame;

    //若視頻播放完成,退出循環

    if (frame.empty())

    {

      break;

    }

    frame.copyTo(result);

    //cvtColor(frame, frame, COLOR_GRAY2BGR);

    bgsubtractor->apply(frame, mask, 0.2);


    imshow("原視頻", frame);  //顯示當前幀

    //waitKey(30);  //延時30ms


    imshow("混合高斯建模", mask);

    //waitKey(30);


    //cvtColor(mask, mask, COLOR_GRAY2BGR);

    //對前景先進行中值濾波,再進行形態學膨脹操作,以去除僞目標和連接斷開的小目標

    medianBlur(mask, mask, 5);

    //morphologyEx(mask, mask, MORPH_DILATE, getStructuringElement(MORPH_RECT, Size(5, 5)));


    //測試:先開運算再閉運算

    morphologyEx(mask, mask, MORPH_CLOSE, getStructuringElement(MORPH_RECT, Size(5, 5)));

    morphologyEx(mask, mask, MORPH_OPEN, getStructuringElement(MORPH_RECT, Size(5, 5)));


    imshow("混合高斯建模", mask);

    waitKey(30);


    //拷貝

    mask.copyTo(srcImage);


    //各聯通分量的輪廓

    //外層vector的size代表了圖像中輪廓的個數,裏面vector的 size代表了輪廓上點的個數

    vector<vector<Point>> contours;

    //只獲取最外輪廓,獲取每個輪廓的每個像素,並相鄰兩個像素位置差不超過1

    findContours(srcImage, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);


    //測試輪廓獲取

    imshow("輪廓獲取", srcImage);


    if (contours.size() < 1) continue;

    //外接矩陣

    Rect rct;


    //對輪廓進行外接矩陣之前先對輪廓按面積降序排序,目的爲了去除小目標(僞目標)

    sort(contours.begin(), contours.end(), descSort);


    for (int i = 0; i < contours.size(); i++)

    {

      //當第i個連通分量的外接矩陣面積小於最大面積的1/6,則認爲是僞目標

      if (contourArea(contours[i]) < contourArea(contours[0]) / 5)

        break;

      //包含輪廓的最小矩陣

      rct = boundingRect(contours[i]);

      rectangle(result, rct, Scalar(0, 255, 0), 2);


    }

    imshow("結果", result);

  }

  getchar();

  return 0;

}


參考

http://blog.csdn.net/xfgryujk/article/details/61421763


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章