Write frames with non-standard resolution to video in opencv

筅森魡賤 提交于 2019-12-11 01:56:33

问题


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)

回答1:


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.




回答2:


cv2.VideoWriter("video_out.avi", fourcc, 25, (173, 99)) creates a writer for frames of size 173x99 (width x height).

frame_out is a frame of size 99x173 (frame is indexed [y, x]).

Change the indexing to write matching frame sizes.




回答3:


In OSX environment:

  • OSX: High Sierra (10.13.6)
  • Python: 3.6.3
  • Open CV (using prebuilt python pck): opencv-python-headless 4.1.0.25

The only combination that worked for me was mp4 wrapper (OSX doesn't love avi) and mp4v codec. Also tried avc1 but it wouldn't write a non standard sized frame

codec = 'mp4v'
fourcc = cv2.VideoWriter_fourcc(*codec)
size = ( 1000 , 500 )
fps = 15
writer = cv2.VideoWriter('filename.mp4', fourcc, fps, size, True)


来源:https://stackoverflow.com/questions/50983996/write-frames-with-non-standard-resolution-to-video-in-opencv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!