MFC:CImage显示OpenCV:Mat矩阵图像
*************************************/
//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矩阵图像的更多相关文章
- 使用GDI+显示OpenCV中的图像IplImage
OpenCV虽然自带了轻量级的界面库HighGUI,但是支持的图像化元素实在是太少了,一般只在前期算法测试时使用.实际产品还是使用MFC库.因此本文记录了如何在GDI+中显示OpenCV中的IplIm ...
- 一个显示 OpenCV Mat 图像的自定义 Qt 控件
今天学习 Qt 的时候顺手写了一个,包含一个头文件 qcvdisplay.h 和一个源文件 qcvdisplay.cpp,因为这是 qt 默认的文件命名方式,在 Qt Designer 中提升控件时会 ...
- OpenCV MAT基本图像容器
参考博客: OpenCv中cv::Mat和IplImage,CvMat之间的转换 Mat - 基本图像容器 Mat类型较CvMat和IplImage有更强的矩阵运算能力,支持常见的矩阵运算(参照Mat ...
- Opencv Mat矩阵中data、size、depth、elemSize、step等属性的理解
data: uchar类型的指针,指向Mat数据矩阵的首地址.可以理解为标示一个房屋的门牌号: dims: Mat矩阵的维度,若Mat是一个二维矩阵,则dims=2,三维则dims=3,大多数情况下处 ...
- OpenCV Mat - 基本图像容器
Mat 在2001年刚刚出现的时候,OpenCV基于 C 语言接口而建.为了在内存(memory)中存放图像,当时采用名为 IplImage 的C语言结构体,时至今日这仍出现在大多数的旧版教程和教学材 ...
- Opencv Mat矩阵操作注意事项
矩阵操作通常不会进行元素复制,应注意: Mat a=Mat(100,100,CV_32S); Mat b=Mat(100,100,CV_32S); b=a.col(8);//此时并未进行元素赋值,而只 ...
- Imagelab-0-QT label显示 opencv 图像
Imagelab-0-QT label显示 opencv 图像 opencvc++qtimagelab 开始之前 这其实也是opencv 处理图像的系列, 只是想我们在进一步复杂化我们的代码之前, 每 ...
- OpenCV 显示Mat矩阵异常 显示“程序停止工作” 解决办法
笔者调试OpenCV 程序时,在使用标准输出显示Mat矩阵时,编译没有错误,但每次运行都弹出程序停止工作的对话框.google之,得到解决方案. 程序如下: #include <iostream ...
- C++ Opencv Mat类型使用的几个注意事项及自写函数实现Laplace图像锐化
为了提升自己对Opencv中Mat数据类型的熟悉和掌握程度,自己尝试着写了一下Laplace图像锐化函数,一路坎坷,踩坑不断.现将代码分享如下: #include <opencv2/opencv ...
随机推荐
- flex布局以及常用属性。
(1)flex布局排列 会消除块状属性,所有与块状相关的属性将失效,比如块状元素会独占一行,如图2,设置flex后会在一行排列
- Java实现 LeetCode 767 重构字符串(ASCII的转换)
767. 重构字符串 给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同. 若可行,输出任意可行的结果.若不可行,返回空字符串. 示例 1: 输入: S = "aab&qu ...
- Java实现 蓝桥杯VIP 算法训练 寂寞的数
问题描述 道德经曰:一生二,二生三,三生万物. 对于任意正整数n,我们定义d(n)的值为为n加上组成n的各个数字的和.例如,d(23)=23+2+3=28, d(1481)=1481+1+4+8+1= ...
- Java实现 LeetCode 372 超级次方
372. 超级次方 你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出. 示例 1: 输入: a = 2, b = [3] 输出: 8 示例 2: ...
- Java实现 LeetCode 101 对称二叉树
101. 对称二叉树 给定一个二叉树,检查它是否是镜像对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2 ...
- Java实现 LeetCode 72 编辑距离
72. 编辑距离 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可以对一个单词进行如下三种操作: 插入一个字符 删除一个字符 替换一个字 ...
- Java实现 洛谷 P1582 倒水
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import ...
- Java实现第八届蓝桥杯正则问题
正则问题 考虑一种简单的正则表达式: 只由 x ( ) | 组成的正则表达式. 小明想求出这个正则表达式能接受的最长字符串的长度. 例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是 ...
- Linux文件搜索命令locate、which、grep详解
命令locate详解 命令locate,其基本功能是在文件资料库中可以快速的搜索系统文件,占用系统资源很少,例如:locate my.cnf 还可以使用locate -i [文件名],不区分大小写进行 ...
- 变分(图)自编码器不能直接应用于下游任务(GAE, VGAE, AE, VAE and SAE)
自编码器是无监督学习领域中一个非常重要的工具.最近由于图神经网络的兴起,图自编码器得到了广泛的关注.笔者最近在做相关的工作,对科研工作中经常遇到的:自编码器(AE),变分自编码器(VAE),图 ...