【发布时间】:2019-12-03 14:47:03
【问题描述】:
我目前正在尝试截取屏幕截图,然后将其转换为 OpenCV 可编辑的格式。我使用的代码来自微软网站https://docs.microsoft.com/en-gb/windows/win32/gdi/capturing-an-image。该代码使用“Windows.h”库。最简单的方法显然是将位图保存为 .bmp,然后使用 opencv 打开它。但是,我希望它比这更有效率,但我不知道该怎么做。当我使用代码时,它输出了一个 char 指针,我不知道如何将其转换为 cv::Mat。代码如下:
cv::Mat * Capture::GetMat()
{
cv::Mat * mat1;
MemoryHandle = NULL;
BitmapHandle = NULL;
// Find the handle for the device context of the entire screen, and the specific window specified.
ScreenHandle = GetDC(NULL);
WindowHandle = GetDC(hwnd);
//Make the compatible DC (Device Context) for storing the data in memory.
MemoryHandle = CreateCompatibleDC(WindowHandle);
//Make a compatible DC for the bitmap to be stored in.
BitmapHandle = CreateCompatibleBitmap(WindowHandle, width, height);
//Select the correct bitmap, and put it into memory using the memory handle.
SelectObject(MemoryHandle, BitmapHandle);
//Transfer the actual bitmap into the compatible memory DC.
BitBlt(MemoryHandle, 0, 0, 1920, 1080, WindowHandle, 0, 0, SRCCOPY);
//Get the bitmap from the handle, and ready it to be filed.
GetObject(BitmapHandle, sizeof(BITMAP), &Bitmap);
//Cofinguring INFO details.
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = Bitmap.bmWidth;
bmpInfoHeader.biHeight = Bitmap.bmHeight;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
bmpInfoHeader.biCompression = BI_RGB;
bmpInfoHeader.biSizeImage = 0;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;
bmpSize = ((Bitmap.bmWidth * bmpInfoHeader.biBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
memhnd = GlobalAlloc(GHND, bmpSize);
mat1 = (cv::Mat *)GlobalLock(memhnd);
std::cout << GetLastError() << std::endl;
return mat1;
}
int Capture::save_mat(cv::Mat * mat)
{
std::string FileName("P:/Photos/capture");
FileName += std::to_string(image_count_mat);
FileName += (const char*)(".jpg");
cv::Mat mat2 = *mat;
cv::imwrite(FileName.c_str(), mat2);
image_count_mat++;
return 0;
}
该类具有以下属性:
private:
HWND hwnd;
HDC hdc;
int image_count_bitmap = 0;
int image_count_mat = 0;
int height;
int width;
HDC ScreenHandle;
HDC WindowHandle;
HDC MemoryHandle = NULL;
HBITMAP BitmapHandle = NULL;
BITMAP Bitmap;
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
DWORD bmpSize;
HANDLE memhnd;
GetMat() 函数工作正常并且不输出错误,尽管我不知道如何检查输出的 cv::Mat 是否正确。但是,当我运行 save_mat() 函数时,程序崩溃了。
【问题讨论】:
-
这样不行。您需要以通常的方式创建 Mat,通过使用正确的大小构造或调用 Mat::create()。然后将数据从 Bitmap 复制到 Mat,因为 AFAIK 在 OpenCV 中没有对应于 Bitmap 布局的配色方案。