How to quickly acquire and process real time screen output
        Posted  
        
            by Akusete
        on Stack Overflow
        
        See other posts from Stack Overflow
        
            or by Akusete
        
        
        
        Published on 2010-06-07T00:38:59Z
        Indexed on 
            2010/06/07
            0:42 UTC
        
        
        Read the original article
        Hit count: 616
        
I am trying to write a program to play a full screen PC game for fun (as an experiment in Computer Vision and Artificial Intelligence).
For this experiment I am assuming the game has no underlying API for AI players (nor is the source available) so I intend to process the visual information rendered by the game on the screen.
The game runs in full screen mode on a win32 system (direct-X I assume).
Currently I am using the win32 functions
#include <windows.h>
#include <cvaux.h>
class Screen {
    public:
    HWND    windowHandle;
    HDC     windowContext;
    HBITMAP buffer;
    HDC     bufferContext;
    CvSize  size;
    uchar*  bytes;
    int channels;
Screen () {
    windowHandle = GetDesktopWindow();
    windowContext   = GetWindowDC (windowHandle);
    size = cvSize (GetDeviceCaps (windowContext, HORZRES), GetDeviceCaps (windowContext, VERTRES));
    buffer = CreateCompatibleBitmap (windowContext, size.width, size.height);
    bufferContext = CreateCompatibleDC (windowContext);
    SelectObject (bufferContext, buffer);
    channels = 4;
    bytes = new uchar[size.width * size.height * channels];
}
~Screen () {
    ReleaseDC(windowHandle, windowContext);
    DeleteDC(bufferContext);
    DeleteObject(buffer);
    delete[] bytes;
}
void CaptureScreen (IplImage* img) {
    BitBlt(bufferContext, 0, 0, size.width, size.height, windowContext, 0, 0, SRCCOPY);
    int n = size.width * size.height;
    int imgChannels = img->nChannels;
    GetBitmapBits (buffer, n * channels, bytes); 
    uchar* src = bytes;
    uchar* dest = (uchar*) img->imageData;
    uchar* end  = dest + n * imgChannels;
    while (dest < end) {
        dest[0] = src[0];
        dest[1] = src[1];
        dest[2] = src[2];
        dest  += imgChannels;
        src += channels;
    }
}
The rate at which I can process frames using this approach is much to slow. Is there a better way to acquire screen frames?
© Stack Overflow or respective owner