乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      如何使用GDI或者GDI+的函數(shù)對IplImage進(jìn)行圖像處理?

       學(xué)海無涯GL 2013-05-05
      如何將OpenCV中的IplImage顯示在MFC的窗口中

      :主要函數(shù)有兩個(gè),一個(gè)是填寫相應(yīng)的Bitmapinfo結(jié)構(gòu)體,另外一個(gè)是把圖片顯示到CWnd類型的窗口上去。
       雖然我特殊處理了一下256位的圖,但我仍然無法畫灰度圖,挺奇怪的。目前只支持24位的圖片。
      main:
      IplImage *img = cvLoadImage("****");
      BITMAPINFO bmi;
      FillBitmapInfo(&bmi, img->width, img->height, img->depth*img->nChannels);
      ShowImage(img, wnd, bmi); // 這里的wnd是目標(biāo)窗口,必須是CWnd類型的。
       
      void FillBitmapInfo( BITMAPINFO *bmi, int width, int height, int bpp )
      {
       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 = -abs(height);
       bmih->biPlanes = 1;
       bmih->biBitCount = bpp;
       bmih->biCompression = BI_RGB;
       if( bpp == 8 )
       {
        RGBQUAD* palette = bmi->bmiColors;
        int i;
        for( i = 0; i < 256; i++ )
        {
         palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
         palette[i].rgbReserved = 0;
        }
       }
      }
      void ShowImage(IplImage *pImg, CWnd *wnd, BITMAPINFO &bmi)
      {
       CDC *pDC = wnd->GetDC();
       HDC  hDC = pDC->GetSafeHdc();
       CRect rect;
       wnd->GetClientRect(&rect);
       if(bmi.bmiHeader.biBitCount== 8)
       {
        CPalette pal;
        HPALETTE hpal=NULL;
        HPALETTE hOldPal=NULL;
        ::SetPaletteEntries(hpal,0,256,(LPPALETTEENTRY)bmi.bmiColors);
        hOldPal = ::SelectPalette(pDC->GetSafeHdc(), hpal, TRUE);
       }
       ::SetStretchBltMode(pDC->m_hDC, COLORONCOLOR);
       ::StretchDIBits(pDC->GetSafeHdc(),rect.left,rect.top,pImg->width,pImg->height,0,0,
          pImg->width,pImg->height,pImg->imageData,&bmi,DIB_RGB_COLORS,SRCCOPY);
      }



      (1 )IplImage -> Bitmap and Bitmap -> IplImage

      IplImage *img ;
      Bitmap bitmap( 20 ,20 ,PixelFormat24bppRGB ) ;
      Graphics pGra( & bitmap) ;
      HDC hdc = pGra ->GetHDC() ;
      CvvImage cvimg ;
      cvimg .CopyOf( img , -1) ;
      RECT rect = { 0 , 0 , img ->width , img ->height } ;
      cvimg.DrawToHDC( hdc , &rect ) ;
      pGra ->ReleaseHDC( hdc ) ;

      IplImage *tempimg = cvCreateImage(cvSize(bitmpa ->GetWidth() , bitmap ->Getheight (), 8 , 3) ;
      BitmapData mydata;
      Rect rect(0, 0, bitmpa ->GetWidth() , bitmap ->Getheight()) ;
      bitmap.LockBits( &rect , ImageLockModeRead , PixelFormat24bppRGB ,&mydata) ;
      memcpy(tempimg ->imagedata, mydata.scan0 , tempimg->width * tempimg->height* 3) ;
      bitmap.UnlockBits( & objdata ) ;


      (2) CBitmap ->Bitmap adn Bitmap -> CBitamp

      CDC *pdc = this ->GetDC() ;
      CBitmap m_Cbit;
      m_Cbit.CreateCompatibleBitmap(pdc , 100 ,100 ) ;
      Bitmap m_bit((HBITMAP) m_Cbit , NULL) ;

      HBITMAP bitmap ;
      m_bit.GetHBITMAP( Color( 0 , 0 , 0) , & bitmap ) ;
      CBitmap *m_pbit = CBitmap ::FromHandle( bitmap) ;

      ...do something ;

      m_pbit->DeleteObject() ;

      (3) IplImage ->CBitmap , Cbitmap ->IplImage
      CDC *pdc = this ->GetDC() ;
      IplImage *img = cvCreateImage( cvSize( 100,100 ) , 8 , 3 );
      CBitmap m_bitmap ;
      m_bitmap.CreateCompatibleBitmap( pdc , 100 ,100 ) ;
      CDC memdc ;
      memdc.CreateCompatibleDC( pdc ) ;
      CBitmap *pold = memdc .SelectObject( &m_bitmap) ;
      CvvImage cvimg ;
      Rect rect(0 , 0 , 100,100 ) ;
      cvimg.CopyOf( img , -1 ) ;
      cvimg.DrawToHDC( memdc.m_hDC , &rect ) ;
      ReleaseDC( pdc) ;
      IplImage *tempimg = cvCloneImage( img ) ;
      m_bitmap.GetBitmapBits( img ->widthStep * img ->height , img ->imageData) ;

      DirectShow OpenCV GDI+ 圖形顯示格式轉(zhuǎn)換

      DirectShow OpenCV GDI+ 圖形顯示格式轉(zhuǎn)換

      GDI+在顯示圖像方面要比GDI使用起來更方便

      OpenCV圖像處理方面無論深度和與VC的兼容性方面都是很好的,
      DirectShow要視頻采集方面目前應(yīng)該說是最優(yōu)秀的

      但OpenCV的IplImage格式與GDI+所需要的BITMAPINFO稍有不同
      同時(shí)OpenCV集成的視頻捕捉部分采用的VFW,效率上遠(yuǎn)不如DirectShow

      三者之間的圖像轉(zhuǎn)換工作我采用的如下方法,經(jīng)測試效率還可以
      測試架構(gòu)為
      1.DirectShow采集一幀圖像到源內(nèi)存buf,把此buf轉(zhuǎn)為OpenCV的彩色I(xiàn)plImage格式
      2.用OpenCV的方法轉(zhuǎn)成灰度圖得到一個(gè)新的灰度IplImage
      3.把灰度IplImage轉(zhuǎn)為GDI+所能識(shí)別的Bitmap,顯示到指定DC中
      以上所有過程沒有對源內(nèi)存buf的無效copy過程(當(dāng)然轉(zhuǎn)灰度圖過程OpenCV是要建個(gè)Buf的,不可省的)

      1.DirectShow采集一幀圖像到源內(nèi)存buf,在CB函數(shù)中..
      STDMETHODIMP CSampleGrabberCB::BufferCB(double SampleTime, BYTE * pBuffer, long BufferSize )
      {

      //cvCreateImage opencv自帶函數(shù),建立一個(gè)空圖

      IplImage *pImg = cvCreateImage(cvSize(biWidth ,biHeight), 8, 3);//建立空圖3*8=24位

      pImg->imageData = (char*)pBuffer;//得到buf指針,圖像創(chuàng)建完畢

      ::SendMessageW(m_hWnd, UM_DVBACK, 0, LPARAM(pImg));//把圖發(fā)到主線程,轉(zhuǎn)2

      cvReleaseImage(&pImg);//釋放圖

      return 0;

      }

      2.在主線程中消息響應(yīng)函數(shù)中用OpenCV的方法轉(zhuǎn)成灰度圖得到一個(gè)新的灰度IplImage
      LRESULT CMy05_ThreadSnapDlg::OnUMDVBACK(WPARAM wParam, LPARAM lParam)
      {

      IplImage *pImgSrc = (IplImage *)lParam;// 得到源圖

      IplImage* pImgGray = cvCreateImage(cvGetSize(pImgSrc), 8, 1);// 建立新的空的灰度圖

      cvCvtColor(pImgSrc, pImgGray, CV_BGR2GRAY);// 24位RGB彩圖轉(zhuǎn)灰度圖,opencv自帶函數(shù),這里可以使用任何opencv函數(shù)進(jìn)行圖象處理

      DrawImgToHwnd(m_hWnd, pImgGray); //自寫函數(shù),顯示灰度圖,即處理結(jié)果;轉(zhuǎn)3

      }

      3.把灰度IplImage轉(zhuǎn)為GDI+所能識(shí)別的Bitmap,顯示到指定DC中
      void CMy05_ThreadSnapDlg::DrawImgToHwnd(HWND hWnd, IplImage *pImg)
      {

      int nBitCount = (pImg->depth & 255) * pImg->nChannels;//圖像色彩深度 opencv源碼這樣寫的,也可以直接乘

      int nWidth = pImg->width;

      int nHeight = pImg->height;//這里特別注意,如果發(fā)現(xiàn)倒像,這里設(shè)為負(fù)值即可(-pImg->height)

      BITMAPINFO *pBITMAPINFO = nBitCount == 24 ? m_pBITMAPINFO_24:m_pBITMAPINFO_08;

      //24位圖和8位圖的BITMAPINFO是固定的,要提前創(chuàng)建好,一次即可

      Bitmap* pBitmap = Bitmap::FromBITMAPINFO(pBITMAPINFO, pImg->imageData);//GDI+的圖像格式

      Graphics *gdiDC = Graphics::FromHWND(hWnd);//GDI+創(chuàng)建畫板方法

      gdiDC->DrawImage(pBitmap,0,0);//GDI+畫圖方法

      delete pBitmap;

      delete gdiDC;

      }


      使用GDI+顯示OpenCV中的圖像IplImage

        OpenCV雖然自帶了輕量級(jí)的界面庫HighGUI,但是支持的圖像化元素實(shí)在是太少了,一般只在前期算法測試時(shí)使用。實(shí)際產(chǎn)品還是使用MFC庫。因此本文記錄了如何在GDI+中顯示OpenCV中的IplImage格式的圖像數(shù)據(jù)。

        假設(shè)創(chuàng)建的MFC MDI應(yīng)用程序名為GdiplusTest。關(guān)于如何在MFC中使用GDI+圖形化系統(tǒng)已經(jīng)在《GDI+ 使用指南》一文中介紹了。

        顯示OpenCV中的IplImage圖像格式具體步驟如下:

      1. 在GdiplusTestView.cpp中添加OpenCV的頭文件
        #include <cv.h>
        #include <highgui.h>
      2. 在CGdiplusTestView::OnDraw(CDC* pDC)函數(shù)中添加如下代碼:
        復(fù)制代碼
        //載入圖像
        IplImage* srcImage = cvLoadImage("lena.jpg");
        //創(chuàng)建Bitmap對象
        Gdiplus::Bitmap bitmap(srcImage->width, srcImage->height, srcImage->widthStep,
        PixelFormat24bppRGB, (BYTE*)srcImage->imageData);

        Gdiplus::Graphics graphics(pDC->GetSafeHdc());
        graphics.DrawImage(&bitmap, 0, 0);

        GDI+ 使用指南(basic guiding of GDI plus )

          其實(shí)這個(gè)也沒有什么用,畢竟已經(jīng)是過時(shí)的技術(shù)了。不過技術(shù)的更新跟實(shí)際的使用還是有差距了,免不了還是要用這種過時(shí)的技術(shù),所以還是記錄下來,方便以后查閱。
          GDI+沒記錯(cuò)的話是跟隨XP誕生的,是XP系統(tǒng)上的圖形繪制系統(tǒng)(以前的是GDI),GDI+相對于GDI提供了一些新的特性,比如漸變的畫刷,支持多種圖像格式等等。不過我覺得最大的變化,還是編程模型上的變化。GDI+使用了面向?qū)ο蟮乃枷?,對接口進(jìn)行了類封裝,使用更加方便。
          在應(yīng)用程序中使用GDI+庫應(yīng)該遵循一下步驟:
          1.包含Gdiplus.h頭文件,如果圖方便,加上:using namespace Gdiplus;這樣使用GDI+中的任何東西就不需要重新指定命名空間了。
          2.鏈接DLL的導(dǎo)入庫Gdiplus.lib。在VS中有兩種方法,一是直接在項(xiàng)目屬性->鏈接->輸入中填入Gdiplus.lib;二是直接使用編譯器原語:#pragma comment(lib, "Gdiplus.lib")
          3.在調(diào)用任何GDI+函數(shù)前一定要調(diào)用GDI+庫初始化函數(shù)GdiplusStartup(),初始化GDI+庫。
          4.在確定不需要使用任何GDI+函數(shù)并且所有GDI+對象均已銷毀(變量超過了生存期),需要調(diào)用GDI+關(guān)閉函數(shù)GdiplusShutdown()。GDI+支持多線程,所以可以在任意一個(gè)線程中調(diào)用。

          下面講下在實(shí)際MFC 單/多文檔程序中,如何使用GDI+圖形系統(tǒng)(程序名叫:GdiplusTest)。
          1.在Stdafx.h頭文件中添加如下代碼

        #include <GdiPlus.h>
        #pragma comment(lib, "Gdiplus.lib")

          2.在CGdiplusTestApp類中,添加兩個(gè)變量,用于GDI+初始化函數(shù)。

        private:
        Gdiplus::GdiplusStartupInput gdiplusStartupInput;
        ULONG_PTR gdiplusToken;

        3.在CGdiplusTestApp::InitInstance()函數(shù)中添加如下代碼,一定要在pMainFrame->ShowWindow(m_nCmdShow)之前,建議添加在CWinAppEx::InitInstance()之后。

        // Initialize GDI+.
        Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

        4.重載CGdiplusTestApp的ExitInstance()函數(shù),然后添加GDI+關(guān)閉函數(shù)。

        	Gdiplus::GdiplusShutdown(gdiplusToken);

        5.在CGdiplusTestView::OnDraw(CDC* pDC)函數(shù)中使用GDI+類,顯示圖片lena.jpg

        Gdiplus::Graphics graphics(pDC->GetSafeHdc());
        Gdiplus::Image image(L"lena.jpg");
        graphics.DrawImage(&image, 10, 10);

        
        

        OpenCV ---HBITMAP to IplImage

        IplImage* hBitmap2Ipl(HBITMAP hBmp)
        {

        BITMAP bmp;
        ::GetObject(hBmp,sizeof(BITMAP),&bmp);
        int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8 ;
        int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
        IplImage* img = cvCreateImageHeader( cvSize(bmp.bmWidth, bmp.bmHeight), depth, nChannels );
        img->imageData =(char*)malloc(bmp.bmHeight*bmp.bmWidth*nChannels*sizeof(char));
        memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);
        return img;
        }

        void createDIB(IplImage* &pict)

        {

        IplImage * Red=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),IPL_DEPTH_8U, 1 );
        IplImage * Green=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),IPL_DEPTH_8U, 1 );
        IplImage * Blue=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),IPL_DEPTH_8U, 1 );
        cvSetImageCOI( pict, 3);
        cvCopy(pict,Red);
        cvSetImageCOI( pict, 2);
        cvCopy(pict,Green);
        cvSetImageCOI(pict, 1);
        cvCopy(pict,Blue);
        //Initialize the BMP display buffer
        bmi = (BITMAPINFO*)buffer;
        bmih = &(bmi->bmiHeader);
        memset( bmih, 0, sizeof(*bmih));
        bmih->biSize = sizeof(BITMAPINFOHEADER);
        bmih->biWidth = IMAGE_WIDTH;
        bmih->biHeight = IMAGE_HEIGHT; //
        -IMAGE_HEIGHT;
        bmih->biPlanes = 1;
        bmih->biCompression = BI_RGB;
        bmih->biBitCount = 24;
        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;
        }
        cvReleaseImage(&Red);
        cvReleaseImage(&Green);
        cvReleaseImage(&Blue);
        }


        IplImage與CImage 圖像類型的轉(zhuǎn)換

        IplImage* plmg; //定義兩個(gè)IplImage和CImage類型
        CImage cimg;
        plmg=cvLoadImage(pDoc->m_paName,1); //然后以路徑為參數(shù),把圖形讀進(jìn)IplImage cimg.CopyOf(plmg); //把IplImage轉(zhuǎn)換成CImage類型

        pImg =cimg.GetImage(); //把CImage類型轉(zhuǎn)換成IplImage

        CRect rect(0,0,cimg.Width(),cimg.Height());
        HDC hDC=pDC->GetSafeHdc();
        cimg.DrawToHDC(hDC,rect); //CImage類型才能用DrawToHDC進(jìn)行顯示

        Bitmap與IplImage之間的轉(zhuǎn)換

        在MFC編程中,用OpenCV來處理圖像時(shí),可能會(huì)進(jìn)行Bitmap與IplImage之間的轉(zhuǎn)換;所以在此留個(gè)記號(hào),以免下次再用到的時(shí)候,還要去找。

        IplImage* BitmapToIplImage(HBITMAP hBmp)
        {
        	BITMAP bmp;    
        	
        	GetObject(hBmp, sizeof(BITMAP), &bmp);
        	int depth     = (bmp.bmBitsPixel == 1) ? IPL_DEPTH_1U : IPL_DEPTH_8U;
        	int nChannels = (bmp.bmBitsPixel == 1) ? 1 : bmp.bmBitsPixel/8;    
        	
        	IplImage* img = cvCreateImage(cvSize(bmp.bmWidth,bmp.bmHeight), depth, nChannels);  
        	
        	BYTE *pBuffer = new BYTE[bmp.bmHeight*bmp.bmWidth*nChannels];    
        	GetBitmapBits(hBmp, bmp.bmHeight*bmp.bmWidth*nChannels, pBuffer);
        	memcpy(img->imageData, pBuffer, bmp.bmHeight*bmp.bmWidth*nChannels);   
        	delete pBuffer;
        
        	IplImage *dst = cvCreateImage(cvGetSize(img), img->depth,3);    
        	cvCvtColor(img, dst, CV_BGRA2BGR);   
        	cvReleaseImage(&img);   
        	return dst;
        }

        如果要從CBitmap轉(zhuǎn)為IplImage,可以先將CBitmap轉(zhuǎn)為BITMAP,再由BITMAP轉(zhuǎn)為IplImage;

        // CBitmap 轉(zhuǎn)為 BITMAP
        CBitmap bitmap;
        bitmap.LoadBitmap(IDB_BITMAP);
        BITMAP   bmp;
        bitmap.GetBitmap(&bmp);
        
        // CBitmap與HBITMAP間的轉(zhuǎn)換
        // CBitmap轉(zhuǎn)為HBITMAP
        CBitmap bitmap;
        bitmap.LoadBitmap(IDB_BITMAP);
        HBITMAP bmp = HBITMAP(bitmap);
        // HBITMAP轉(zhuǎn)為CBitmap
        HBITMAP  hbitmap;  
        CBitmap   bitmap;
        bitmap.Attach(hbitmap);
        

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請遵守用戶 評(píng)論公約

        類似文章 更多