OpenCV Video Capture nonfunctional as class member (C++)
Question is cross-posted from https://stackoverflow.com/questions/64764106/opencv-video-capture-nonfunctional-as-class-member-c
My application requires that the OpenCV VideoCapture object be used as a member variable. There is no way around this requirement.
I am experiencing strange behavior when using cv::VideoCapture
as a member of a user-defined class. I've run the following code:
#define int64 opencv_broken_int
#include <opencv2/opencv.hpp>
#undef int64
class Foo { public: Foo() = default;
void run(void) { cv::VideoCapture*
cap = new cv::VideoCapture();
cv::VideoCapture g_cap = *cap; if
(not g_cap.open(0)) { std::cerr <<
"Cannot open camera 0" << std::endl;
exit(-1); } for (int i = 0; i <
10; i++) { if (not
g_cap.isOpened())
std::cerr << "Video capture is not open here!" << std::endl; cv::Mat
f; g_cap >> f; if (f.empty())
std::cerr << "Frame was empty" <<
std::endl; break; std::string
filename = "Foo_test_" +
std::to_string(i) + ".tiff"; bool b
= cv::imwrite(filename, f);
if (not b) std::cerr << "Error in writing image" << std::endl;
//cv::waitKey(25); } };
};
int main(void) { cv::VideoCapture
cap;
if (not cap.open(0)) { std::cerr <<
"Cannot open camera 0" << std::endl;
return -1; }
for (int i =0; i < 10; i++) {
cv::Mat frame; cap >> frame; if
(frame.empty()) { std::cerr <<
"frame is empty" << std::endl;
break; } // Else write the
image to a file std::string filename
= "test_" + std::to_string(i) + ".tiff"; bool res =
cv::imwrite(filename, frame); if
(not res) std::cerr << "Error in
writing image" << std::endl;
}
cap.release();
Foo f; f.run();
return 0; }
which only produced test_N.tiff for N = [0,9], i.e., the only images produced are coming from the cv::VideoCapture
object in main( )
and not from within class Foo
.
I tried to instantiate a global variable g_cap
of type cv::VideoCapture
and still I only can read/write images from the object within the main function. As shown in the above code I also tried to instantiate the VideoCapture object as a pointer (a hail mary, if you will) and that does not work either. Note however that setting cap
declared in main( )
to be a reference to g_cap
(obviously when g_cap
was in global scope) gave the same output - getting images from within main( )
but not from within Foo::run( )
as needed.
Note another strange behavior is that no error messages appear in the console. That would indicate that Foo
's member of type VideoCapture
is in fact open and that loading an image frame into f
of type cv::Mat
did not return an empty frame. Similarly the imwrite
function does not return false indicating that the operation was successful. However, as previously stated, no files of name Foo_test_N.tiff were produced.
How could this behavior be explained? Is there some requirement that cv::VideoCapture
be in some different scope perhaps? If the images are not saved or the video stream is not opened correctly would this not produce an error message as the above ...
(Here your code is completely illegibly formatted and impossible to even try to understand.)
trying to use more than 1 Videocapture(0) must fail.