为了账号安全,请及时绑定邮箱和手机立即绑定

如何在OpenCV中捕获桌面(即,将位图转换为Mat)?

如何在OpenCV中捕获桌面(即,将位图转换为Mat)?

慕妹3242003 2019-11-12 10:33:18
我想使用OpenCV处理桌面,就好像它是视频流一样。我熟悉OpenCV。我不熟悉Windows API。我意识到还有其他捕获屏幕的方法,但是出于我的问题,我需要使用OpenCV来完成。这是我的(超级天真)代码:HWND hDesktopWnd;HDC hDesktopDC;hDesktopWnd=GetDesktopWindow();hDesktopDC=GetDC(hDesktopWnd);// get the height and width of the screenint height = GetSystemMetrics(SM_CYVIRTUALSCREEN);int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);// create a bitmapHBITMAP hbDesktop = CreateCompatibleBitmap( hDesktopDC, width, height);Mat src(height,width,CV_8UC4);src.data = (uchar*)hbDesktop;imshow("output",src);  //fails :(在StackOverflow上也有类似的问题,但这些问题要么针对旧式OpenCV,要么针对Android操作系统。我在Windows 7 64xOpencv 2.4.3上感谢任何可以回答这个问题的人。
查看完整描述

3 回答

?
Helenr

TA贡献1780条经验 获得超3个赞

一种更好的方法是在将内存分配给像素一次的同时执行此操作。所以这里唯一要做的就是BitBlt制作的副本

int main()


{


    int x_size = 800, y_size = 600; // <-- Your res for the image






    HBITMAP hBitmap; // <-- The image represented by hBitmap


    Mat matBitmap; // <-- The image represented by mat






    // Initialize DCs


    HDC hdcSys = GetDC(NULL); // Get DC of the target capture..

    HDC hdcMem = CreateCompatibleDC(hdcSys); // Create compatible DC 







    void *ptrBitmapPixels; // <-- Pointer variable that will contain the potinter for the pixels










    // Create hBitmap with Pointer to the pixels of the Bitmap

    BITMAPINFO bi; HDC hdc;

    ZeroMemory(&bi, sizeof(BITMAPINFO));

    bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    bi.bmiHeader.biWidth = x_size;

    bi.bmiHeader.biHeight = -y_size;  //negative so (0,0) is at top left


    bi.bmiHeader.biPlanes = 1;


    bi.bmiHeader.biBitCount = 32;

    hdc = GetDC(NULL);

    hBitmap = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &ptrBitmapPixels, NULL, 0);

    // ^^ The output: hBitmap & ptrBitmapPixels



    // Set hBitmap in the hdcMem 

    SelectObject(hdcMem, hBitmap);




    // Set matBitmap to point to the pixels of the hBitmap

    matBitmap = Mat(y_size, x_size, CV_8UC4, ptrBitmapPixels, 0);

    //                ^^ note: first it is y, then it is x. very confusing


    // * SETUP DONE *





    // Now update the pixels using BitBlt

    BitBlt(hdcMem, 0, 0, x_size, y_size, hdcSys, 0, 0, SRCCOPY);



    // Just to do some image processing on the pixels.. (Dont have to to this)

    Mat matRef = matBitmap(Range(100, 200), Range(100, 200));

    //                              y1    y2            x1     x2

    bitwise_not(matRef, matRef); // Invert the colors in this x1,x2,y1,y2





    // Display the results through Mat

    imshow("Title", matBitmap);


    // Wait until some key is pressed


    waitKey(0);



    return 0;



}

请注意,这里没有进行错误处理以使其易于理解,但是您必须在代码中进行错误处理!


希望这可以帮助


查看完整回答
反对 回复 2019-11-12
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

值得注意的是,如果上面的代码在可重复使用的场景(例如循环)中使用,从长远来看,将导致内存泄漏并泛滥您的堆内存/崩溃应用程序。您必须调用DeleteObject(hBitmap); 和matBitmap.release()处理完图像后。

查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 2326 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信