Comment afficher OpenCV Tapis sur MFC Vue
Je pensais que l'affichage OpenCV2 Tapis sur MFC point de Vue est simple mais ne l'est pas. Ce n'est pertinente que le matériel que j'ai trouvé sur google. Excusez-moi pour mon ignorance, mais je ne trouve pas d'autres matériaux montrant comment utiliser SetDIBitsToDevice avec un tableau unidimensionnel "données" membre retourne. Plus précisément, j'ai besoin de savoir comment spécifier BITMAPINFO pour la fonction. Dois-je revenir à la Vieille de style C OpenCV pour MFC?
Mise à JOUR:
J'ai trouvé un exemple de SetDIBitsToDevice qui est fait pour les vieux C-style OpenCV. Mais il était simple de le convertir pour OpenCV2. Il y a des choses que j'ai besoin de parler pour le faire fonctionner:
-
Bpp méthode ne fonctionne pas bien que des Tapis de profondeur renvoie 0. Je viens de modifier comme ceci:
static int Bpp(cv::Mat img) { return 8 * img.channels(); }
-
Tapis n'est pas membre d'origine. Mais tout simplement en mettant 0 est bien pour origine l'argument de FillBitmapInfo méthode.
Autres que que, d'après le code fonctionne très bien. Espérons que cela aide d'autres devs trop.
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;
}
}
}
Malgré les documents sur SetDIBitsToDevice, je ne peux pas comprendre comment utiliser SetDIBitsToDevice avec un tableau unidimensionnel "données" membre retourne.
J'ai vu ton exemple comme une base pour d'autres plusieurs questions/réponses. Cependant, je me demandais, comment fais-tu pour éviter la fuite de mémoire à partir de l'utilisation de la
memset
dans le FillBitmapInfo
fonction? ou d'une certaine manière est automatiquement libéré? Pouvez vous nous donner des précisions à cet égard.Je suis désolé mais je ne comprends pas votre question. Ce qui fait que vous pensez qu'il s'agit de la mémoire de la fuite de l'utilisation de la memset? Et pourquoi devrait-il être libéré?
Vous êtes mon héros! Me sauver beaucoup de temps. Je n'ai pas besoin de CvvImage, il suffit de copier et de modifier légèrement votre code. Point-clé est
SetDIBitsToDevice
appel, mais BITMAPINFO
confusion débutant.
OriginalL'auteur Tae-Sung Shin | 2011-12-14
Vous devez vous connecter pour publier un commentaire.
À partir de MSDN:
C'est le pointeur, vous devez init avec les données renvoyées par Mat::données.
La BITMAPINFO est une structure avec les noms de champ disant clairement ce qu'ils contiennent: BITMAPINFOHEADER->largeur, hauteur, etc. Avez-vous jamais vraiment lu cette page? Veuillez lire également le Tapis de la documentation.
Ok, je l'ai utilisé il y a quelques temps, mais en regardant les modifier ci-dessus, il n'est pas aussi simple que l'oubli. Désolé.
OriginalL'auteur Sam
Ici est encore un autre moyen d'affichage d'OpenCV données MFC que j'utilise et fonctionne très bien:
CvMat mat = cvMat( height, width, CV_8UC1, data); IplImage *img = cvCreateImage(cvSize(height,width), IPL_DEPTH_8U, 1); cvGetImage(&mat, img);
nan je ne sais pas si c'est plus rapide, c'est juste beaucoup plus facile 😉
OriginalL'auteur Smash
CvvImage n'est pas disponible dans une nouvelle version d'OpenCV. En utilisant le code suivant, vous pouvez convertir Tapis de CImage et afficher CImage partout où vous voulez:
OriginalL'auteur hosseinkhosravi