OpenCV Video Capture nonfunctional as class member (C++)

asked 2020-11-10 08:58:56 -0600

updated 2020-11-10 15:33:17 -0600

supra56 gravatar image

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 ... (more)

edit retag flag offensive close merge delete

Comments

1

(Here your code is completely illegibly formatted and impossible to even try to understand.)

mvuori gravatar imagemvuori ( 2020-11-10 14:14:14 -0600 )edit

trying to use more than 1 Videocapture(0) must fail.

berak gravatar imageberak ( 2020-11-14 03:47:58 -0600 )edit