*************************************/

//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];
}
}
}
} }

MFC:CImage显示OpenCV:Mat矩阵图像的更多相关文章

  1. 使用GDI+显示OpenCV中的图像IplImage

    OpenCV虽然自带了轻量级的界面库HighGUI,但是支持的图像化元素实在是太少了,一般只在前期算法测试时使用.实际产品还是使用MFC库.因此本文记录了如何在GDI+中显示OpenCV中的IplIm ...

  2. 一个显示 OpenCV Mat 图像的自定义 Qt 控件

    今天学习 Qt 的时候顺手写了一个,包含一个头文件 qcvdisplay.h 和一个源文件 qcvdisplay.cpp,因为这是 qt 默认的文件命名方式,在 Qt Designer 中提升控件时会 ...

  3. OpenCV MAT基本图像容器

    参考博客: OpenCv中cv::Mat和IplImage,CvMat之间的转换 Mat - 基本图像容器 Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Mat ...

  4. Opencv Mat矩阵中data、size、depth、elemSize、step等属性的理解

    data: uchar类型的指针,指向Mat数据矩阵的首地址.可以理解为标示一个房屋的门牌号: dims: Mat矩阵的维度,若Mat是一个二维矩阵,则dims=2,三维则dims=3,大多数情况下处 ...

  5. OpenCV Mat - 基本图像容器

    Mat 在2001年刚刚出现的时候,OpenCV基于 C 语言接口而建.为了在内存(memory)中存放图像,当时采用名为 IplImage 的C语言结构体,时至今日这仍出现在大多数的旧版教程和教学材 ...

  6. Opencv Mat矩阵操作注意事项

    矩阵操作通常不会进行元素复制,应注意: Mat a=Mat(100,100,CV_32S); Mat b=Mat(100,100,CV_32S); b=a.col(8);//此时并未进行元素赋值,而只 ...

  7. Imagelab-0-QT label显示 opencv 图像

    Imagelab-0-QT label显示 opencv 图像 opencvc++qtimagelab 开始之前 这其实也是opencv 处理图像的系列, 只是想我们在进一步复杂化我们的代码之前, 每 ...

  8. OpenCV 显示Mat矩阵异常 显示“程序停止工作” 解决办法

    笔者调试OpenCV 程序时,在使用标准输出显示Mat矩阵时,编译没有错误,但每次运行都弹出程序停止工作的对话框.google之,得到解决方案. 程序如下: #include <iostream ...

  9. C++ Opencv Mat类型使用的几个注意事项及自写函数实现Laplace图像锐化

    为了提升自己对Opencv中Mat数据类型的熟悉和掌握程度,自己尝试着写了一下Laplace图像锐化函数,一路坎坷,踩坑不断.现将代码分享如下: #include <opencv2/opencv ...

随机推荐

  1. 蓝桥杯(Java方法、详细解法分析)基础练习 阶乘计算

    问题描述 给定n和len,输出n!末尾len位. 输入格式 一行两个正整数n和len. 输出格式 一行一个字符串,表示答案.长度不足用前置零补全. 样例输入 6 5 样例输出 00720 数据规模和约 ...

  2. Java实现 蓝桥杯VIP 算法训练 FBI树

    问题描述 我们可以把由"0"和"1"组成的字符串分为三类:全"0"串称为B串,全"1"串称为I串,既含"0&q ...

  3. Java实现 LeetCode 23 合并K个排序链表

    23. 合并K个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1->3->4, 2->6 ] 输 ...

  4. jstat监控JVM内存使用、GC回收情况

    jstat -gcutil 2388 3000 6 每隔3秒打印一次pid为2388的堆内存的使用情况,共打印6次 S0— Heap上的 Survivor space 0 区已使用空间的百分比 S1  ...

  5. pi-star 升级固件命令

    单天线热点: sudo pistar-mmdvmhshatflash hs_hat 双天线热点: sudo pistar-mmdvmhshatflash hs_dual_hat 命令: wget ht ...

  6. js循环练习

    var a=1; while(a>0){ var b=prompt('input number'); if(b>a){ alert('big'); } else if(b<a){ a ...

  7. @loj - 3046@「ZJOI2019」语言

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 九条可怜是一个喜欢规律的女孩子.按照规律,第二题应该是一道和数据 ...

  8. @gym - 100591D@ Fox Rocks

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定 N 个点以及 P 条单向道路 Ai -> Bi,每条 ...

  9. Ubuntu18.04下MySQL8.0和Navicat15的安装与使用

    目录 一.MySQL8.0安装 二.Navicat安装并与MySQL连接 一.MySQL8.0安装 注意:若直接 sudo apt install mysql-server,你会发现安装后的版本是5. ...

  10. Python基础002---基础知识

    一.标识符 标识符是自己定义的,是开发人员在程序中自己定义的一些符号和名称,如变量名.函数名等.在 Python 里,标识符由字母(区分大小写).数字.下划线组成,且数字不能开头.常用的命名方法有小驼 ...