Что я сделал
У меня есть небольшое изображение шаблона, которое предназначено для поиска координат совпадающих субизображений в более крупном скриншоте. Сам снимок экрана записывается в контроллер домена памяти с помощью BitBlt
, затем преобразуется в cv::Mat
с помощью GetDIBits
, например:
HDC windowDc = GetWindowDC(hwndTarget);
HDC memDc = CreateCompatibleDC(windowDc);
// ...
HBITMAP hbmp = CreateCompatibleBitmap(windowDc, width, height);
SelectObject(memDc, hbmp);
BITMAPINFOHEADER bi =
{
sizeof(BITMAPINFOHEADER), // biSize
width, // biWidth
-height, // biHeight
1, // biPlanes
32, // biBitCount
BI_RGB, // biCompression
0, // biSizeImage
0, // biXPelsPerMeter
0, // biYPelsPerMeter
0, // biClrUser
0 // biClrImportant
};
// ...
BitBlt(memDc, 0, 0, width, height, windowDc, offsetX, offsetY, SRCCOPY);
matScreen.create(height, width, CV_8UC4);
GetDIBits(memDc, hbmp, 0, (UINT)height, matScreen.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
Кажется, это работает нормально, и быстрый imshow("Source", matScreen)
отображает изображение правильно.
Тем не мение...
Поскольку этот снимок экрана был создан как 32-битная растровая карта памяти RGB и помещен внутри cv::Mat
с использованием флага CV_8UC4
, он не проходит несколько утверждений в OpenCV (а также выводит странные результаты при использовании нескольких методов OpenCV). В частности, matchTemplate
всегда терпит неудачу в следующей строке:
CV_Assert( (depth == CV_8U || depth == CV_32F) && type == _templ.type() && _img.dims() <= 2 );
Я пытался сопоставить флаги глубины снимка экрана и матов шаблона/результата, и в лучшем случае я могу отобразить все 3 изображения, но сопоставление шаблона не работает, потому что я предполагается, что исходное изображение (скриншот) отображается в цвете, а остальные — в оттенках серого. Другие преобразования либо терпят неудачу, либо отображают странные результаты и не соответствуют шаблону (или просто вызывают ошибку)... И изменение Mat
изображения скриншота для использования любого другого флага глубины приводит к неправильному отображению изображения.
Вопрос
Что я могу сделать, чтобы использовать шаблон OpenCV, соответствующий снимку экрана, сделанному на С++? Есть ли какое-то ручное преобразование, которое я должен сделать для изображения скриншота, или что-то в этом роде?
Код:
Код скриншота взят из: github.com/acdx/opencv-screen-capture
Мой основной код: codeshare.io/vLio1
CV_8UC4
кажется единственным флагом, который правильно отображает исходное изображение... Так что, возможно, есть способ преобразовать растровое изображение для работы, скажем, сCV_32F
? - person RectangleEquals   schedule 24.04.2015