猿问

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

我想使用OpenCV处理桌面,就好像它是视频流一样。

我熟悉OpenCV。

我不熟悉Windows API。我意识到还有其他捕获屏幕的方法,但是出于我的问题,我需要使用OpenCV来完成。


这是我的(超级天真)代码:


HWND hDesktopWnd;

HDC hDesktopDC;

hDesktopWnd=GetDesktopWindow();

hDesktopDC=GetDC(hDesktopWnd);


// get the height and width of the screen

int height = GetSystemMetrics(SM_CYVIRTUALSCREEN);

int width = GetSystemMetrics(SM_CXVIRTUALSCREEN);


// create a bitmap

HBITMAP hbDesktop = CreateCompatibleBitmap( hDesktopDC, width, height);


Mat src(height,width,CV_8UC4);

src.data = (uchar*)hbDesktop;


imshow("output",src);  //fails :(

在StackOverflow上也有类似的问题,但这些问题要么针对旧式OpenCV,要么针对Android操作系统。

我在Windows 7 64x

Opencv 2.4.3上


感谢任何可以回答这个问题的人。


慕妹3242003
浏览 2474回答 3
3回答

Helenr

一种更好的方法是在将内存分配给像素一次的同时执行此操作。所以这里唯一要做的就是BitBlt制作的副本int main(){&nbsp; &nbsp; int x_size = 800, y_size = 600; // <-- Your res for the image&nbsp; &nbsp; HBITMAP hBitmap; // <-- The image represented by hBitmap&nbsp; &nbsp; Mat matBitmap; // <-- The image represented by mat&nbsp; &nbsp; // Initialize DCs&nbsp; &nbsp; HDC hdcSys = GetDC(NULL); // Get DC of the target capture..&nbsp; &nbsp; HDC hdcMem = CreateCompatibleDC(hdcSys); // Create compatible DC&nbsp;&nbsp; &nbsp; void *ptrBitmapPixels; // <-- Pointer variable that will contain the potinter for the pixels&nbsp; &nbsp; // Create hBitmap with Pointer to the pixels of the Bitmap&nbsp; &nbsp; BITMAPINFO bi; HDC hdc;&nbsp; &nbsp; ZeroMemory(&bi, sizeof(BITMAPINFO));&nbsp; &nbsp; bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);&nbsp; &nbsp; bi.bmiHeader.biWidth = x_size;&nbsp; &nbsp; bi.bmiHeader.biHeight = -y_size;&nbsp; //negative so (0,0) is at top left&nbsp; &nbsp; bi.bmiHeader.biPlanes = 1;&nbsp; &nbsp; bi.bmiHeader.biBitCount = 32;&nbsp; &nbsp; hdc = GetDC(NULL);&nbsp; &nbsp; hBitmap = CreateDIBSection(hdc, &bi, DIB_RGB_COLORS, &ptrBitmapPixels, NULL, 0);&nbsp; &nbsp; // ^^ The output: hBitmap & ptrBitmapPixels&nbsp; &nbsp; // Set hBitmap in the hdcMem&nbsp;&nbsp; &nbsp; SelectObject(hdcMem, hBitmap);&nbsp; &nbsp; // Set matBitmap to point to the pixels of the hBitmap&nbsp; &nbsp; matBitmap = Mat(y_size, x_size, CV_8UC4, ptrBitmapPixels, 0);&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ^^ note: first it is y, then it is x. very confusing&nbsp; &nbsp; // * SETUP DONE *&nbsp; &nbsp; // Now update the pixels using BitBlt&nbsp; &nbsp; BitBlt(hdcMem, 0, 0, x_size, y_size, hdcSys, 0, 0, SRCCOPY);&nbsp; &nbsp; // Just to do some image processing on the pixels.. (Dont have to to this)&nbsp; &nbsp; Mat matRef = matBitmap(Range(100, 200), Range(100, 200));&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y1&nbsp; &nbsp; y2&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x1&nbsp; &nbsp; &nbsp;x2&nbsp; &nbsp; bitwise_not(matRef, matRef); // Invert the colors in this x1,x2,y1,y2&nbsp; &nbsp; // Display the results through Mat&nbsp; &nbsp; imshow("Title", matBitmap);&nbsp; &nbsp; // Wait until some key is pressed&nbsp; &nbsp; waitKey(0);&nbsp; &nbsp; return 0;}请注意,这里没有进行错误处理以使其易于理解,但是您必须在代码中进行错误处理!希望这可以帮助

叮当猫咪

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