Myślałem, że wyświetlenie maty OpenCV2 w widoku MFC jest proste, ale nie jest. This is only relevant material I found on google. Przepraszam za moją ignorancję, ale nie mogę znaleźć żadnych innych materiałów pokazujących, jak korzystać z SetDIBitsToDevice z jednowymiarowymi tablicami zwracanymi przez "dane". Dokładniej, muszę wiedzieć, jak określić BITMAPINFO dla funkcji. Czy wracam do OpenCV w starym stylu C, aby współpracować z MFC?Jak wyświetlić Matę OpenCV na MFC View
UPDATE:
znalazłem an example of SetDIBitsToDevice która jest faktycznie na starym stylu C OpenCV. Łatwo było jednak przekonwertować go na OpenCV2. Są rzeczy, muszę wspomnieć, że praca:
- metoda
BPP nie działa dobrze jak głębokość Mat wraca 0. Właśnie zmienił tak:
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
Mat nie ma pochodzenie członek. Ale wprowadzenie 0 jest w porządku dla argumentu pochodzenia metody FillBitmapInfo.
Poza tym poniższy kod działa świetnie. Mam nadzieję, że to pomoże także innym programistom.
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;
}
}
}
A co jest nie tak z linkiem, który podałeś? – Sam
@vasile Pomimo dokumentów na SetDIBitsToDevice, nie mogę dowiedzieć się, jak korzystać z SetDIBitsToDevice z jednowymiarowymi tablicami zwracanymi przez "dane". –
@Paul Widziałem twój przykład jako podstawę dla innych pytań/odpowiedzi. Zastanawiam się jednak, w jaki sposób uniknąć wycieku pamięci z użycia 'memset' w funkcji' FillBitmapInfo'? lub w jakiś sposób jest automatycznie zwalniany? Czy możesz rozwinąć w tym zakresie. – adn