MFC:CImage显示OpenCV:Mat矩阵图像

  1. /*************************************/  
  2.   
  3. //1.读入Mat矩阵(cvMat一样),Mat img=imread("*.*");//cvLoadImage  
  4. //确保转换前矩阵中的数据都是uchar(0~255)类型(不是的话量化到此区间),这样才能显示。(初学者,包括我经常忘了此事)  
  5. //2.根据矩阵大小创建(CImage::Create)新的的CImage类  
  6. CImage CI;  
  7. int w=img.cols;//宽  
  8. int h=img.rows;//高  
  9. int chinnels=img.channels();//通道数  
  10. CI.Destroy();//创建前,最好使用它,防止重复创建,程序崩溃  
  11. CI.Create(w,h,8*chinnels);  
  12.   
  13. //3.下来就是对CI进行赋值了,这里是最核心的地方,分二类讨论  
  14. //  (1)如果是1个通道的图像(灰度图像) DIB格式才需要对调色板设置  
  15. //  CImage中内置了调色板,我们要对他进行赋值:  
  16. RGBQUAD* ColorTable;  
  17. int MaxColors=256;  
  18. //这里可以通过CI.GetMaxColorTableEntries()得到大小(如果你是CI.Load读入图像的话)  
  19. ColorTable = new RGBQUAD[MaxColors];  
  20. CI.GetColorTable(0,MaxColors,ColorTable);//这里是取得指针  
  21. for (int i=0; i<MaxColors; i++)  
  22. {  
  23.     ColorTable[i].rgbBlue = (BYTE)i;  
  24.     //BYTE和uchar一回事,但MFC中都用它  
  25.     ColorTable[i].rgbGreen = (BYTE)i;  
  26.     ColorTable[i].rgbRed = (BYTE)i;  
  27. }  
  28. CI.SetColorTable(0,MaxColors,ColorTable);  
  29. delete []ColorTable;  
  30. //然后就是数据拷贝了(这里的矩阵表示方法,根据需要(cvMat or Mat)修改):  
  31. if(chinnels==1)  
  32. {//灰度图像   
  33.     uchar *pS;  
  34.     uchar *pImg=(uchar *)CI.GetBits();  
  35.     int step=CI.GetPitch();  
  36.     for(int i=0;i<h;i++)  
  37.     {  
  38.         pS=img.ptr<uchar>(i);  
  39.         for(int j=0;j<w;j++)  
  40.         {  
  41.             *(pImg+i*step+j)=pS[j];  
  42.         }  
  43.     }  
  44. }  
  45. //(2)如果是3个通道(彩色图像)  
  46. //没有调色板,直接赋值  
  47. if(chinnels==3)  
  48. {//彩色图像  
  49.         uchar *pS;  
  50.         uchar *pImg=(uchar *)CI.GetBits();//得到CImage数据区地址  
  51.         int step=CI.GetPitch();  
  52.         //这个是一行像素站的存储空间w*3,并且结果是4的倍数(这个不用关注,到底是不是4的倍数有待考证)  
  53.         for(int i=0;i<h;i++)  
  54.         {  
  55.             pS=img.ptr<uchar>(i);  
  56.             for(int j=0;j<w;j++)  
  57.             {  
  58.                 for(int k=0;k<3;k++)  
  59.                     *(pImg+i*step+j*3+k)=pS[j*3+k];  
  60.                 //注意到这里的step不用乘以3  
  61.             }  
  62.         }  
  63. }  
  64. //4.至此已经构建好CImage,下来就是显示它。我们可以直接在对话框、单文档等地方显示他,还可以使用CPictureCtrl空间显示他。下面给出几个显示方法:  
  65. //显示前,这里有个问题,等会讨论  
  66. //(1)放在一个按钮响应或者函数中  
  67. //这里的m_Pic是一个CPictureCtrl的control,其他控件等也一样  
  68. //CStatic m_Pic;  
  69. //DDX_Control(pDX, IDC_STATIC_Img, m_Pic);  
  70. CWnd * pCWnd = CWnd::FromHandle(m_Pic.GetSafeHwnd())//通过变量得到dc比较复杂,但很好用  
  71. CPaintDC dc(pCWnd);  
  72.         Invalidate(false);  
  73.         SetStretchBltMode(dc.m_hDC,COLORONCOLOR);  
  74.         //这个需要百度看看为什么这样设置  
  75.         CI.StretchBlt(dc.m_hDC,rect,SRCCOPY);  
  76.         //这里显示大小rect(CRect类型)也由自己定义,这个函数有许多重载函数  
  77.         //图像显示的大小和效果,在你能显示出来后,可以慢慢考虑  
  78.   
  79.         //这里的控件的dc还可以由下面方式取得  
  80.             CPaintDC dc(GetDlgItem(IDC_STATIC_Img));//IDC_STATIC_Img是空间的ID  
  81.         //(2)直接显示(下面就写得简单点,少的部分自己加)  
  82.             CDC *pDC=GetDC();  
  83.         Invalidate(false);  
  84.         CI.StretchBlt(pDC->m_hDC,rect,SRCCOPY);  
  85.         ///或者  
  86.             CPaintDC dc(this);  
  87.         CI.Draw(dc.m_hDC,0,0);//这个以某个dc(可以是窗口)的(0,0)为起点  




总结起来就是:


[cpp]  view plain copy
  1. void MatToCImage( Mat &mat, CImage &cImage)  
  2. {  
  3.     //create new CImage  
  4.     int width    = mat.cols;  
  5.     int height   = mat.rows;  
  6.     int channels = mat.channels();  
  7.   
  8.     cImage.Destroy(); //clear  
  9.     cImage.Create(width,   
  10.         height, //positive: left-bottom-up   or negative: left-top-down  
  11.         8*channels ); //numbers of bits per pixel  
  12.   
  13.     //copy values  
  14.     uchar* ps;  
  15.     uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer  
  16.           
  17.     //The pitch is the distance, in bytes. represent the beginning of   
  18.     // one bitmap line and the beginning of the next bitmap line  
  19.     int step = cImage.GetPitch();  
  20.   
  21.     for (int i = 0; i < height; ++i)  
  22.     {  
  23.         ps = (mat.ptr<uchar>(i));  
  24.         for ( int j = 0; j < width; ++j )  
  25.         {  
  26.             if ( channels == 1 ) //gray  
  27.             {  
  28.                 *(pimg + i*step + j) = ps[j];  
  29.             }  
  30.             else if ( channels == 3 ) //color  
  31.             {  
  32.                 for (int k = 0 ; k < 3; ++k )  
  33.                 {  
  34.                     *(pimg + i*step + j*3 + k ) = ps[j*3 + k];  
  35.                 }             
  36.             }  
  37.         }     
  38.     }  
  39.   
  40. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值