0

I tried capturing a part of the screen and put it in a cv::Mat, the output is the same color (when i captured a white background it is white, when gray it is gray so you can understand it does function to some degree) but the image is fuzzy, aligned and repetitive (it repeats the same pixels).

For example, upon writing this question in my Chrome browser I tried the program and the result was: fuzzy output

You can recognize the browser (the URL-bar, the text box and buttons and so on. But the image itself is far from accurate or even close, and the pixels are repetitive when they shouldn't be (url bar repeats itself, text box and so on).

The code in this question did not compile on my machine. But I know that the code I used (not the OpenCV part) works on my machine (I already used it to capture my screen and it worked perfectly when I saved it with libpng).

My code is as follows (the variables which aren't declared here are declared elsewhere and which value is correct, i checked, such as x, w, h etc.):

    HDC hdcSource = GetDC(NULL);
    HDC hdcMemory = CreateCompatibleDC(hdcSource);
    HBITMAP hBitmap = CreateCompatibleBitmap(hdcSource, w, h);
    HBITMAP hBitmapOld = (HBITMAP)SelectObject(hdcMemory, hBitmap);
    BITMAPINFOHEADER bmi = { 0 };
    bmi.biSize = sizeof(BITMAPINFOHEADER);
    bmi.biPlanes = 1;
    bmi.biBitCount = 24;

    bmi.biWidth = w;
    bmi.biHeight = -h;
    bmi.biCompression = BI_RGB;

    bmi.biSizeImage = ((bmi.biWidth * bmi.biBitCount + 31) & ~31) / 8 * bmi.biHeight<0 ? -bmi.biHeight : bmi.biHeight;
    bmi.biXPelsPerMeter = 0;
    bmi.biYPelsPerMeter = 0;
    bmi.biClrImportant = 0;
    bmi.biClrUsed = 256;

    if (!(BitBlt(hdcMemory, 0, 0, w, h, hdcSource, p1.x, p1.y, SRCCOPY)))
    {
        exit(1);
    }
    hBitmap = (HBITMAP)SelectObject(hdcMemory, hBitmapOld);
    if (!hBitmap)
    {
        exit(1);
    }

    my_pic.create(h, w, CV_8UC4);

    //StretchBlt(hdcSource, 0, 0, w, h, GetDC(NULL), 0, 0, w, h, SRCCOPY); //This line is what I saw in the other question but it didn't help

    if (!(GetDIBits(hdcSource, hBitmap, 0, h, my_pic.data, (BITMAPINFO*)&bmi, DIB_RGB_COLORS)))
    {
        exit(1);
    }
    DeleteDC(hdcSource);
    DeleteDC(hdcMemory);
Community
  • 1
  • 1
Jim
  • 125
  • 1
  • 8

1 Answers1

1

You have RGB format for bitmap pixels, but you trying to fit it to CV_8UC4 (four channel) matrix. Try to use CV_8UC3 matrix type.

Andrey Smorodov
  • 10,649
  • 2
  • 35
  • 42
  • PERFECT! Thank you so much, I can't believe I didn't notice it. Somehow, when I call it too often it is a aligned for some sort of reason like [here](http://postimg.org/image/g3nrcla1d/), but most of the times (after I let the computer 'rest' a couple of seconds without executing the code) it can come up as expected like [this](http://postimg.org/image/6nnedepad/) for a couple of times executing it in a row (say 5 times). Any idea why would that be? The only thing I think could change is maybe concluding memory but how would that affect the picture and make it aligned? Any idea? – Jim Dec 22 '15 at 19:42
  • Opencv uses alignment so you need to align rows in memory. Look in the web there are a lot of implementations. Mat to bitmap convertors. – Andrey Smorodov Dec 22 '15 at 20:45
  • Take a look hee for instance: http://answers.opencv.org/question/64896/how-to-fix-resized-image-in-mfc/ – Andrey Smorodov Dec 22 '15 at 21:12