OpenCV memory leak using cvCreateFileCapture and cvQueryFrame - c++

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?

Related

How do I make a portable program with OpenCV2 on C++?

I have installed OpenCV on Windows 10 and using C++ in Visual Studio.
Now I'm trying to make a program that makes several photos then saves them.
Problem:
I made a copy of project on USB flash (go to another PC) and when I try to start it from .exe file, I get this error:
How can start it without installing 1Gb of FULL OpenCV libraries?
I tried to start from release version.
My C++ source:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <windows.h> // For Sleep
using namespace cv;
using namespace std;
int main(int, char**)
{
VideoCapture cap(0);
// Get the frame
Mat save_img; cap >> save_img;
if (save_img.empty())
{
std::cerr << "Something is wrong with the webcam, could not get frame." << std::endl;
}
// Save the frame into a file
imwrite("test.jpg", save_img); // A JPG FILE IS BEING SAVED
return 0;
}
My settings:
P.S. I want to make light program for making photo on Windows. And how to make real portable programs.

OpenCV imread could not open or find image

I'm doing a project with OpenCV. I am trying to run a simple code:
#include<opencv2/core.hpp>
#include<opencv2/videoio.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<stdio.h>
#include<math.h>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
cv::Mat img2 = cv::imread("test.jpg", 1);
if (!img2.data) // Check for invalid input
{
cout << "Could not open or find the image" << std::endl;
cv::waitKey(5000);
return -1;
}
else {
cout << "Working" << endl;
cv::waitKey(5000);
}
return 0;
}
My project is a lot more bigger then this, however something simple like this isn't working for me. I have tried many things such as full path names // and \\, even tried an IplImage and convert it into Mat still no luck.
I have tried many different file types as well. If it helps I have coded it to stop the application after hitting any button, that does not work as it isn't taking any input from my keyboard.
How can I determine what is wrong?
I had this exact issue including the part about it only working in release mode. I found out I was using the release libraries for both release and debug. Because I had followed the tutorial on the OpenCV website for visual studio (incorrectly albeit), I changed the .lib folder to the correct d.lib and that fixed it.

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.

Read a JPEG image from memory with boost::gil

I am trying to read an image from memory by using boost::gil present in boost 1.53. I have taken the following lines from an example taken from internet:
#include <boost/gil/gil_all.hpp>
boost::gil::rgb8_image_t img;
boost::gil::image_read_settings<jpeg_tag> readSettings;
boost::gil::read_image(mystream, img, readSettings);
Except the first line, the type and function in the remaining lines cannot be found in the boost::gil namespace, so I cannot test if the above lines do what I want. Do you have any idea where to get the required types and functions?
See the new version of gil here: gil stable version
It works well and it is stable.
using namespace boost::gil;
image_read_settings<jpeg_tag> readSettings;
rgb8_image_t newImage;
read_image(stream, newImage, readSettings);
You code seems correct.
Boost 1.68, which is planned for release on 8th of August, 2018, will finally deliver the new Boost.GIL IO (aka IOv2) reviewed and accepted long time ago.
It is already available from the current master branch of the Boost super-project (check Boost.GIL CONTRIBUTING.md for guidelines how to work with the super-project).
Now, you can use GIL from Boost 1.68 or later, here is example that shows how to read image from input stream. It does not have to be file-based stream, but any std::istream-compatible stream should work.
#include <boost/gil.hpp>
#include <boost/gil/io/io.hpp>
#include <boost/gil/extension/io/jpeg.hpp>
#include <fstream>
#include <iostream>
int main(int argc, char* argv[])
{
if (argc != 2)
{
std::cerr << "input jpeg file missing\n";
return EXIT_FAILURE;
}
try
{
std::ifstream stream(argv[1], std::ios::binary);
namespace bg = boost::gil;
bg::image_read_settings<bg::jpeg_tag> read_settings;
bg::rgb8_image_t image;
bg::read_image(stream, image, read_settings);
return EXIT_SUCCESS;
}
catch (std::exception const& e)
{
std::cerr << e.what() << std::endl;
}
return EXIT_FAILURE;
}

OpenCV capture loops video/Does not detect last frame

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..