• opencv::将两幅图像合并后,在同一个窗口显示;并将合并的图像流保存成视频文件


    /**
     * @file main-opencv.cpp
     * @date July 2014 
     * @brief An exemplative main file for the use of ViBe and OpenCV
     */
    //#include <opencv2corecore.hpp>
    #include "vibe-background-sequential.h"
    
    using namespace cv;
    using namespace std;
    
    const int minArea = 2;    // 舍去面积极小的方框
    const double maxAreaRatio = 0.1;   // 舍去面积极大的方框
    const double boxRatio = 0.1;   // 舍去长宽比严重失衡的方框
    
    /**
     * Displays instructions on how to use this program.
     */
    void help()
    {
        cout
        << "--------------------------------------------------------------------------" << endl
        << "This program shows how to use ViBe with OpenCV                            " << endl
        << "Usage:"                                                                     << endl
        << "./main-opencv <video filename>"                                             << endl
        << "for example: ./main-opencv video.avi"                                       << endl
        << "--------------------------------------------------------------------------" << endl
        << endl;
    }
    
    void processVideo(char* videoFilename);
    
    void contour(const Mat &mor, Mat &img);
    
    
    /**
     * Main program. It shows how to use the grayscale version (C1R) and the RGB version (C3R). 
     */
    int main(int argc, char* argv[])
    {
      /* Print help information. */
      help();
    
      /* Check for the input parameter correctness. */
     /* if (argc != 2) {
        cerr <<"Incorrect input" << endl;
        cerr <<"exiting..." << endl;
        return EXIT_FAILURE;
      }
    
      /* Create GUI windows. */
      //namedWindow("Frame");
      //namedWindow("Segmentation by ViBe");
    
    processVideo("framelink_yd.avi");  //读取 framelink_yd.avi 视频进行处理
      /* Destroy GUI windows. */
      destroyAllWindows();
      return EXIT_SUCCESS;
    }
    
    /**
     * Processes the video. The code of ViBe is included here. 
     *
     * @param videoFilename  The name of the input video file. 
     */
    void processVideo(char* videoFilename)
    {
       VideoCapture capture(videoFilename);     /* Create the capture object. */
      if (!capture.isOpened()) {
        cerr << "Unable to open video file: " << videoFilename<< endl;    /* Error in opening the video input. */
        exit(EXIT_FAILURE);
      }
    
      clock_t start, finish;
      double total;
      start=clock();
    
      /* Variables. */
      static int frameNumber = 1;  /* The current frame number */
      int lastCount = 0; 
      int probFactor = gradient_Factor;   /*概率因子,用梯度因子初始化概率因子*/
      Mat frame,frame1;                  /* Current frame. */
      Mat segmentationMap;        /* Will contain the segmentation map. This is the binary output map. */
      int keyboard = 0;           /* Input from keyboard. Used to stop the program. Enter 'q' to quit. */
      char fileName[200] = { 0 };
      int sampleCounts[10] = {0};
      int speSamples[10] = {0};
      vibeModel_Sequential_t *model = NULL;      /* Model used by ViBe. */
    
      int heig = 512;
      int widt = 1340;
      Mat res = Mat::zeros(heig, widt, CV_8UC3); //res为三通道像素帧,用来保存最后合并的图像
    
      /* 创建保存视频的文件名并打开 */
      const string Name = "res.avi";
      VideoWriter writer;
      Size sz(widt, heig);
      writer.open(Name, CV_FOURCC('M', 'J', 'P', 'G'), 70, sz, true);
    
    while ((char)keyboard != 'q' && (char)keyboard != 27 ) { /* Read input data. ESC or 'q' for quitting. */ if (!capture.read(frame1)) { /* Read the current frame. */ cerr << "Unable to read next frame." << endl; cerr << "Exiting..." << endl; break;// exit(EXIT_FAILURE); } /* Applying ViBe. * If you want to use the grayscale version of ViBe (which is much faster!): * (1) remplace C3R by C1R in this file. * (2) uncomment the next line (cvtColor). */ cvtColor(frame1, frame, CV_BGR2GRAY); //将三通道图像帧转换为单通道 if ( frameNumber==1 ) { segmentationMap = Mat(frame.rows, frame.cols, CV_8UC1); model = (vibeModel_Sequential_t*)libvibeModel_Sequential_New(); libvibeModel_Sequential_AllocInit_8u_C1R(model, frame.data, frame.cols, frame.rows); class_samples(model,frame.data, sampleCounts,speSamples,frame.cols, frame.rows); } /* ViBe: Segmentation and updating. */ libvibeModel_Sequential_Segmentation_8u_C1R(model, frame.data, segmentationMap.data); libvibeModel_Sequential_Update_8u_C1R(model, frame.data, segmentationMap.data, &probFactor,frameNumber); medianBlur(segmentationMap, segmentationMap, 3); /* 3x3 median filtering */ contour(segmentationMap, frame1); //在原图上框出动目标,至此图像处理完毕 //sprintf(fileName, "results55_2/%06d.jpg",frameNumber); //imwrite(fileName, frame1); Mat segmentationMap1; //新定义一个帧变量,不能 cvtColor(segmentationMap, segmentationMap, CV_GRAY2BGR),因为 segmentationMap 为单通道帧; cvtColor(segmentationMap, segmentationMap1, CV_GRAY2BGR); //将单通道帧图像 segmentationMap 转化为三通道segmentationMap1,因为 res 帧为三通道帧图像 // segmentationMap1要合并在 res 中; /* Shows the current frame and the segmentation map. */ //imshow("Frame", frame1); //imshow("Segmentation by ViBe", segmentationMap); /* 将 segmentationMap1 和 frame1 合并成一帧存放在 res 中*/ segmentationMap1.copyTo(res(Rect(0, 0, 640, 512))); frame1.copyTo(res(Rect(700, 0, 640, 512))); imshow("res", res); //显示合并后的图像 /* 将 res 写入打开的视频文件中 */ writer << res; //将合并图像写入,连续的图像帧保存为视频文件;
    ++frameNumber; keyboard = waitKey(1); /* Gets the input from the keyboard. */ } finish=clock(); total=(double)(finish-start); cout<<total<<endl; cout<<frameNumber<<endl; capture.release(); /* Delete capture object. */ libvibeModel_Sequential_Free(model); /* Frees the model. */ } /* 框出运动目标 */ void contour(const Mat &mor, Mat &img) { int img_size = img.cols * img.rows; Mat tmp = (mor == 255); // Each detected contour is stored as a vector of points vector<vector<Point> > contours; vector<Vec4i> hierarchy; // containing information about the image topology findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); for (size_t k = 0; k < contours.size(); k++) { Rect rect = boundingRect(contours[k]); double whratio = double(rect.width) / double(rect.height); double hwratio = double(rect.height) / double(rect.width); double ratio = min(hwratio, whratio); double area = rect.area(); //框出符合条件的轮廓,舍去: 面积很小的, 面积很大的, 长宽比严重失调的 if (area > minArea && area < img_size*maxAreaRatio && ratio > boxRatio) { int w = rect.width; int h = rect.height; if(rect.width < 20) rect.width = 20; /* if(rect.width < 6) rect.width = 2*rect.width; else rect.width = rect.width + rect.width/2; */ if(rect.height < 20) rect.height = 20; /* if(rect.height < 6) rect.height = 2*rect.height; else rect.height = rect.height + rect.height/2; */ int w_add = (rect.width - w)/2; int h_add = (rect.height - h)/2; rect.x = rect.x - h_add; rect.y = rect.y - w_add; rectangle(img, rect, Scalar(0,0,255)); } } }
  • 相关阅读:
    Spring scope注解
    classpath与clsspath*
    Hadoop 5 Hbase 遇到的问题
    Hadoop 3
    Hadoop 4 MapReduce
    Hadoop 2
    Hadoop 1
    毕业设计---jQuery动态生成的a标签的事件绑定
    毕业设计---json,Struts,ajax以及JQuery简单案例
    基于SSH框架的学生选课质量属性分析
  • 原文地址:https://www.cnblogs.com/warmbeast/p/7662035.html
Copyright © 2020-2023  润新知