OpenCV capture loops video/Does not detect last frame - c++

I am capturing an avi file and processing it. My code has worked for sometime without problem but now it does not seem to stop after the last frame of the video is captured. Instead it keeps looping back to the beginning of the video. I do not understand why this is happening and I can not think of anything changing with regards to Eclipse or OpenCV. I have tried the same code on my Ubuntu pc with the same video and it works without problems. I have even tried as much as reinstalling the OS and apps without success.
Sample code:
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
Mat frame;
VideoCapture capture;
const string inputVideo = argv[1];
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string fileName( buff );
fileName.append("/");
fileName.append(inputVideo);
capture.open(inputVideo);
while(true)
{
capture >> frame;
if(!frame.empty())
{
imshow("frame", frame);
}
else
{
printf(" --(!) No captured frame -- Break!");
break;
}
int key = waitKey(10);
if((char)key == 'c')
{
break;
}
}
return 0;
}
I am running this on a Mac OS X (10.8.2), Eclipse Juno, and OpenCV 2.4.3.
Any advice or comments are appreciated. Thanks in advance

The solution that I used was posted as a comment by #G B. I am creating a solution so that it may be marked as one.
I used capture.get(CV_CAP_PROP_POS_FRAMES) before and after frame grabbing, if the value "after" is less than the value "before", then I've reached the end of the video.

Get the frame count like below,
int frameCnt = capture.get(CV_CAP_PROP_FRAME_COUNT);
And check to exit the loop when the frame count exceeds..

Related

wrting to csv file in c++ fails [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Im working with this code which is supposed to detect faces. The code works totally fine, but as soon as I try to insert three lines for writing to csv file, it breaks down with lengthy error of some 100+ lines -ERROR FILE LOG.
This code was taken from :- https://github.com/shunyaos/shunyaface
// Header file for Face-Recognition/Detection
#include "shunyaface.h"
#include "opencv2/opencv.hpp"
#include <bits/stdc++.h>
#include "fstream"
using namespace std;
using namespace cv;
int main(int argc, char** argv){
// Create instance of class FaceRec
std::ofstream filename("test.csv");
filename<< "TESTING CSV WRITE";
FaceRec facerec;
Mat frame;
Mat frame2;
clock_t start, end; //This will hold the start and end-time
int count = 0; //Variable which hold the number of frames elapsed
VideoCapture cap(0);
time(&start);
while(1)
{
// Capture a frame
cap >> frame;
// Pass the frame to the detect function which will return the frame with a bounding-box on the face and points on the lips and eyes
frame2 = facerec.detect(frame);
count++; //Increment count
// Display the frame to the user
imshow("face-detect", frame2);
if(waitKey(1) == 'q')
break;
}
time(&end); // Stop the time
cout<< "Output FPS is:"<<count/(end-start)<<endl; //Display Output-FPS
filename.close();
return 0;
}
So basically as shown above,after inclusion of these lines the code is breaking :-
std::ofstream filename("test.csv");
filename<< "TESTING CSV WRITE";
filename.close()
You forget to end this line cout<< "In while"<<.
Somewhere in your code is this snippet
out<< "In while"<<
// Capture a frame
~~~~~~~~~~~~~~~~~~
cap >> frame;
You should try to fix error from top to bottom. The first error is regarding cout, operator<< and cv::VideoCapture cap.

OpenCV memory leak using cvCreateFileCapture and cvQueryFrame

I am new to OpenCV (OpenCV 3.2 / opencv_ffmpeg320_64.dll / Windows 10 / Visual Studio 2017) and wrote a program dealing with a video stream of a webcam. Unfortunately the program has a memory leak. After hours of searching and googling I managed to break down the problem to the following minimal example:
#include <iostream>
#include <opencv2/opencv.hpp>
#include <thread>
CvCapture *capture;
IplImage *frame;
int main(int argc, char **argv)
{
capture = cvCreateFileCapture("http://192.168.1.123:8080/CamStream");
while (true)
{
cvWaitKey(1);
frame = cvQueryFrame(capture);
if (frame)
{
std::cout << "New image" << std::endl;
}
}
return 0;
}
As you can see I am capturing of a simple HTTP stream. After the capture is created new frames are received. Unfortunately the task manager shows a never stopping increase of memory:
What could cause this problem and what are possible approaches to solve it?

OpenCV VideoCapture working properly only after breakpoint

I'm currently using OpenCV 2.3.1 with Visual Studio 2008. I'm trying to read the frames from a Hauppauge Usb Live-2 using VideoCapture, but I'm ran into a strange issue. Below is the relevant part of my code:
VideoCapture vc(0);
if (!vc.isOpened()) return -1;
Mat frame;
namedWindow("Camera");
bool success;
while (true)
{
success = vc.read(frame);
if (!success) continue;
imshow("Camera", frame);
if (waitkey(30) == 27) break;
}
Initially, when running my code in debug mode, the window displaying the captured frames shows only a solid gray image. Attempting to debug my program, I placed breakpoint a breakpoint at the start of my code and stepped through each line. At imshow, however, the window started displaying the grabbed frames properly, showing what was captured by my camera. Subsequently, I realized that so long as I enter a breakpoint between opening my device and displaying it on the window, the frames will start showing up properly.
Does anyone have any idea how entering a breakpoint may affect the execution of a program in debug mode (in this case allowing the VideoCapture object to start reading the frames properly)?
Note: Running the executable gave no problems either, so I'm posting this question out of curiosity.
I believe your code is trying to display the image (which is empty) before your camera gets ready. Try to slow down for one or two seconds, by first include files like:
#include <chrono>
#include <thread>
Then before your while statement, add this line:
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
If you are using C++ with lower version than 11, then the sleep_for method might be different. Take a reference here.
The camera has an initialisation period so you need to check for empty frames.
Now there are two options, you could do what #Derman has said and put in a wait but how do you know how long you need to wait for?
Or you can check for empty frames and only show the window if they are not empty
VideoCapture vc(0);
if ( !vc.isOpened() ) // if not success, exit program
{
cout << "Cannot open the video file" << endl;
return -1;
}
Mat frame;
namedWindow("Camera");
bool success;
while (true)
{
vc.read(frame);
if(frame.empty()){
std::cerr<<"frame is empty"<<std::endl;
break;
}
imshow("Camera", frame);
if (waitkey(30) == 27) break;
}
I don't see any reason why this code shouldn't start showing the frames once they are avaliable from the camera

OpenCV: Reading the frames of a video sequence

Anyone help me ,I am trying to run code to read frames from video in folder its success in building but when debugging there isn't any output
* I am using Visual studio 2012 ,opencv 2.4.11 version
the code is :
#include "stdafx.h"
#include <opencv2/opencv.hpp>
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}
int main()
{
// Open the video file
cv::VideoCapture capture("C:/Users/asus/Desktop/A.mp4");
// check if video successfully opened
if (!capture.isOpened())
return 1;
// Get the frame rate
int rate= capture.get(CV_CAP_PROP_FPS);
bool stop(false);
cv::Mat frame; // current video frame
cv::namedWindow("Extracted Frame");
// Delay between each frame in ms
// corresponds to video frame rate
int delay= 1000/rate;
// for all frames in video
while (!stop) {
// read next frame if any
if (!capture.read(frame))
break;
cv::imshow("Extracted Frame",frame);
// introduce a delay
// or press key to stop
if (cv::waitKey(delay)>=0)
stop= true;
}
// Close the video file.
// Not required since called by destructor
capture.release();
}
Your main() function is never executed. The only thing, that gets executed is _tmain(), which does nothing and returns immediately.
I haven't done much Windows programming in a while, but if I remember correctly this is how it works:
When Unicode is enabled for your compiler
int _tmain(int argc, _TCHAR* argv[])
gets compiled as
int wmain(int argc, wchar * argv[])
which is then used as the program entry point.
Since you seem not to be using any Windows-APIs in your code I would ignore the Microsoft specific way of doing multibyte character strings, which is non-portable, and simply use plain ASCII strings as you did in the main() function, that you intended to use.
So to solve your problem simply throw out the _tmain() function. Maybe you also need to disable Unicode in your project settings if you get linker errors.

