Search code examples
pythonopencvvideo-recording

Write frames with non-standard resolution to video in opencv


Relating to this question: OpenCV VideWriter not working after image resize

Is it possible to create videos with opencv's cv2.VideoWriter that have "non-standard" video resolutions, i.e., non-standard aspect ratios? My code so far:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
video_out = cv2.VideoWriter("video_out.avi", fourcc, 25, (99, 173))

cap = cv2.VideoCapture("video_in.avi")

while(cap.isOpened()):
    ret, frame = cap.read()
    frame_out = frame[50:50+173,400:400+99]      
    video_out.write(frame_out) 
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

I have tried other video formats (H264, MJPG) as well, no success.

EDIT: No success meaning that the output video gets created, but remains empty. If I use the original frame size the frames do get written to video.

EDIT: Micka's answer works, but I got my python code to run now as well: the boolean argument for coloured video output was missing.

   video_out = cv2.VideoWriter("video_out.avi", fourcc, 25, (99, 173), False)

Solution

  • For me, this code does work, but MJPG does round the odd resolution to an even resolution. H264 did not work with that resolution at all.

    int main(int argc, char* argv[])
    {
        // start camera
        cv::VideoCapture cap(0);
    
        // read a single image to find camera resolution
        cv::Mat image;
        cap >> image;
        if (image.empty())
        {
            std::cout << "Could not find/open camera. Press Enter to exit." << std::endl;
            std::cin.get();
            return 0;
        }
    
        cv::Size targetSize(199, 171);
        cv::VideoWriter writer("out.avi", CV_FOURCC('M','J','P','G'), 25, targetSize, true); // does create a 198x170 video file.
        //cv::VideoWriter writer("out.avi", -1, 25, targetSize, true); // does not work for x264vfw for example with an error message.
    
    
        while (cv::waitKey(30) != 'q')
        {
            cap >> image;
            if (!image.empty())
            {
                cv::imshow("captured image", image);
    
                // resize the actual image to a target size
                cv::Mat writableImage;
                cv::resize(image, writableImage, targetSize);
    
                writer.write(writableImage);
            }
        }
    
    
        // release the camera
        cap.release();
        writer.release();
    
        std::cout << "Press Enter to exit." << std::endl;
        std::cin.get();
    
        return 0;
    }
    

    In general, many codecs are restricted to some pixel-block-constraints like having a multiple of 2, 4, 8, 16 or 32 in each dimension. Either because of the algorithm itself or some hardware instruction optimizations.