將OpenCV:Mat矩陣圖像轉換為MFC:CImage圖像


參考:http://blog.csdn.net/merlin_q/article/details/7041040

——————————————以下為原文————————————————

/*************************************/  
  
//1.讀入Mat矩陣(cvMat一樣),Mat img=imread("*.*");//cvLoadImage  
//確保轉換前矩陣中的數據都是uchar(0~255)類型(不是的話量化到此區間),這樣才能顯示。(初學者,包括我經常忘了此事)  
//2.根據矩陣大小創建(CImage::Create)新的的CImage類  
CImage CI;  
int w=img.cols;//寬  
int h=img.rows;//高  
int chinnels=img.channels();//通道數  
CI.Destroy();//創建前,最好使用它,防止重復創建,程序崩潰  
CI.Create(w,h,8*chinnels);  
  
//3.下來就是對CI進行賦值了,這里是最核心的地方,分二類討論  
//  (1)如果是1個通道的圖像(灰度圖像) DIB格式才需要對調色板設置  
//  CImage中內置了調色板,我們要對他進行賦值:  
RGBQUAD* ColorTable;  
int MaxColors=256;  
//這里可以通過CI.GetMaxColorTableEntries()得到大小(如果你是CI.Load讀入圖像的話)  
ColorTable = new RGBQUAD[MaxColors];  
CI.GetColorTable(0,MaxColors,ColorTable);//這里是取得指針  
for (int i=0; i<MaxColors; i++)  
{  
    ColorTable[i].rgbBlue = (BYTE)i;  
    //BYTE和uchar一回事,但MFC中都用它  
    ColorTable[i].rgbGreen = (BYTE)i;  
    ColorTable[i].rgbRed = (BYTE)i;  
}  
CI.SetColorTable(0,MaxColors,ColorTable);  
delete []ColorTable;  
//然后就是數據拷貝了(這里的矩陣表示方法,根據需要(cvMat or Mat)修改):  
if(chinnels==1)  
{//灰度圖像   
    uchar *pS;  
    uchar *pImg=(uchar *)CI.GetBits();  
    int step=CI.GetPitch();  
    for(int i=0;i<h;i++)  
    {  
        pS=img.ptr<uchar>(i);  
        for(int j=0;j<w;j++)  
        {  
            *(pImg+i*step+j)=pS[j];  
        }  
    }  
}  
//(2)如果是3個通道(彩色圖像)  
//沒有調色板,直接賦值  
if(chinnels==3)  
{//彩色圖像  
        uchar *pS;  
        uchar *pImg=(uchar *)CI.GetBits();//得到CImage數據區地址  
        int step=CI.GetPitch();  
        //這個是一行像素站的存儲空間w*3,並且結果是4的倍數(這個不用關注,到底是不是4的倍數有待考證)  
        for(int i=0;i<h;i++)  
        {  
            pS=img.ptr<uchar>(i);  
            for(int j=0;j<w;j++)  
            {  
                for(int k=0;k<3;k++)  
                    *(pImg+i*step+j*3+k)=pS[j*3+k];  
                //注意到這里的step不用乘以3  
            }  
        }  
}  
//4.至此已經構建好CImage,下來就是顯示它。我們可以直接在對話框、單文檔等地方顯示他,還可以使用CPictureCtrl空間顯示他。下面給出幾個顯示方法:  
//顯示前,這里有個問題,等會討論  
//(1)放在一個按鈕響應或者函數中  
//這里的m_Pic是一個CPictureCtrl的control,其他控件等也一樣  
//CStatic m_Pic;  
//DDX_Control(pDX, IDC_STATIC_Img, m_Pic);  
CWnd * pCWnd = CWnd::FromHandle(m_Pic.GetSafeHwnd())//通過變量得到dc比較復雜,但很好用  
CPaintDC dc(pCWnd);  
        Invalidate(false);  
        SetStretchBltMode(dc.m_hDC,COLORONCOLOR);  
        //這個需要百度看看為什么這樣設置  
        CI.StretchBlt(dc.m_hDC,rect,SRCCOPY);  
        //這里顯示大小rect(CRect類型)也由自己定義,這個函數有許多重載函數  
        //圖像顯示的大小和效果,在你能顯示出來后,可以慢慢考慮  
  
        //這里的控件的dc還可以由下面方式取得  
            CPaintDC dc(GetDlgItem(IDC_STATIC_Img));//IDC_STATIC_Img是空間的ID  
        //(2)直接顯示(下面就寫得簡單點,少的部分自己加)  
            CDC *pDC=GetDC();  
        Invalidate(false);  
        CI.StretchBlt(pDC->m_hDC,rect,SRCCOPY);  
        ///或者  
            CPaintDC dc(this);  
        CI.Draw(dc.m_hDC,0,0);//這個以某個dc(可以是窗口)的(0,0)為起點  

總結起來就是:

void MatToCImage( Mat &mat, CImage &cImage)  
{  
    //create new CImage  
    int width    = mat.cols;  
    int height   = mat.rows;  
    int channels = mat.channels();  
  
    cImage.Destroy(); //clear  
    cImage.Create(width,   
        height, //positive: left-bottom-up   or negative: left-top-down  
        8*channels ); //numbers of bits per pixel  
  
    //copy values  
    uchar* ps;  
    uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer  
          
    //The pitch is the distance, in bytes. represent the beginning of   
    // one bitmap line and the beginning of the next bitmap line  
    int step = cImage.GetPitch();  
  
    for (int i = 0; i < height; ++i)  
    {  
        ps = (mat.ptr<uchar>(i));  
        for ( int j = 0; j < width; ++j )  
        {  
            if ( channels == 1 ) //gray  
            {  
                *(pimg + i*step + j) = ps[j];  
            }  
            else if ( channels == 3 ) //color  
            {  
                for (int k = 0 ; k < 3; ++k )  
                {  
                    *(pimg + i*step + j*3 + k ) = ps[j*3 + k];  
                }             
            }  
        }     
    }  
  
}  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM