彻底解决MFC/C#中在控件上播放opencv的Mat类型帧视频-亲测满足实时性要求

来源:互联网 发布:嘉兴职业技术学院网络 编辑:程序博客网 时间:2024/06/06 00:51

做MFC+opencv项目时,对于我来说,将视频显示到相应控件上(static或者picture)这个问题一直存在,虽然之前写个一个帖子,介绍了一种将opencv的显示window贴到相应控件上的方法,代码很少,使用简单。但或多或少感觉这种方法总是欠缺点什么。今天无聊时翻知乎,看到几年前几个大神的讨论,地址:https://www.zhihu.com/question/29611790,感觉很不错,总结了BrightGuo老师的方法,自己写代码跑了一下,确实不错,贴出来亮一亮!

/* *显示视频 HWND Mat */void ShowMat(Mat img, HWND hWndDisplay){if (img.channels() == 1){//调整图片与显示控件大小一致RECT rect;GetClientRect(hWndDisplay, &rect);Mat imgShow(abs(rect.top - rect.bottom), abs(rect.right - rect.left), CV_8UC1);resize(img, imgShow, imgShow.size());ATL::CImage CI;int w = imgShow.cols;//宽  int h = imgShow.rows;//高  int channels = imgShow.channels();//通道数  CI.Destroy();//防止重复创建导致程序崩溃CI.Create(w, h, 8 * channels);RGBQUAD* ColorTable;int MaxColors = 256;ColorTable = new RGBQUAD[MaxColors];CI.GetColorTable(0, MaxColors, ColorTable);//这里是取得指针  for (int i = 0; i < MaxColors; i++){ColorTable->rgbBlue = (BYTE)i;ColorTable->rgbGreen = (BYTE)i;ColorTable->rgbRed = (BYTE)i;}CI.SetColorTable(0, MaxColors, ColorTable);delete[] ColorTable;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];}}HDC dc = GetDC(hWndDisplay);CI.Draw(dc, 0, 0);ReleaseDC(hWndDisplay, dc);CI.Destroy();}if(img.channels() == 3){//调整图片与显示控件大小一致RECT rect;GetClientRect(hWndDisplay, &rect);cv::Mat imgShow(abs(rect.top - rect.bottom), abs(rect.right - rect.left), CV_8UC3);resize(img, imgShow, imgShow.size());ATL::CImage CI;int w = imgShow.cols;//宽  int h = imgShow.rows;//高  int channels = imgShow.channels();//通道数  CI.Destroy();//防止重复创建导致程序崩溃CI.Create(w, h, 8 * channels);uchar *pS;//图片数据类型:uchar; value range:0~255uchar *pImg = (uchar *)CI.GetBits();//得到CImage数据区地址 int step = CI.GetPitch();for (int i = 0; i < h; i++){pS = imgShow.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];}}HDC dc = GetDC(hWndDisplay);CI.Draw(dc, 0, 0);ReleaseDC(hWndDisplay, dc);CI.Destroy();}}
理论上用到CImage类,需要include <atlImage.h>,但我在我的工程里没有添加编译仍然通过,不知道什么原因,具体不深究了。

总之,显示视频功能实现了,自己玩去吧!

阅读全文
1 0
原创粉丝点击