opencv 4.0无法保存视频

时间:2018-12-31 07:28:53

标签: c++ windows opencv

我试图记录我的桌面屏幕,并使用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;
}

2 个答案:

答案 0 :(得分:1)

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

也请启用警告,因为编译器通常会完全告诉您。

答案 1 :(得分:0)

使用* .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 failed\n";
        return 0;
    }

    while(GetAsyncKeyState(VK_ESCAPE) == 0)
    {
        cout << ".";
        hwnd2mat(frame);
        video.write(frame);
        Sleep(int(1000.0/fps));
    }

    video.release();
    cout << "\nreleased\n";

    return 0;
}