OpenCV 4.0 无法保存视频

opencv 4.0 can't save video

本文关键字:保存 视频 OpenCV      更新时间:2023-10-16

我正在尝试录制我的桌面屏幕并使用opencv videoWriter将其保存到视频中,但最终总是有一个甚至无法播放的6kb视频。

这是我的代码,

我首先为屏幕创建 mat 对象,然后将它们写入文件。

#include "pch.h"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> 
#include <iostream>
#include <stdio.h>
#include <opencv2/objdetect/objdetect.hpp>
#include <Windows.h>
using namespace std;
using namespace cv;

int height;
int width;
Mat hwnd2mat()
{
  // returning Mat object for screen and working fine as I'm showing it into a window
}

void CaptureScreen()
{
    int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
    int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
    HWND hDesktopWnd = GetDesktopWindow();
    int key = 0;
    string filename = "D:/outcpp.avi";
    cv::Size targetSize = cv::Size(320, 240);
    VideoWriter video(filename, cv::VideoWriter::fourcc('M', 'J', 'P', 'G'), 10, targetSize);
    while (1)
    {
        Mat frame = hwnd2mat();
        cv::Mat image = frame;
        cv::Mat dst;
        cv::resize(image, dst, targetSize);
        if (dst.empty())
            break;
        video.write(dst);
        imshow("Frame", dst);
        char c = (char)waitKey(1);
        if (c == 27)
            break;
    }
    video.release();
    destroyAllWindows();
    //readVideo(filename);
}


int main(int argc, char **argv)
{
    CaptureScreen();
    return 0;
}

您正在调用一个函数,该函数根据其签名返回某些内容,但实际上没有。这会导致根据C++标准定义的行为,因此您的程序存在错误。

还请启用警告,因为编译器通常会准确地告诉您。

使用 *.mp4 尝试不同的 fourcc 代码,无论如何都更好,并在不显示图像的情况下运行。确保视频已成功打开和发布。

void hwnd2mat(cv::Mat &mat)
{
    int w = mat.cols;
    int h = mat.rows;
    auto hdc = GetDC(0);
    auto memdc = CreateCompatibleDC(hdc);
    auto hbitmap = CreateCompatibleBitmap(hdc, w, h);
    auto holdbmp = SelectObject(memdc, hbitmap);
    BitBlt(memdc, 0, 0, w, h, hdc, 0, 0, SRCCOPY);
    BITMAPINFOHEADER bi = { sizeof(bi), w, -h, 1, 24 };
    GetDIBits(hdc, hbitmap, 0, h, mat.data, (BITMAPINFO*)&bi, 0);
    SelectObject(memdc, holdbmp);
    DeleteDC(memdc);
    DeleteObject(hbitmap);
    ReleaseDC(0, hdc);
}
int main()
{
    int w = GetSystemMetrics(SM_CXSCREEN);
    int h = GetSystemMetrics(SM_CYSCREEN);
    cv::Size size = cv::Size(w, h);
    Mat frame(size, CV_8UC3);
    double fps = 10.0;
    //string filename = "d:\outcpp.avi";
    //auto fourcc = cv::VideoWriter::fourcc('M', 'J', 'P', 'G');
    string filename = "d:\outcpp.mp4";
    auto fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v');
    VideoWriter video(filename, fourcc, fps, frame.size());
    if(!video.isOpened())
    {
        cout << "codec failedn";
        return 0;
    }
    while(GetAsyncKeyState(VK_ESCAPE) == 0)
    {
        cout << ".";
        hwnd2mat(frame);
        video.write(frame);
        Sleep(int(1000.0/fps));
    }
    video.release();
    cout << "nreleasedn";
    return 0;
}