Получение кадров из Chrome (простая игра) и их отображение с помощью OpenCV - PullRequest
0 голосов
/ 28 августа 2018

Я искал способы отображения простой игры в реальном времени в небольшом окне и понял, что OpenCV может справиться с этим для меня. Но для этого мне нужно получать кадры на каждой итерации, перед тем, как показывать их в нужном окне.

Это текущее решение, которое я использую:

HDC hwindowDC;
HDC hwindowCompatibleDC;    // Memory for given DC 

HBITMAP hbwindow;

int height, width;

//  handles information about DIB (device-independent bitmap)
//  https://docs.microsoft.com/en-us/windows/desktop/gdi/device-independent-bitmaps
BITMAPINFOHEADER  bi;   

//  retrieces a handle to DC for the client area for entire screen
hwindowDC = GetDC(NULL);

//  creates memory DC for the entire screen
hwindowCompatibleDC = CreateCompatibleDC(hwindowDC);    

//  enables strecn mode which has low costs - because of the grayscale game
SetStretchBltMode(hwindowCompatibleDC, COLORONCOLOR);

//  size of the game window - according to the inspect of the game within chrome
height = 150;
width = 600;

//  creates matrix with four color channels and values in the range 0 to 255
//  -   https://stackoverflow.com/questions/39543580/what-is-the-purpose-of-cvtype-cv-8uc4
frame.create(height, width, CV_8UC4);

// create a bitmap for the window
hbwindow = CreateCompatibleBitmap(hwindowDC, width, height);

bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = -height;  //the minus sign 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;

// attach the bitmap with the memory DC for our window
SelectObject(hwindowCompatibleDC, hbwindow);

// copy from the window device context to the bitmap device context
StretchBlt(hwindowCompatibleDC, 0, 0, width, height, hwindowDC, 650, 130, 620, 150, SRCCOPY); //change SRCCOPY to NOTSRCCOPY for wacky colors !

// Gets the "bits" from the bitmap and copies them into src.data
GetDIBits(hwindowCompatibleDC, hbwindow, 0, height, frame.data, (BITMAPINFO *)&bi, DIB_RGB_COLORS);  //copy from hwindowCompatibleDC to hbwindow

// avoid memory leak                                                                                               // avoid memory leak
DeleteObject(hbwindow);
DeleteDC(hwindowCompatibleDC);  //  for any DC that was created by calling the CreateDC function
ReleaseDC(hwnd, hwindowDC);     // releasing the DC for use of other applications (MUST)

img2 = frame;
//img1 = frame;

return frame;

После попытки выяснить, как сделать игру более гладкой, я попытался реализовать средство записи экрана с помощью DirectX API, но безуспешно. Этот код приводит к черному экрану.

IDirect3DSurface9* pSurface;
d3ddev->CreateOffscreenPlainSurface(100, 100,
    D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL);
d3ddev->GetFrontBufferData(NULL , pSurface);

/*D3DLOCKED_RECT lockedRect;
ZeroMemory(&lockedRect, sizeof(D3DLOCKED_RECT));
pSurface->LockRect(&lockedRect, 0, D3DLOCK_READONLY);
*/
LPD3DXBUFFER buffer;
D3DXSaveSurfaceToFileInMemory(&buffer, D3DXIFF_BMP, pSurface, NULL, NULL);
DWORD imSize = buffer->GetBufferSize();
void* imgBuffer = buffer->GetBufferPointer();
//**** OpenCV

Mat D3DSurface(100, 100, CV_8UC4, imgBuffer);

imshow("D3DSurface", D3DSurface);
pSurface->Release();
return D3DSurface;

Может ли кто-нибудь помочь мне разобраться, как лучше выполнить эту задачу? Я просто думаю, что есть кое-что, что я не совсем понимаю в этом процессе, зеркальное отображение живой движущейся игры в желаемое окно с минимальными задержками.

Моя цель - сделать бота для онлайн-игры.

...