OpenCV 2.2 and later version numbers cancel out the CvvImage.h and CvvImage.cpp two files, which directly lead to the bitter force of the program apes cannot invoke the inside display function to display the image to the picture control control of MFC. For this reason, there are a lot of people on the Internet that just want to extract the two files and put them in project to solve this problem, but also provide two files download, but this trouble does not say. It will also cause some weird errors (at least I am this, very crash!). So after understanding some GDI drawing combined with the online code to write such as the following function, just call to be able to display the OpenCV picture on it (only support three channels do not support single channel), the initial test efficiency of the original two files almost the same. If there is a great god please help me to complete this code!
After configuring OpenCV, add the following line of code to the header of the file:
#define Widthbytes (BITS) ((bits) +31)/32*4)//used to make the image width occupy a multiple of 4byte bytes
to declare a function in a dialog class:
void Drawpic (iplimage* img, unsigned int id);//Draw to MFC's picture control-control-related function. An image data structure class that is a parameter of OpenCV. Parameter two is the ID of the picture control control
Define functions such as the following:
void Cmfcdrawdlg::d rawpic (iplimage* img, unsigned int id)//cmfcdrawdlg for dialog box class name {bitmapinfo *pbmi;//bitmap information byte *bmibuf;// Bitmap information space byte *g_pbits; HDC G_HMEMDC; Hbitmap g_hbmp; CDC *PDC; CStatic *pic;int width, height; CRect rect;//Bitmap Information Initialization bmibuf = new Byte[sizeof (bitmapinfo) +256 * sizeof (Rgbquad)];memset (bmibuf, 0, sizeof (BMIBUF));p BMI = (bitmapinfo*) bmibuf;pbmi->bmiheader.bisize = sizeof (bitmapinfoheader);p bmi->bmiheader.biwidth = img-> Width;pbmi->bmiheader.biheight = Img->height;pbmi->bmiheader.biplanes = 1;pbmi->bmiHeader.biBitCount = 24;pbmi->bmiheader.bicompression = bi_rgb;//Gets the device DC and displays the width of the high PDC = GetDlgItem (ID)->getdc ();p IC = (cstatic*) GetDlgItem (ID);p ic->getclientrect (&rect); width = rect. Width (); height = rect. Height (); G_HMEMDC = CreateCompatibleDC (PDC->M_HDC);//Create a compatible device environment memory Dcg_hbmp = CreateDIBSection (G_HMEMDC, Pbmi, DIB_ Rgb_colors, (void**) &g_pbits, 0, 0);//Create a device-independent bitmap that the application can write directly to//alter the contents of the image: G_pbitsint l_width = widthbytes (img-> width* Pbmi->bmiheader.bibitcoUNT); for (int row = 0; row < img->height; row++) memcpy (&g_pbits[row*l_width], &img->imagedata[(img- >height-row-1) *l_width], l_width); SelectObject (G_HMEMDC, g_hbmp);//Select the bitmap object into G_HMEMDC memory DC//Stretch paint TransparentBlt (pdc->m_hdc, 0, 0, width, height, g_ HMEMDC, 0, 0, img->width, Img->height, RGB (1, 0, 0));//rgb value was originally set to (0,0,0), but it seems that there is a bug in the drawing here, it is therefore changed (1,0,0)// Free Memory Resource ReleaseDC (PDC);D Eletedc (G_HMEMDC);D eleteobject (pic);D eleteobject (g_hbmp);}
Add the following code where you need to display the picture to the image control controls:
Char *filename = "pic1.jpg";//image path iplimage* img = cvloadimage (filename);d rawpic (IMG, idc_static_show);//idc_static_ SHOW is the Idcvreleaseimage (&img) of the picture control control;
It's been a long time since I started writing this article, because I have to work on drawing in the near future and the job requires a very high efficiency in drawing, so I look back at this thing. Some errors have been found, and the wrong places have been changed. I believe that the people who have GDI drawing basis should have seen it, really ashamed.
For the above code, it can be applied to the general situation of the drawing work. However, it is very promising to further optimize performance, such as splitting the program into "initialization", "body part", "Memory release" three parts. It is not necessary to initialize and memory release each time the picture is displayed, which will further improve the efficiency of the program. The following code that changes the version number is also put in.
Declare a class to hold information about bitmaps and device environments:
Class drawbitmapobj{public://Bitmap Object bitmapinfo *pbmi;//bitmap information byte *bmibuf;//bitmap information space byte *g_pbits; Hbitmap g_hbmp; CDC *PDC; CRect rect; CStatic *pic; HDC G_HMEMDC;};
to declare a function in a dialog class:
void Drawpicinit (iplimage* img, unsigned int ID, drawbitmapobj &mybmpobj);//initialization function. The OPENCV image data structure class, the parameter two is the control ID, the parameter is the bitmap and the device information object void Drawpic (iplimage* img, drawbitmapobj &mybmpobj);//drawing to the picture of MFC Control-related functions. The OPENCV is the image data structure class, the parameter two is the bitmap and the device information object void Drawrelease (Drawbitmapobj &mybmpobj);//Release Paint Object
due to the bitmap involved, four-byte alignment is required. So put the formula in the header of the file you need to use:
#define Widthbytes (BITS) ((bits) +31)/32*4)//used to make the image width occupy a multiple of 4byte bytes
Define three functions separately:
void Cmfcdrawdlg::d rawpicinit (iplimage* img, unsigned int ID, drawbitmapobj &mybmpobj) {//bitmap information Initialization mybmpobj.bmibuf = New Byte[sizeof (bitmapinfo) +256 * sizeof (Rgbquad)];memset (mybmpobj.bmibuf, 0, sizeof (MYBMPOBJ.BMIBUF)); Mybmpobj.pbmi = (bitmapinfo*) mybmpobj.bmibuf;mybmpobj.pbmi->bmiheader.bisize = sizeof (Bitmapinfoheader); Mybmpobj.pbmi->bmiheader.biwidth = Img->width;mybmpobj.pbmi->bmiheader.biheight = img->height; Mybmpobj.pbmi->bmiheader.biplanes = 1;mybmpobj.pbmi->bmiheader.bibitcount = 24;mybmpobj.pbmi-> Bmiheader.bicompression = BI_RGB;MYBMPOBJ.PDC = GetDlgItem (ID)->getdc (); mybmpobj.pic = (cstatic*) GetDlgItem (ID); Mybmpobj.pic->getclientrect (&mybmpobj.rect); MYBMPOBJ.G_HMEMDC = CreateCompatibleDC (Mybmpobj.pDC->m_hDC );//Create a compatible device environment memory Dcmybmpobj.g_hbmp = CreateDIBSection (MYBMPOBJ.G_HMEMDC, Mybmpobj.pbmi, Dib_rgb_colors, (void**) & Mybmpobj.g_pbits, 0, 0);//Create a device-independent bitmap that the application can write directly}void Cmfcdrawdlg::d rawpic (iplimage* img, Drawbitmapobj & Mybmpobj)//Cmfcopencvshowdlg for dialog class name {//change image content: g_pbits//do this here. A four-byte alignment mechanism for BMP images. The second is because the BMP image is started from the lower left corner of the image, assuming that the direct copy causes the image to be upside down int l_width = widthbytes (img->width* mybmpobj.pbmi-> Bmiheader.bibitcount); for (int row = 0; row < img->height; row++) memcpy (&mybmpobj.g_pbits[row*l_width], & img->imagedata[(img->height-row-1) *l_width], l_width); SelectObject (MYBMPOBJ.G_HMEMDC, mybmpobj.g_hbmp);//Select the bitmap object into the G_HMEMDC memory DC//Extrude paint TransparentBlt (mybmpobj.pdc->m_ HDC, 0, 0, mybmpobj.rect.Width (), Mybmpobj.rect.Height (), MYBMPOBJ.G_HMEMDC, 0, 0, img->width, Img->height, RGB (1, 0, 0));//rgb value was originally set to (0,0,0), but it seems that there will be a bug in the drawing, it is therefore changed (1,0,0)}void Cmfcdrawdlg::d rawrelease (drawbitmapobj &mybmpobj) {/ /Frees Memory Resources DELETE[]MYBMPOBJ.BMIBUF;DELETEDC (MYBMPOBJ.G_HMEMDC);D eleteobject (mybmpobj.pic);D Eleteobject (mybmpobj.g_ hbmp); ReleaseDC (MYBMPOBJ.PDC);}
Done with the above is OK, the way to invoke such as the following:
Drawbitmapobj Mybmpobj;char *filename = "1.jpg";//image path iplimage* img = cvloadimage (filename);d rawpicinit (IMG, idc_ Static_show, mybmpobj); Long begintime = clock (); int i = 8;while (i--) {drawpic (img, mybmpobj);//idc_static_show is picture C Ontrol control's id}printf ("Time Consuming:%dms\n", (Clock ()-begintime)/8), Cvreleaseimage (&img);d rawrelease (mybmpobj);
Of course. can also be further encapsulated directly into a class
#include "stdafx.h" #include "afxdialogex.h"/****************************** Name: Drawing Image Class * * Function: OpenCV The input Iplimage Image object draws an image into a control in the specified window * * Explanation: Showwnd is the specified window, ID is the specified window ID. IMG For input Image object **weixinhum** time: 2015/10/29****************************/class paintimgtoscreencontrols:public CDialogEx {public://Bitmap object bitmapinfo *pbmi;//bitmap information byte *bmibuf;//bitmap information space byte *g_pbits; Hbitmap g_hbmp; CDC *PDC; CRect rect; CStatic *pic; HDC g_hmemdc;void drawpicinit (iplimage* img, unsigned int ID, cwnd* showwnd);//initialization function. The OPENCV is the image data structure class, the parameter two is the control idvoid drawpic (iplimage* img);//Drawing to MFC's picture control-control-related function, a OPENCV image data structure class void Drawrelease ();//Release drawing Object cwnd* Mshowwnd;}; #define Widthbytes (BITS) ((bits) +31)/32*4)//is used to make the image width of the number of bytes is 4byte of multiples of void Paintimgtoscreencontrols::d rawpicinit ( iplimage* img, unsigned int ID, cwnd* showwnd) {//bitmap information initialization bmibuf = new Byte[sizeof (bitmapinfo) +256 * sizeof (RGBQUAD)];memse T (bmibuf, 0, sizeof (BMIBUF));p BMI = (bitmapinfo*) bmibuf;pbmi->bmiheader.bisize = sizeof (bitmapinfoheader);p bmi- >bmiheader.biwidth = Img-> width;pbmi->bmiheader.biheight = Img->height;pbmi->bmiheader.biplanes = 1;pbmi->bmiHeader.biBitCount = 24;pbmi->bmiheader.bicompression = Bi_rgb;mshowwnd = SHOWWND;PDC = Mshowwnd->getdlgitem (ID)->GetDC ();p IC = ( cstatic*) Mshowwnd->getdlgitem (ID);p ic->getclientrect (&rect); G_HMEMDC = CreateCompatibleDC (pDC->m_ HDC);//Create a compatible device environment memory Dcg_hbmp = CreateDIBSection (G_HMEMDC, Pbmi, Dib_rgb_colors, (void**) &g_pbits, 0, 0);// Create device-independent bitmaps that your application can write directly}void paintimgtoscreencontrols::d rawpic (iplimage* img)//cmfcopencvshowdlg for dialog class name {//change image content: G _pbits//here. This is a four-byte alignment mechanism for BMP images, and the second is that BMP images start from the lower left corner of the image. Assuming a direct copy causes the image to be upside down int l_width = widthbytes (img->width* pbmi->bmiheader.bibitcount); for (int row = 0; row < img-> Height row++) memcpy (&g_pbits[row*l_width], &img->imagedata[(img->height-row-1) *l_width], l_width); SelectObject (G_HMEMDC, g_hbmp);//Select the bitmap object into the G_HMEMDC memory DC//Extrude paint TransparentBlt (pdc->m_hdc, 0, 0, rect. Width (), Rect. Height (), G_HMEMDC, 0, 0, img->width, Img->height, RGB (1, 0, 0));//rgb value was originally set to (0,0,0), but it seems that there will be a bug in the drawing, it is therefore changed (1,0,0)}void Paintimgtoscreencontrols::d rawrelease () {//Frees memory resource Delete[]bmibuf;deletedc (G_HMEMDC);D eleteobject (pic);D Eleteobject (g_hbmp); Mshowwnd->releasedc (PDC);}
and then call
Paintimgtoscreencontrols Paintobj;char *filename = "pano.jpg";//image path iplimage* img = cvloadimage (filename); Paintobj.drawpicinit (IMG, Idc_static_pano, this); int i = 8;while (i--) {paintobj.drawpic (img);//idc_static_show Id}cvreleaseimage (&img) for the picture control control;p aintobj.drawrelease ();
OpenCV 2.2 Version number above display pictures into the picture control control of MFC