OpenCV videoWriter codec issue

I am trying to write a video in OpenCV in Windows and am meeting various issues when choosing codecs. I'm not sure if it is something in my code or I do not have the codecs necessary. The code is:
int main(int argc, char ** argv){
VideoCapture inputVideo("LFW.mp4");
Mat inputFrame, outputFrame;
VideoWriter outputVideo;
if (!inputVideo.isOpened()){
std::cout << "!!! Input video could not be opened" << std::endl;
return 1;
}
int ex = static_cast<int>(inputVideo.get(CV_CAP_PROP_FOURCC));
const string name = "Output.mp4";
Size size = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), (int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
outputVideo.open(name, CV_FOURCC('M','P','4','2'), inputVideo.get(CV_CAP_PROP_FPS), size, true);
if (!outputVideo.isOpened()){
std::cout << "!!! Output video could not be opened" << std::endl;
return 2;
}
return 0;
}
The code keeps exiting with code 2, therefore the videoWriter object is not happy with its configuration.
I have a problem with many codecs on windows. I have installed ffmpeg correctly, but still there is a problem with many video format.
Try this one CV_FOURCC('W', 'M', 'V', '2')
VideoWriter video("Result.wmv", CV_FOURCC('W', 'M', 'V', '2'), 30, SizeOfFrame, true);
WMV is awful format but works perfect for me. I am working with Visual Studio 2015 and my own build of Opencv 3.0.0.
In Opencv 3.0.0, I can strongly recommend include also
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/videoio/videoio.hpp"
There is anoter recommandation. Check size of input video and size of VideoWriter. CV_CAP_PROP_FRAME_WIDTH and CV_CAP_PROP_FRAME_HEIGHT in some cases return wrong values. Check both sizes before video.write(Mat)
You can check your video writer by this loop.
Set your writer sizes as dummy constant.
Size SizeOfFrame = cv::Size( 800, 600);
VideoWriter video("Result.wmv", CV_FOURCC('W', 'M', 'V', '2'), 30, SizeOfFrame, true);
In video loop resize retrieved video to same size as writer. If this fail your installation is probably wrong.
for (;;)
{
bool Is = cap.grab();
if (Is == false) {
cout << "cannot grab video frame" << endl;
}
else {
cap.retrieve(LoadedImage, CV_CAP_OPENNI_BGR_IMAGE);
resize(LoadedImage, LoadedImage, Size(800, 600));
video.write(LoadedImage);
}
}
My Tutorial here
It is not uncommon that people have codec issues when working with VideoCapture and VideoWriter. (Another less common issue is that OpenCV has been compiled without an encoder (like using WITH_FFMPEG=NO or WITH_VFW=NO when compiling OpenCV) )
I would try the following things dissect the problem (ordered by the level of hassle involved :) ):
Try running the same program but passing -1instead of CV_FOURCC('M','P','4','2') as the second argument to outputVideo.open(). You will then get a pop-up asking you to select codec and can then see which ones OpenCV finds.
If that doesn't help you - use a debugger to step into outputVideo.open(). You might turn out to arrive at an empty function (#ifdefed away due to some preprocessor macro). Unfortunately you will have to have a debug-compiled OpenCV with pdb-files to do this properly.