Kev*_*Kim 5 c++ mfc opencv atl
我想从转换ATL::CImage到cv::Mat图像处理OpenCV中(C ++)。你能帮忙转换这个对象吗?
我CImage从 Windows 屏幕截图中得到(使用 MFC)。然后,我想在 OpenCV Mat 对象中处理图像。
我不知道如何转换。
CImage image;
int cx;
int cy;
CWnd* pWndDesktop = CWnd::GetDesktopWindow();
CWindowDC srcDC(pWndDesktop);
Rect rcDesktopWindow;
::GetWindowRect(pWndDesktop->m_hWnd, %rcDesktopWindow);
cx = (rcDesktopWindow.right - rcDesktopWindow.left);
cy = (rcDesktopWindow.bottom - rcDesktopWindow.top);
image.create(cx, cy, srcDC.GetDeviceCaps(BITPIXEL));
CDC* pDC = CDC::FromHandle(image.GetDC());
pDC->BitBlt(0, 0, cx, cy, &srcDC, 0, 0, SRCCOPY);
image.ReleaseDC();
cv::Mat mat;
// I want set image to mat!
mat = image???
Run Code Online (Sandbox Code Playgroud)
无法转换ATL::Image为cv::Mat.
CImage如果高度为正,则创建一个自下而上的位图。您必须传递负高度才能创建上下位图mat
用于CImage::GetBits检索位,如下所示:
HDC hdc = GetDC(0);
RECT rc;
GetClientRect(GetDesktopWindow(), &rc);
int cx = rc.right;
int cy = rc.bottom;
CImage image;
image.Create(cx, -cy, 32);
BitBlt(image.GetDC(), 0, 0, cx, cy, hdc, 0, 0, SRCCOPY);
image.ReleaseDC();
ReleaseDC(0, hdc);
cv::Mat mat;
mat.create(cy, cx, CV_8UC4);
memcpy(mat.data, image.GetBits(), cy * cx * 4);
//or borrow pixel data from CImage
cv::Mat mat(cy, cx, CV_8UC4, image.GetBits());
Run Code Online (Sandbox Code Playgroud)
或者强制进行深复制,如下所示:
cv::Mat mat;
mat = cv::Mat(cy, cx, CV_8UC4, image.GetBits()).clone();
Run Code Online (Sandbox Code Playgroud)
注意,CImage对像素数据进行自己的分配。并且Mat需要自己进行分配,否则就必须从中借用,这CImage可能会很棘手。
如果您只是截取屏幕截图,则可以使用普通的 Windows API 来完成此操作,然后直接写入cv::Mat. 这种方式有一个单一的分配(更快一点)并且mat不依赖于其他对象。例子:
void foo()
{
HDC hdc = ::GetDC(0);
RECT rc;
::GetClientRect(::GetDesktopWindow(), &rc);
int cx = rc.right;
int cy = rc.bottom;
cv::Mat mat;
mat.create(cy, cx, CV_8UC4);
HBITMAP hbitmap = CreateCompatibleBitmap(hdc, cx, cy);
HDC memdc = CreateCompatibleDC(hdc);
HBITMAP oldbmp = (HBITMAP)SelectObject(memdc, hbitmap);
BitBlt(memdc, 0, 0, cx, cy, hdc, 0, 0, SRCCOPY);
BITMAPINFOHEADER bi = { sizeof(bi), cx, -cy, 1, 32, BI_RGB };
GetDIBits(hdc, hbitmap, 0, cy, mat.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
//GDI cleanup:
SelectObject(memdc, oldbmp);
DeleteDC(memdc);
DeleteObject(hbitmap);
::ReleaseDC(0, hdc);
}
Run Code Online (Sandbox Code Playgroud)
mat.data = (unsigned char*)image.GetBits();memcpy(mat.data, image.GetBits(), cy * cx * 4);
更改ReleaseDC(0, hdc)为::ReleaseDC(0, hdc)以避免冲突CWnd::ReleaseDC(dc)