Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>fix</p> <ul> <li>change <code>_fgmask.create(img_input.size(), CV_8U);</code> to <code>_fgmask.create(img_input.size(), CV_8UC3);</code> or <code>_fgmask.create(img_input.size(), img_input.type());</code> </li> </ul> <p>why</p> <ul> <li>this is because <code>cv::absdiff(img_input_prev, img_input, img_foreground);</code> recreate a new array everytime internally. and it does update the img_foreground structure but after the allocation, the memory address data inside _fgmask fail to change since the headers are passed by value. <ul> <li>you can seemlingly fix this(but still incurs creation cost) by doing <code>cv::Mat&amp; img_foreground = _fgmask.getMatRef();</code></li> </ul></li> <li>and that is because CV_8U is not the same as CV_8UC3 and therefore the check @ Mat::create() in mat.hpp always end up allocating a new array due to type difference</li> </ul> <p>opinion</p> <p>i think...maybe use Mat instead?</p> <pre><code>#include "opencv2/opencv.hpp" using namespace cv; class FrameDifferenceBGS { public: Mat prev; Mat diff; bool enableThreshold; bool showOutput; bool firstTime; uchar threshold; FrameDifferenceBGS():firstTime(false),enableThreshold(false),showOutput(false),threshold(0) { } void FrameDifferenceBGS::operator()(cv::Mat&amp; _in, cv::Mat &amp;_fg, double _lr) { if(_in.empty()) return; if(prev.empty()) { prev=_in.clone(); _fg=cv::Mat::zeros(_in.size(),CV_8UC1); return; } cv::absdiff(prev, _in, diff); if(diff.channels() == 3) cv::cvtColor(diff, _fg, CV_BGR2GRAY); else _fg=diff; if(enableThreshold) cv::threshold(_fg, _fg, threshold, 255, cv::THRESH_BINARY); if(showOutput) cv::imshow("Frame Difference", _fg); prev=_in.clone(); firstTime = false; } }; int main() { VideoCapture cap(0); FrameDifferenceBGS bgs; Mat frame,fg; for(;;) { cap &gt;&gt; frame; bgs(frame,fg,0); imshow("frame", frame); imshow("fg", fg); if(waitKey(1) ==27) exit(0); } return 0; } </code></pre> <h2>edit 2(modified original)</h2> <pre><code>#include "opencv2/opencv.hpp" class FrameDifferenceBGS { public: cv::Mat img_input_prev; cv::Mat diff; cv::Mat img_foreground;//put this in class in stead of inside the function bool enableThreshold; bool showOutput; bool firstTime; uchar threshold; FrameDifferenceBGS():firstTime(false),enableThreshold(false),showOutput(false),threshold(0) { } void FrameDifferenceBGS::operator()(cv::InputArray _image, cv::OutputArray _fgmask, double learningRate) { cv::Mat img_input = _image.getMat(); if(img_input.empty()) return; if(_fgmask.empty()) _fgmask.create(img_input.size(), CV_8UC1); if(img_input_prev.empty()) { img_input.copyTo(img_input_prev); return; } cv::absdiff(img_input_prev, img_input, img_foreground); if(img_foreground.channels() == 3) cv::cvtColor(img_foreground, _fgmask, CV_BGR2GRAY); if(enableThreshold) cv::threshold(img_foreground, img_foreground, threshold, 255, cv::THRESH_BINARY); if(showOutput) cv::imshow("Frame Difference", img_foreground); img_input.copyTo(img_input_prev); //img_foreground.copyTo(_fgmask); firstTime = false; } }; int main() { cv::VideoCapture cap(0); FrameDifferenceBGS bgs; cv::Mat frame,fg; for(;;) { cap &gt;&gt; frame; bgs(frame,fg,0); cv::imshow("frame", frame); cv::imshow("fg", fg); if(cv::waitKey(1) ==27) exit(0); } return 0; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload