OpenCV video write Help on Nano

Hello,

I am having some trouble saving video on the jetson nano using openCV. The issue I am seeing is only one frame is being saved in the video. The video opens when I try to view it, but there is only one frame being displayed.

Any suggestions would be appreciated. I believe I am using a valid video format, I’ve tried a couple and get the same results; only one frame for the entire duration of the video. I am initially thinking if the images written are the same, but I don’t think this is happening. I think a good debug step would be to print a few elements from Mat image array and see if the data matches. However I see the detections updating and main application working on the video output.

In the code below I’ve removed some of the code from my main application and only showed the major steps where I’m creating the image array and writing the image array to a video file. I hope this helps make debugging easier as I’ve removed unrelated code.

    bool detection_found = false;   // If a detection is found. 
    bool record_done = false;       // Indicates if recording is finished.
    float record_seconds = 5.0;     // amount of seconds to record.
    float cooldown_time = 0.0;      // Time to cooldown after recording.
    int number_frames = record_seconds * framerate;        // Number of frames in recording time.
    cv::Mat image_array[number_frames];     // Array of images containing the video.
    int frame_idx = 0;              // Current frame index, used for saving images.

    const uint32_t overlay_flags = detectNet::OverlayFlagsFromStr("box,labels,conf");

    while(!signal_received)
    {

        img_grabbed = cap.read(img);

        if(img_grabbed == true)
        {
        
            const int numDetections = net->Detect(img_buffer, (uint32_t) capture_width,(uint32_t) capture_height, &detections, overlay_flags);

            if(numDetections > 0 && detection_found == false)
            {
                detection_found = true;

            }

            if(detection_found == true && numDetections > 0)
            {
                printf("Saved image! %i\n", frame_idx);
                image_array[frame_idx] = img;
                if(frame_idx == number_frames - 1)
                {
                    record_done = true;
                }
                frame_idx += 1;
            }

            if(record_done == true)
            {
		printf("starting video write...\n");
                CV_WRAP static int fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
                cv::VideoWriter video("test.avi", fourcc, (double) number_frames/record_seconds, cv::Size(capture_width, capture_height), true);
                //cv::VideoWriter video("test.avi", fourcc, (double) framerate, cv::Size(860, 640), true);

                for(int i = 0; i < number_frames; ++i)
                {
                    video.write(image_array[i]);
                }
                detection_found = false;
                frame_idx = 0;
                record_done = false;

                video.release();
                printf("############# RECORDING DONE ##############\n");
            }
        }

To help debug, I think the issue has to do with variable image_array and function video.write()

Thank you!

Hi,
A general solution is to run gstreamer pipelines in cv2.VideoCapture() and cv2.VideoWriter(). Please take a look at
Displaying to the screen with OpenCV and GStreamer - #9 by DaneLLL

See if you can run it successfully and customize it to run your use-case.

@DaneLLL
Thanks for the guidance.
Using the gstreamer pipeline helps performance by a lot. The video is created much faster. However oddly enough the solution didn’t have to do with the pipeline. All I needed to do was clear the image variable I was using after each iteration in my loop. Now I can save video. I also did some optimization with some image variables in my code and am getting about 40 FPS now while detections are occurring on the nano.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.