Pensé que mostrar OpenCV2 Mat en MFC View es simple pero no lo es. This is only relevant material I found on google. Perdóneme por mi ignorancia, pero no puedo encontrar ningún otro material que demuestre cómo usar SetDIBitsToDevice con los retornos de un miembro "de datos" de una matriz dimensional. Más específicamente, necesito saber cómo especificar BITMAPINFO para la función. ¿Vuelvo a Old C-style OpenCV para trabajar con MFC?Cómo mostrar OpenCV Mat en MFC View
ACTUALIZACIÓN:
He encontrado an example of SetDIBitsToDevice que en realidad es para el viejo estilo de OpenCV-C. Pero fue sencillo convertirlo para OpenCV2. Hay cosas que tengo que mencionar a hacer que funcione:
- método
Bpp no funciona así como la profundidad de Mat devuelve 0. Me acaba de cambiar de esta manera:
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
Mat no tiene origen miembro. Pero simplemente poner 0 está bien para el argumento de origen del método FillBitmapInfo.
Aparte de eso, siguiente código funciona muy bien. Espero que esto ayude a otros desarrolladores también.
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;
}
}
}
Y lo que es malo en el enlace que ya ha proporcionado? – Sam
@vasile A pesar de los documentos en SetDIBitsToDevice, no puedo encontrar la forma de usar SetDIBitsToDevice con una matriz dimensional que devuelve un miembro de "datos". –
@Paul He visto su ejemplo como base para otras varias preguntas/respuestas. Sin embargo, me pregunto, ¿cómo se puede evitar la pérdida de memoria por el uso del 'memset' en la función' FillBitmapInfo'? o de alguna manera se libera automáticamente? ¿Puedes elaborar en este sentido? – adn