php 图片转mat,OpenCV中Mat对象转CImage

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,8*channels ); //默认图像像素单通道占用1个字节

//copy values

uchar* ps;

uchar* pimg = (uchar*)cImage.GetBits(); //A pointer to the bitmap buffer

int step = cImage.GetPitch();

for (int i = 0; i < height; ++i)

{

ps = (mat.ptr(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];

}

}

}

}

}

下面是完整的将OpenCV:Mat矩阵图像转换为MFC:CImage图像,并显示。包括了CImage调色板的设置等。

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

//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

{

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

{

pS=img.ptr(i);

for(int j=0;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

{

pS=img.ptr(i);

for(int j=0;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)为起点

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值