Tôi nghĩ hiển thị OpenCV2 Mat trên MFC View rất đơn giản nhưng không phải. This is only relevant material I found on google. Xin lỗi vì sự thiếu hiểu biết của tôi nhưng tôi không thể tìm thấy bất kỳ tài liệu nào khác cho thấy cách sử dụng SetDIBitsToDevice với mảng dữ liệu "mảng" một chiều trở về. Cụ thể hơn, tôi cần biết cách chỉ định BITMAPINFO cho hàm này. Tôi có quay trở lại OpenCV kiểu C cũ để làm việc với MFC không?Cách hiển thị OpenCV Mat trên MFC Xem
UPDATE:
tôi thấy an example of SetDIBitsToDevice mà thực sự là thay cũ OpenCV C-phong cách. Nhưng thật đơn giản để chuyển đổi nó cho OpenCV2. Có những điều tôi cần phải đề cập đến để làm cho nó làm việc:
- phương pháp
BPP không hoạt động cũng như chiều sâu Mat của trả về 0. Tôi chỉ thay đổi như thế này:
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
Mat không có nguồn gốc hội viên. Nhưng chỉ cần đặt 0 là tốt cho đối số xuất xứ của phương thức FillBitmapInfo.
Ngoài ra, mã sau hoạt động rất tốt. Hy vọng điều này cũng giúp các nhà phát triển khác.
void COpenCVTestView::OnDraw(CDC* pDC)
{
COpenCVTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
if(pDoc->m_cvImage.empty()) return;
// TODO: add draw code for native data here
int height=pDoc->m_cvImage.rows;
int width=pDoc->m_cvImage.cols;
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024];
BITMAPINFO* bmi = (BITMAPINFO*)buffer;
FillBitmapInfo(bmi,width,height,Bpp(pDoc->m_cvImage),0);
SetDIBitsToDevice(pDC->GetSafeHdc(), 0, 0, width,
height, 0, 0, 0, height, pDoc->m_cvImage.data, bmi,
DIB_RGB_COLORS);
}
void COpenCVTestView::FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin)
{
assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32));
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset(bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = origin ? abs(height) : -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = (unsigned short)bpp;
bmih->biCompression = BI_RGB;
if (bpp == 8)
{
RGBQUAD* palette = bmi->bmiColors;
for (int i = 0; i < 256; i++)
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
Và những gì xảy ra với các liên kết mà bạn cung cấp? – Sam
@vasile Mặc dù tài liệu trên SetDIBitsToDevice, tôi không thể tìm ra cách sử dụng SetDIBitsToDevice với mảng dữ liệu một chiều "thành viên" trả về. –
@Paul Tôi đã xem ví dụ của bạn làm nền tảng cho một số câu hỏi/câu trả lời khác. Tuy nhiên, tôi tự hỏi, làm thế nào để bạn tránh rò rỉ bộ nhớ từ việc sử dụng 'memset' trong hàm' FillBitmapInfo'? hoặc bằng cách nào đó được tự động giải phóng? Bạn có thể xây dựng trong lĩnh vực này không. – adn