在MFC图像控件上显示opencv Mat格式图片


/*
显示opencv图片格式Mat到图像控件vIDC上
vMat:图像Mat
vIDC:图像控件ID
*/
void CDLFaceDlg::showMat(Mat vMat, int vIDC){ 	
	if (vMat.empty()){
		return; 
	}
	
	//获取图片的宽 高度
	int tImgWidth = vMat.cols; 
	int tImgHeight = vMat.rows; 
	 
	//获取Picture Control控件的大小
	CRect rect;
	GetDlgItem(vIDC)->GetWindowRect(&rect);
	//将客户区选中到控件表示的矩形区域内
	//ScreenToClient(&rect);

	CString msg;
	msg.Format(_T("tImgWidth=%d,tImgHeight=%d, rect:w=%d, h=%d"), tImgWidth, tImgHeight, rect.Width(), rect.Height());
	//MessageBox(msg, _T("showMat"), MB_OK); 
	 
	int tNewWidth, tNewHeight;

	int tLeft = 0, tTop = 0, tRight = rect.Width(), tBottom = rect.Height();
	if (tImgWidth > tImgHeight){
		//如果图像是横的
		tNewWidth = tRight;
		tNewHeight = tNewWidth * tImgHeight / tImgWidth;
		tTop = (tNewWidth - tNewHeight) / 2;
		tBottom = rect.Height() - tTop;
	}
	else{
		//如果图像是竖的
		tNewHeight = tBottom;
		tNewWidth = tNewHeight * tImgWidth / tImgHeight;
		tLeft = (tNewHeight - tNewWidth) / 2;
		tRight = rect.Width() - tLeft;
	}

	Mat zoomImg;
	cv::resize(vMat, zoomImg, Size(tNewWidth-1, tNewHeight-1)); 
	 
	//把opencv的图转为CImage,才能显示在图像控件上
	CImage cimg; 
	MatToCImage(zoomImg, cimg);
 
	msg.Format(_T("neww=%d, newh=%d"), cimg.GetWidth(), cimg.GetHeight());
	//MessageBox(msg, _T("mm"), MB_OK); 

	///-----------------------------------------------------------------
	//以下是显示
	CWnd *pWnd = NULL;
	pWnd = GetDlgItem(vIDC);//获取控件句柄 

	CDC *pDc = NULL;
	pDc = pWnd->GetDC();//获取picture的DC

	//白色背景填充,保留边框
	CBrush brush(RGB(255, 255, 255));
		
	CRect tRect = CRect(1, 1, rect.Width()-2, rect.Height()-2);
	pDc->FillRect(tRect, &brush);
	cimg.Draw(pDc->m_hDC, CRect(tLeft+1, tTop+1, tRight-1, tBottom-1));
	 
	ReleaseDC(pDc);
	//msg.Format(_T("tLeft=%d,tTop=%d, tRight=%d,tBottom=%d"), tLeft, tTop, tRight, tBottom);
	//MessageBox(msg, _T("showMat"), MB_OK);
} 

// 实现cv::Mat 结构到 CImage结构的转化
void CDLFaceDlg::MatToCImage(Mat& mat, CImage& cImage)
{
	int width = mat.cols;
	int height = mat.rows;
	int channels = mat.channels();

	cImage.Destroy();//这一步是防止重复利用造成内存问题
	cImage.Create(width, height, 8 * channels);

	uchar* ps;
	uchar* pimg = (uchar*)cImage.GetBits(); //获取CImage的像素存贮区的指针
	int step = cImage.GetPitch();//每行的字节数,注意这个返回值有正有负

	// 如果是1个通道的图像(灰度图像) DIB格式才需要对调色板设置  
	// CImage中内置了调色板,我们要对他进行赋值:
	if (1 == channels)
	{
		RGBQUAD* ColorTable;
		int MaxColors = 256;
		//这里可以通过CI.GetMaxColorTableEntries()得到大小(如果你是CI.Load读入图像的话)  
		ColorTable = new RGBQUAD[MaxColors];
		cImage.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;
		}
		cImage.SetColorTable(0, MaxColors, ColorTable);
		delete[]ColorTable;
	}


	for (int i = 0; i < height; i++)
	{
		ps = mat.ptr<uchar>(i);
		for (int j = 0; j < width; j++)
		{
			if (1 == channels)
			{
				*(pimg + i*step + j) = ps[j];
				//*(pimg + i*step + j) = 105;
			}
			else if (3 == channels)
			{
				*(pimg + i*step + j * 3) = ps[j * 3];
				*(pimg + i*step + j * 3 + 1) = ps[j * 3 + 1];
				*(pimg + i*step + j * 3 + 2) = ps[j * 3 + 2];
			}
		}
	}	 
}


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值