computing average image of N webcam images crashes sometimes
Hey guys, I wanted to write a program which takes N live webcam images, calculates an averaged-image out of it and saves the average image as a jpg. I'm passing the filename and the number N of images to be averaged as parameters. First I thought everything is working fine with my code, but sometimes the program crashes during runtime (I'm calling the exe via LabVIEW). I'm not changing N, only the filename-number is incremented by 1 for each call, so I don't think that's the issue. It crashes about 1 time in 25 calls but it's nor really reproducible when. With crashing I mean the window freezes, and is greyed out by Windows and I get the promt that the program isn't responding.
Here is my code:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
string outputfilename;
int NMean; // number of images to take mean values of
if (argc == 2)
{
outputfilename = argv[1];
NMean = 100;
}
else if(argc > 2)
{
outputfilename = argv[1];
istringstream ss(argv[2]);
ss >> NMean;
}
else
{
outputfilename = "newframe.jpg";
NMean = 100;
}
VideoCapture cap(0);
if (!cap.isOpened())
{
cout << "Cannot open the video cam" << endl;
return -1;
}
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cout << "Frame size : " << dWidth << " x " << dHeight << endl;
cap.set(CV_CAP_PROP_FRAME_WIDTH, 1280);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 1024);
namedWindow("WebcamImage",CV_WINDOW_AUTOSIZE);
Mat frame;
Mat meanImage(1024, 1280, CV_32FC3, cv::Scalar(0));
for (int i=0; i<NMean; i++)
{
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "Cannot read a frame from video stream" << endl;
break;
}
imshow("WebcamImage", frame);
accumulate(frame, meanImage);
if (waitKey(30) == 27)
{
cout << "esc key is pressed by user" << endl;
break;
}
}
meanImage = meanImage / NMean;
meanImage.convertTo(meanImage,CV_8UC3);
imwrite(outputfilename.c_str(),meanImage);
cap.release();
destroyWindow("WebcamImage");
return 0;
}
I noticed that during a crash the averaged image is still saved. So the error must occur after the last imwrite (I also tried to put destroyWindow in front of break; but it didn't help).
What could be the issue? Thanks a lot and best regards!
is there any chance, your frame is empty() ? imshow() will break then.
like @berak said, add enough checks to ensure every step is performed on valid data. This can be done by adding a line like
if(frame.empty()){ continue; }
which will just skipp the misread frame. This can happen due to encoding errors in the video capture.I have tried your program and I have changed some line code. I have test it using a function and there is no problem :
I must say that first and second frame are wrong with my webcam