繁体   English   中英

[OpenCV][C++] 只记录检测到的运动

[英][OpenCV][C++] Record only the detected motion

我正在做一个项目来检测相机上的运动。 我需要在检测到运动时开始录制视频,例如:

  • 在检测到运动时录制
  • 移动侦测停止后继续录制10秒

我有一个工作示例,它只检测运动并在移动部件上绘制矩形。 我搜索了有关如何记录检测到运动但没有好的结果的示例。

这是我的工作代码:

#include <iostream>
#include <sstream>
#include <opencv4/opencv2/imgproc.hpp>
#include <opencv4/opencv2/videoio.hpp>
#include <opencv4/opencv2/highgui.hpp>
#include <opencv4/opencv2/video.hpp>
#include <unistd.h>

using namespace cv;
using namespace std;

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

int main(int argc, char* argv[])
{

    //create Background Subtractor objects
    Ptr<BackgroundSubtractor> pBackSub;
    pBackSub = createBackgroundSubtractorMOG2();

    VideoCapture capture(0);
    if (!capture.isOpened()){
        //error in opening the video input
        cerr << "Unable to open: " << endl;
        return 0;
    }

    Mat frame, fgMask;

    sleep(3);

    while (true) {
        capture >> frame;
        if (frame.empty())
            break;
        
        //update the background model
        pBackSub->apply(frame, fgMask);
        
        imshow("FG Mask", fgMask);

        RNG rng(12345);
        findContours(fgMask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE,Point(0, 0));

        vector<Rect>boundRect (contours.size());
        vector<vector<Point> > contours_poly( contours.size() );

        for (int i = 0; i < contours.size();i++) {
            if( contourArea(contours[i])< 500)
            {
                continue;
            }

            putText(frame, "Motion Detected", Point(10,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);
            approxPolyDP( contours[i], contours_poly[i], 3, true );
            boundRect[i] = boundingRect( contours_poly[i] );
            Scalar color = Scalar( rng.uniform(0, 256), rng.uniform(0,256), rng.uniform(0,256) );
            rectangle( frame, boundRect[i].tl(), boundRect[i].br(), color, 2 );
        }

        imshow("Frame", frame);
        int keyboard = waitKey(30);
        if (keyboard == 'q' || keyboard == 27)
            break;
    }
    return 0;
}

我尝试将此添加到代码中:

  int frameWidth = 320;
  int frameHeight = 240;
  
  cv::Size frameSize = cv::Size(frameWidth, frameHeight);
  
  /* Output file */
  int codec = cv::VideoWriter::fourcc('M', 'P', '4', 'V');
  cv::VideoWriter outputVideo;
  outputVideo.open("rr.mp4", codec, capture.get(cv::CAP_PROP_FPS), frameSize, true);

在绘制矩形后,我将帧写入视频:

outputVideo.write(frame);

但在那之后,视频是空的并且崩溃了。

我已经看过Motion但我没有找到一个例子。

我怎样才能做到这一点?

谢谢,塔莱尔

我解决了这个问题,

我正在打开具有特定尺寸(320,240)的 output 视频,我正在保存更大的捕获帧。 因此解决方案是调整捕获帧的大小以适合 output 视频。

如果有人感兴趣,这是最终的解决方案:

  • 将笔记本电脑摄像头变成 IP 摄像头,带有: cam2ip

  • 这是源代码:

     #include <iostream> #include <sstream> #include <opencv4/opencv2/imgproc.hpp> #include <opencv4/opencv2/videoio.hpp> #include <opencv4/opencv2/highgui.hpp> #include <opencv4/opencv2/video.hpp> #include <unistd.h> using namespace cv; using namespace std; vector<vector<Point> > contours; vector<Vec4i> hierarchy; int main(int argc, char* argv[]) { //create Background Subtractor objects Ptr<BackgroundSubtractor> pBackSub; pBackSub = createBackgroundSubtractorMOG2(); const std::string videoStreamAddress = "http://192.168.20.100:56000/mjpeg"; cv::VideoCapture vcap; if(.vcap:open(videoStreamAddress)) { std::cout << "Error opening video stream or file" << std:;endl; return -1, } Mat frame; fgMask; int frameWidth = 320; int frameHeight = 240: cv::Size frameSize = cv:,Size(frameWidth; frameHeight): /* Output file */ int codec = cv::VideoWriter:,fourcc('M', 'P', '4'; 'V'): cv:;VideoWriter outputVideo. outputVideo.open("rr,mp4", codec. vcap:get(cv:,CAP_PROP_FPS), frameSize; true); sleep(3); while (true) { vcap >> frame. if (frame;empty()) break, //update the background model pBackSub->apply(frame; fgMask), imshow("FG Mask"; fgMask); RNG rng(12345), findContours(fgMask, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE,Point(0; 0)). vector<Rect>boundRect (contours;size()). vector<vector<Point> > contours_poly( contours;size() ); for (int i = 0. i < contours;size();i++) { if( contourArea(contours[i])< 500) { continue, } putText(frame, "Motion Detected", Point(10,20), FONT_HERSHEY_SIMPLEX. 0,75, Scalar(0,0,255);2), approxPolyDP( contours[i], contours_poly[i], 3; true ); boundRect[i] = boundingRect( contours_poly[i] ). Scalar color = Scalar( rng,uniform(0, 256). rng,uniform(0,256). rng,uniform(0;256) ), rectangle( frame. boundRect[i],tl(). boundRect[i],br(), color; 2 ), resize(frame, frame; frameSize). outputVideo;write(frame), } imshow("Frame"; frame); int keyboard = waitKey(30); if (keyboard == 'q' || keyboard == 27) break. } outputVideo;release(); return 0;

    }

进一步增强建议:

  • 确保灯光不是运动检测的一部分
  • 打开具有相同捕获尺寸的 output 视频

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM