【发布时间】:2015-10-05 07:58:21
【问题描述】:
背景场景通常会随着时间而变化,例如,照明条件可能会发生变化(例如,从日出到日落),或者可能会从背景中添加或移除新对象。 因此,需要动态构建背景场景的模型。 基于以上,我写了一个简单的帧差分代码。它工作得很好,但它很慢。 我怎样才能让它更快?有什么建议吗?
#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;
}
}
【问题讨论】:
-
OpenCV 已经实现了类似的东西,也许你可以从this 示例中获得一些启发。提供参考他们从中获取实施的论文。但是,根据我的经验,这些事情通常很慢。
-
感谢您的建议。我必须编写一个实时移动对象跟踪器。你知道这个主题的任何实时方法吗?
-
您可以从上面发布的链接开始,并说服自己 opencv 方法比您编写的任何自定义代码更好更快(直到您获得更多经验)。您还可以发布您的执行时间吗?这段代码不可能那么慢...
-
或许你应该使用
if (cv::waitKey(1)>=0)。您的代码有一些小错误(如下面的答案所指出的),但我认为瓶颈是waitKey。 -
您的背景图像需要浮点精度吗?您可以尝试使用 beta=1-alpha 的 addWeighted,但不确定它是否更快(您可能会得到一些开销,但您不必为每帧转换为 8 位。您的
delay值不关心所需的处理时间(例如,如果您有 25 fps,您的延迟将是 40 毫秒,但如果您的处理时间是 20 毫秒,您将在每帧之间等待 60 毫秒而不是 40 毫秒)。此外, cv::waitKey 不是很精确(在 Windows 系统 waitKey 上,可能等待的时间比您希望的要长)