Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 一种简单的帧差分法_Opencv_Frame - Fatal编程技术网

Opencv 一种简单的帧差分法

Opencv 一种简单的帧差分法,opencv,frame,Opencv,Frame,背景场景通常会随着时间的推移而变化,例如,因为照明条件可能会发生变化(例如,从日出到日落),或者因为可以在背景中添加或删除新对象。 因此,有必要动态地建立背景场景的模型。 基于以上,我编写了一个简单的帧差分代码。它工作得很好,但速度很慢。 我怎样才能使它更快?有什么建议吗 #include <opencv2/highgui/highgui.hpp> #include <opencv2/core/core.hpp> #include <iostream> #i

背景场景通常会随着时间的推移而变化,例如,因为照明条件可能会发生变化(例如,从日出到日落),或者因为可以在背景中添加或删除新对象。 因此,有必要动态地建立背景场景的模型。 基于以上,我编写了一个简单的帧差分代码。它工作得很好,但速度很慢。 我怎样才能使它更快?有什么建议吗

 #include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/video/background_segm.hpp >
using namespace cv;
using namespace std;
#include <iostream>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/video/tracking.hpp>

    int main()
    {
        cv::Mat gray; // current gray-level image
     cv::Mat background; // accumulated background
     cv::Mat backImage; // background image
     cv::Mat foreground; // foreground image
     // learning rate in background accumulation
     double learningRate;
     int threshold; // threshold for foreground extraction
     cv::VideoCapture capture("video.mp4");

     // check if video successfully opened
     if (!capture.isOpened())
     return 0;
     // current video frame
     cv::Mat frame;
     double rate= capture.get(CV_CAP_PROP_FPS);
     int delay= 1000/rate;
     // foreground binary image
     //cv::Mat foreground;
      cv::Mat output;
      bool stop(false);
      while (!stop){
          if(!capture.read(frame))
              break;

          cv::cvtColor(frame, gray, CV_BGR2GRAY);
      cv::namedWindow("back");
         cv::imshow("back",gray);

      // initialize background to 1st frame
     if (background.empty())
     gray.convertTo(background, CV_32F);
     // convert background to 8U
     background.convertTo(backImage,CV_8U);
     // compute difference between image and background
     cv::absdiff(backImage,gray,foreground);

         // apply threshold to foreground image
     cv::threshold(foreground,output, 10,255,cv::THRESH_BINARY_INV);
     // accumulate background
     cv::accumulateWeighted(gray, background, 0.01, output);


         cv::namedWindow("out");
         cv::imshow("out",output);
     if (cv::waitKey(delay)>=0)
     stop= true; 
      }

     }
#包括
#包括
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
#包括
#包括
#包括
int main()
{
cv::Mat gray;//当前灰度图像
cv::Mat background;//累积背景
cv::Mat backImage;//背景图像
cv::Mat前景;//前景图像
//背景积累中的学习率
双学习率;
int threshold;//前景提取的阈值
cv::视频捕获捕获(“video.mp4”);
//检查视频是否成功打开
如果(!capture.isOpened())
返回0;
//当前视频帧
cv::垫架;
双速率=捕获。获取(CV\U CAP\U PROP\U FPS);
int延迟=1000/速率;
//前景二值图像
//cv::Mat前景;
cv::Mat输出;
bool-stop(假);
当(!停止){
如果(!捕获.读取(帧))
打破
cv::CVT颜色(边框、灰色、cv_bgr2灰色);
简历::namedWindow(“背”);
cv::imshow(“背”,灰色);
//将背景初始化为第一帧
if(background.empty())
灰色。convertTo(背景,CV_32F);
//将背景转换为8U
背景转换(背景图像,CV_8U);
//计算图像和背景之间的差异
cv::absdiff(背景图像、灰色、前景);
//对前景图像应用阈值
cv::threshold(前景,输出,10255,cv::THRESH\u BINARY\u INV);
//积累背景
cv::累计加权(灰色,背景,0.01,输出);
cv::namedWindow(“out”);
cv::imshow(“输出”,输出);
如果(cv::waitKey(延迟)>=0)
停止=真;
}
}

我修改并更正了部分代码:

  • 在调用
    cv::namedWindow(“back”)
    cv::namedWindow(“out”)
    的while循环中,只需执行一次
  • 使用
    if(background.empty())
    查看数组是否为空,这对于矩阵
    background
    为空的第一个循环是必需的,因为剩余的矩阵将被填充,这样代码就不会出错,第一个循环初始化为零
    background=cv::Mat::zeros(行、列、cv_32F)
    考虑迭代while循环中需要的类型和大小。此外,它不影响积累的运作
更新代码如下:

int main()
{
    cv::Mat gray; // current gray-level image
 cv::Mat background; // accumulated background
 cv::Mat backImage; // background image
 cv::Mat foreground; // foreground image
 // learning rate in background accumulation
 double learningRate;
 int threshold; // threshold for foreground extraction
 cv::VideoCapture capture("C:/Users/Pedram91/Pictures/Camera   Roll/videoplayback.mp4");////C:/Users/Pedram91/Downloads/Video/videoplayback.mp4//C:/FLIR.mp4

 // check if video successfully opened
 if (!capture.isOpened())
 return 0;
 // current video frame
 cv::Mat frame;
 double rate= capture.get(CV_CAP_PROP_FPS);
 int delay= 1000/rate;
 // foreground binary image
 //cv::Mat foreground;
  cv::Mat output;
  bool stop(false);

  cv::namedWindow("back");//This should go here,You only need to call once
  cv::namedWindow("out");//This should go here,You only need to call once

  int cols=capture.get(CV_CAP_PROP_FRAME_HEIGHT);
  int rows=capture.get(CV_CAP_PROP_FRAME_WIDTH);      

  background=cv::Mat::zeros(rows,cols,CV_32F);//this will save the "if (background.empty())" in the while loop


  while (!stop){
      if(!capture.read(frame))
          break;

     cv::cvtColor(frame, gray, CV_BGR2GRAY);

     cv::imshow("back",gray);

  // initialize background to 1st frame
// if (background.empty())
 gray.convertTo(background, CV_32F);
 // convert background to 8U
 background.convertTo(backImage,CV_8U);
 // compute difference between image and background
 cv::absdiff(backImage,gray,foreground);

     // apply threshold to foreground image
 cv::threshold(foreground,output, 10,255,cv::THRESH_BINARY_INV);
 // accumulate background
 cv::accumulateWeighted(gray, background, 0.01, output);



  cv::imshow("out",output);
 if (cv::waitKey(delay)>=0)
 stop= true; 
  }

 }

OpenCV已经实现了类似的功能,也许你们可以从这个例子中得到一些启发。他们提供了实施过程中参考的文件。然而,根据我的经验,这些事情通常都很慢。谢谢你的建议。我得写一个实时运动物体跟踪器。你知道这个主题的任何实时方法吗?你可以从上面的链接开始,说服自己opencv方法比你将要编写的任何自定义代码都更好更快(直到你获得更多的经验)。你能公布你的执行时间吗?这段代码不会那么慢……如果(cv::waitKey(1)>=0),您可能应该使用
。您的代码有一些小错误(如下面的答案所指出的),但我认为瓶颈是
waitKey
。您的背景图像需要浮点精度吗?您可以尝试使用beta=1-alpha的addWeighted,但不确定它是否更快(您可能会有一些开销,但不必为每帧转换为8位。您的
延迟值不关心所需的处理时间(例如,如果您有25 fps,您的延迟将是40 ms,但如果您的处理时间是20 ms,您将在每帧之间等待60 ms,而不是40 ms)。此外,cv::waitKey不是非常精确(在windows系统waitKey上,可能会比您希望的等待时间更长)你能解释一下这个代码对OP代码的改进是什么吗?你对性能进行了比较吗?只有代码的答案不是很清楚,考虑用一些解释来改进它。再检查一下答案。你可以看到我格式化了你的答案。学习如何使用格式化选项来产生更好的答案。同时,请仔细检查我的ED。我是新来的,我还在学习如何处理这个网站,纠正了我糟糕的写作方式,给我留下了深刻的印象,哥伦比亚的问候是的,我同意这是我的答案。