Конвертировать HBITMAP в cv :: Mat - PullRequest
0 голосов
/ 09 августа 2011

Кажется, я не могу понять, как это сделать, я искал в Google и нашел два примера кода, один из библиотеки захвата экрана github и другой в группе сообщений, и ни один из них, похоже, не работает.

У меня есть структура:

struct ClacksScreen
{
    HWND hDesktopWnd; 
    int width, height;
    RECT wr, cr;
    HDC hdcClacksScreen; // hardware ClacksScreen
    HDC hdcMemDC; // ClacksScreen in memory
    HBITMAP hbmClacksScreen; //hbitmap of the ClacksScreen
    BITMAP bmpClacksScreen;
    BITMAPINFOHEADER bi;
};

Это обновлено.У меня определены некоторые функции, в том числе та, которая записывает растровое изображение на диск, все работает нормально, снимок экрана и запись bmp на диск, и это именно то, что я хотел.

Теперь я хочу преобразовать HBITMAPЯ беру экран прямо в cv :: Mat для OpenCV2.1.

Это вроде работает, за исключением того, что изображение чисто серое и оно вылетает.Очевидно, я все еще довольно n00b, когда дело доходит до c ++, так что, вероятно, есть кое-что простое, что я просто не ворчу.

static cv::Mat copyToCVMat(const ClacksScreen * s)
{
    cv::Mat image;
    image.create(s->bmpClacksScreen.bmWidth, s->bmpClacksScreen.bmHeight, CV_8UC4);
    GetDIBits(s->hdcMemDC, s->hbmClacksScreen, 0,
            (UINT)s->bmpClacksScreen.bmHeight,
            image.data,
            (BITMAPINFO *)&s->bi, DIB_RGB_COLORS);
    return image;
}

Когда я оборачиваю cv :: imwrite (image);в попытке поймать я получаю ошибку распределения.Очевидно, что в этот момент мы установили, что я не знаю, как это сделать, поэтому любая помощь будет признательна.

ОБНОВЛЕНИЕ

Если я запускаю этот код:

try {
    cv::Mat screen = cv::imread("captureqwsx.jpg");
    if (!screen.data) {
        printf("no image data?");
    }
    cv::imwrite("out.jpg",screen);
} catch(std::exception e) {
    printf("Exception %s\n",e.what());
}

Я получаю вывод:

нет данных изображения?Неправильное распределение исключений

Когда я пытаюсь запустить высокий графический интерфейс, он остается таким же, как и раньше, возникает проблема как для файлов .jpg и .bmps, записанных на диск, которые можно просматривать в средстве просмотра изображений и в MS Paint.

Я попробовал с совершенно другим изображением, .png с веб-сайта, та же проблема.

Так, что я делаю не так в этот момент?

Ответы [ 3 ]

1 голос
/ 04 января 2013

Я написал свою собственную функцию для выполнения чего-то подобного, надеюсь, она может вам помочь: Как захватить рабочий стол в OpenCV (т.е. превратить растровое изображение в мат)?

1 голос
/ 09 августа 2011

Из документации OpenCV

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

Я думаю, что в этом суть, использование этого конструктора не копирует буфер, который вы передаете конструктору, поэтому вы не должны освобождать эти данные, пока вам больше не понадобится cv :: Mat. Кроме того, я почти ничего не знаю об этом материале, но почему вы передаете BITMAPINFOHEADER и BITMAPFILEHEADER своему объекту cv :: Mat, что совсем не выглядит правильным.

0 голосов
/ 09 августа 2011

Я не знаю, что это, но в ту минуту, когда я задаю вопрос, я становлюсь одержимым поиском ответа.В любом случае, часть этой проблемы фактически решается путем ответа на этот вопрос:

API OpenCV 2.0 C ++ с использованием imshow: возвращает необработанное исключение и «bad-flag»

В Visual C ++:

перейдите в Проект-> Свойства (или Alt-F7) Свойства конфигурации-> Линкер-> Ввод-> Дополнительные зависимости

замените обычный "cv210.lib"cxcore210.lib highgui210.lib "by" cv210d.lib cxcore210d.lib highgui210d.lib "- библиотеки отладки.

highgui по-прежнему показывает серый и не работает, но чтение из HBITMAPИспользование вышеуказанного метода теперь работает.и я действительно не нуждаюсь в highgui, это было только для тестирования в любом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...