I'm trying to get an running average of frames from my cam, but after a few secounds the image of the averaged frames gets brighter and brighter and than white.
my cam provides an image in gray scale with 3 channels. I'm on windows 7, Visualstudio 2012, opencv 243
#include<opencv2\opencv.hpp>
#include<opencv2\core\core.hpp>
#include<opencv2\highgui\highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
VideoCapture cap(0);
Mat frame1;
cap.read(frame1);
Mat acc = Mat::zeros(frame1.size(), CV_32FC1);
while(1){
Mat frame;
Mat gray;
cap.read(frame);
cvtColor(frame ,gray ,CV_BGR2GRAY,0);
accumulateWeighted(gray, acc,0.005);
imshow("gray", gray);
imshow("acc", acc);
waitKey(1); //don't know why I need it but without it the windows freezes
}
}
can anyone tell me what i did wrong? Thanks!
The issue here is with how imshow maps matrix values to pixel values. Typically, the raw data from the cam comes in as an integer data type, typically in the range [0, 255]. The accumulateWeighted function does what you expect and computes a running average of the frames. So acc is a floating-point matrix with values somewhere in [0, 255].
Now, when you pass that matrix to imshow, the matrix values need to get mapped to intensities. Since the datatype is a floating-point type, 0 gets mapped to black, 1 gets mapped to white and everything outside that range gets clipped. Thus, only if a region of your image is very dark and stays that way, will the running average stay below 1 and get mapped to a color other than pure white.
Luckily, the fix is simple:
imshow("acc", acc/255);