OPENCV Desktop Capture

前端 未结 3 464
鱼传尺愫
鱼传尺愫 2020-12-21 13:05

How to capture the desktop in OpenCV (ie. turn a bitmap into a Mat)?

Hello,

Can anyone explain to me how I would use this code in OpenCV to capture the deskt

相关标签:
3条回答
  • 2020-12-21 13:38

    It seems you forgot to capture the return of hwnd2mat():

    HWND hwndDesktop = GetDesktopWindow();
    Mat src = hwnd2mat(hwndDesktop);
    imshow("output", src);
    waitKey(0);
    
    0 讨论(0)
  • 2020-12-21 13:55

    I would make hwnd2mat a little bit more specific and address Stepan Yakovenko's comment by adding definition and references to "valueOfChangeTheSizeOfTextAppsAndOtherItemsInWindowsDisplaySettings".

    Mat hwnd2mat(HWND hwnd)
    {
         HDC hwindowDC,hwindowCompatibleDC;
    
         int height,width,srcheight,srcwidth;
         HBITMAP hbwindow;
         Mat src;
         BITMAPINFOHEADER  bi;
    
         hwindowDC=GetDC(hwnd);
         hwindowCompatibleDC=CreateCompatibleDC(hwindowDC);
         SetStretchBltMode(hwindowCompatibleDC,COLORONCOLOR);
    
         RECT windowsize;    // get the height and width of the screen
         GetClientRect(hwnd, &windowsize);
    
         float valueOfChangeTheSizeOfTextAppsAndOtherItemsInWindowsDisplaySettings = 1.5;
         srcheight = (int)((float)windowsize.bottom * valueOfChangeTheSizeOfTextAppsAndOtherItemsInWindowsDisplaySettings);
         srcwidth = (int)((float)windowsize.right * valueOfChangeTheSizeOfTextAppsAndOtherItemsInWindowsDisplaySettings);
         height = windowsize.bottom/1;  //change this to whatever size you want to resize to
         width = windowsize.right/1;
    
         src.create(height,width,CV_8UC4);
    
         // create a bitmap
         hbwindow = CreateCompatibleBitmap( hwindowDC, width, height);
         bi.biSize = sizeof(BITMAPINFOHEADER);    //http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
         bi.biWidth = width;
         bi.biHeight = -height;  //this is the line that makes it draw upside down or not
         bi.biPlanes = 1;
         bi.biBitCount = 32;
         bi.biCompression = BI_RGB;
         bi.biSizeImage = 0;
         bi.biXPelsPerMeter = 0;
         bi.biYPelsPerMeter = 0;
         bi.biClrUsed = 0;
         bi.biClrImportant = 0;
    
         // use the previously created device context with the bitmap
         SelectObject(hwindowCompatibleDC, hbwindow);
         // copy from the window device context to the bitmap device context
         StretchBlt( hwindowCompatibleDC, 0,0, width, height, hwindowDC, 0, 0,srcwidth,srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
         GetDIBits(hwindowCompatibleDC,hbwindow,0,height,src.data,(BITMAPINFO *)&bi,DIB_RGB_COLORS);  //copy from hwindowCompatibleDC to hbwindow
    
         // avoid memory leak
         DeleteObject (hbwindow);
         DeleteDC(hwindowCompatibleDC);
         ReleaseDC(hwnd, hwindowDC);
    
         return src;
     }
    

    0 讨论(0)
  • 2020-12-21 13:58

    upon OP's comment i think there is still a need to explain how to capture desktop like a video stream

    #include "opencv2/imgproc.hpp"
    #include "opencv2/highgui.hpp"
    #include <Windows.h>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    Mat hwnd2mat(HWND hwnd)
    {
        HDC hwindowDC,hwindowCompatibleDC;
    
        int height,width,srcheight,srcwidth;
        HBITMAP hbwindow;
        Mat src;
        BITMAPINFOHEADER  bi;
    
        hwindowDC=GetDC(hwnd);
        hwindowCompatibleDC=CreateCompatibleDC(hwindowDC);
        SetStretchBltMode(hwindowCompatibleDC,COLORONCOLOR);
    
        RECT windowsize;    // get the height and width of the screen
        GetClientRect(hwnd, &windowsize);
    
        srcheight = windowsize.bottom;
        srcwidth = windowsize.right;
        height = windowsize.bottom/1;  //change this to whatever size you want to resize to
        width = windowsize.right/1;
    
        src.create(height,width,CV_8UC4);
    
        // create a bitmap
        hbwindow = CreateCompatibleBitmap( hwindowDC, width, height);
        bi.biSize = sizeof(BITMAPINFOHEADER);    //http://msdn.microsoft.com/en-us/library/windows/window/dd183402%28v=vs.85%29.aspx
        bi.biWidth = width;
        bi.biHeight = -height;  //this is the line that makes it draw upside down or not
        bi.biPlanes = 1;
        bi.biBitCount = 32;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = 0;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;
    
        // use the previously created device context with the bitmap
        SelectObject(hwindowCompatibleDC, hbwindow);
        // copy from the window device context to the bitmap device context
        StretchBlt( hwindowCompatibleDC, 0,0, width, height, hwindowDC, 0, 0,srcwidth,srcheight, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !
        GetDIBits(hwindowCompatibleDC,hbwindow,0,height,src.data,(BITMAPINFO *)&bi,DIB_RGB_COLORS);  //copy from hwindowCompatibleDC to hbwindow
    
        // avoid memory leak
        DeleteObject (hbwindow);
        DeleteDC(hwindowCompatibleDC);
        ReleaseDC(hwnd, hwindowDC);
    
        return src;
    }
    
    int main(int argc, char **argv)
    {
        HWND hwndDesktop = GetDesktopWindow();
        namedWindow("output",WINDOW_NORMAL);
        int key = 0;
    
        while( key != 27 )
        {
            Mat src = hwnd2mat(hwndDesktop);
            // you can do some image processing here
            imshow("output", src);
            key = waitKey(60); // you can change wait time
        }
    
    }
    

    EDIT: you can find a sample code for screen capturing and saving as a video here

    0 讨论(0)
提交回复
热议问题