首页 > 学院 > 开发设计 > 正文

opencv Mat显示到指定窗体 CImage实现

2019-11-08 03:11:02
字体:
来源:转载
供稿:网友

紧接着上一篇博文,因为direct2d的方式不够稳定,所以博主急需要找到其他的方法,实现把opencv的Mat显示到指定的窗体中。

本博文主要记录基于CImage类的实现。

1、要使用微软提供的CImage类需要包含头文件:

#include <atlimage.h> 2、要使用的三个函数

(1)改变Mat图像的大小,以适应窗体

BOOL GetFixMat(const cv::Mat& src_img, cv::Mat& dst_img, unsigned int dc_heigh, unsigned int dc_width){	if (!src_img.data)	{		return FALSE;	}	unsigned int img_rows(src_img.rows);	unsigned int img_cols(src_img.cols);	unsigned int fix_heigh(chaoMin(img_rows, dc_heigh));	unsigned int fix_width(chaoMin(img_cols, dc_width));	float ratio_w = static_cast<float>(fix_width) / static_cast<float>(img_cols);	float ratio_h = static_cast<float>(fix_heigh) / static_cast<float>(img_rows);	float ratio = chaoMin(ratio_w, ratio_h);	int show_width = static_cast<unsigned int>(ratio * img_cols);	int show_height = static_cast<unsigned int>(ratio * img_rows);	cv::resize(src_img, dst_img, cv::Size(show_width, show_height), (0.0), (0.0), cv::INTER_LINEAR);	return TRUE;}

(2)将Mat转换成CImage

BOOL ConvertMat2CImage(const cv::Mat& src_img, CImage& dst_img){	if (!src_img.data)	{		return FALSE;	}	int width = src_img.cols;           //获取输入图像的宽度  	int height = src_img.rows;          //获取输入图像的高度  	int channels = src_img.channels();  //获取输入图像的  	int src_type = src_img.type();	dst_img.Destroy();	switch (src_type)	{	case CV_8UC1:	{		dst_img.Create(width, -1 * height, 8 * channels);		unsigned char* dst_data = static_cast<unsigned char*>(dst_img.GetBits());		int step_size = dst_img.GetPitch();     //获取位图行与行之间相差的字节数  		unsigned char* src_data = nullptr;		for (int i = 0; i < height; i++)		{			src_data = const_cast<unsigned char*>(src_img.ptr<unsigned char>(i));   //获取行指针  			for (int j = 0; j < width; j++)			{				if (step_size > 0)				{					*(dst_data + step_size*i + j) = *src_data++;				}   //像素的排列方式是自左上开始的  				else				{					*(dst_data + step_size*i - j) = *src_data++;				}			}		}		break;	}	case CV_8UC3:	{		dst_img.Create(width, height, 8 * channels);		unsigned char* dst_data = static_cast<unsigned char*>(dst_img.GetBits());		int step_size = dst_img.GetPitch();     //获取位图行与行之间相差的字节数  		unsigned char* src_data = nullptr;		for (int i = 0; i < height; i++)		{			src_data = const_cast<unsigned char*>(src_img.ptr<unsigned char>(i));   //获取行指针  			for (int j = 0; j < width; j++)			{				for (int k = 0; k < 3; k++)				{					*(dst_data + step_size*i + j * 3 + k) = src_data[3 * j + k];				}			}		}		break;	}	default:		MessageBox(NULL, _T("输入的图像类型出错"), _T("提示"), MB_ICONINFORMATION | MB_OK);		break;	}	return TRUE;}(3)将CImage显示到窗体

BOOL Show2DC(const cv::Mat& img, HDC dst_hdc, unsigned int dc_heigh, unsigned int dc_width){	if (!img.data)	{		return FALSE;	}	CImage dst_img;	cv::Mat temp;   //定义中间变量  	GetFixMat(img, temp, dc_heigh, dc_width);  //图像的几何大小变换  	ConvertMat2CImage(temp, dst_img);          //图像转换  	int offsetx = (dc_width - temp.cols) / 2;           //调整偏移量  	int offsety = (dc_heigh - temp.rows) / 2;	BOOL temp1 = dst_img.Draw(dst_hdc, offsetx, offsety, dst_img.GetWidth(), dst_img.GetHeight());  //图像显示  	return TRUE;}3、调用示例

void getHanle(HWND formhandle, int HDCwidth, int HDCheight)//记录传过来的窗体句柄,和窗体大小{	windowHDC = GetDC(formhandle);//传过来HWND,得到窗体HDC,	windowHeight = HDCheight;	windowwidth = HDCwidth;}
void showImage(){	int idx = 1;	while (true)	{		if (idx > 3) idx = 1;		char filename[100];		sPRintf_s(filename, "%d.bmp", idx);		Mat image = imread(filename);		if (image.empty()) continue;		Show2DC(image, windowHDC, windowHeight, windowwidth);		idx++;		Sleep(100);	}}4、完毕。并且CImage类的方式,在Win7最简单的系统上都可以使用。

over

祝大家编程快乐!


上一篇:鼠标全局钩子

下一篇:disruptor example

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表