首页 > 其他分享 >GOMfctemplate在2022年的重构(blog)

GOMfctemplate在2022年的重构(blog)

时间:2022-12-12 18:46:21浏览次数:60  
标签:src Mat img bmi blog pDlg bmiHeader 2022 GOMfctemplate

由于项目需求,采用MFC实现手持血管增强。工具平台已经发生了较大变化,对GOMfcetemplate进行重构;
根据现有理解,首先尝试64位平台。
1、生成MFC dialog

2、引入OpenCV,显示图片
还是区分3个地方,分别是 目录,解决include

链接器,解决lib

以及Dll,同步引入GOCVHelper,目前最新2020版本

测试图片显示:

进一步测试MFC控件自己的图片显示(现在已经可以不使用CVVImage了)

这里对代码进行一些修改,方便调用。

// 在指定控件中显示图片
void CMFCApplicationDlg::showImage(Mat src, UINT ID)
{
if (src.empty())
return;
CRect rect;
GetDlgItem(ID)->GetClientRect(&rect); // 获取显示控件(位置)的 HDC(设备句柄)
CDC* pDC = GetDlgItem(ID)->GetDC();
HDC hDC = pDC->GetSafeHdc();
BITMAPINFO bmi = { 0 }; //生成bitmap信息
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biWidth = src.cols;
bmi.bmiHeader.biHeight = src.rows * -1;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24;

RGBTRIPLE* m_bitmapBits = new RGBTRIPLE[src.cols * src.rows];  //拷贝到内存中
Mat cv_bitmapBits(Size(src.cols, src.rows), CV_8UC3, m_bitmapBits);
src.copyTo(cv_bitmapBits);                     
if (rect.Width() > src.cols)                 //结果显示出来
    SetStretchBltMode(hDC,HALFTONE);
else
    SetStretchBltMode(hDC, COLORONCOLOR);
::StretchDIBits(hDC, 0, 0, rect.Width(), rect.Height(), 0, 0, src.cols, src.rows, src.data, &bmi, DIB_RGB_COLORS, SRCCOPY);

delete(m_bitmapBits )
ReleaseDC(pDC);
}

 

3、引入视频采集,处理视频
引入Dshow获得视频数据。首先是include

而后是lib

最后总的来说,使用的还是“Video Capture using DirectShow Author: Shiqi Yu ”
按照说明,将CameraDS.h CameraDS.cpp以及目录DirectShow复制到你的项目中

不要忘记添加CmaeraDS.h

正确设置的话,应该可以直接运行。

在Oninit_dialog中获得摄像头变量

m_nCamCount = CCameraDS::CameraCount();//摄像头总数
//获得摄像头数目
char camera_name[1024];
char istr[25];
for (int i = 0; i < m_nCamCount; i++)
{
int retval = CCameraDS::CameraName(i, camera_name, sizeof(camera_name));
sprintf_s(istr, " # %d", i);
strcat_s(camera_name, istr);
CString camstr(camera_name);
if (retval > 0)
m_CBNCamList.AddString(camstr);
else
AfxMessageBox(_T("不能获取摄像头的名称"));
}

 


这个时候,启动的时候就可以自动获得摄像头。

那么我们选中并打开采集线程。这里细节很多,线程函数需要独立撰写

//摄像头显示循环,所有关于采集的操作是通过主线程传递控制变量到采集线程,而后由采集线程完成的
DWORD WINAPI CaptureThread(LPVOID lpParameter)
{
CGOMfcTemplate2Dlg* pDlg = (CGOMfcTemplate2Dlg)lpParameter;
double t_start = (double)cv::getTickCount(); //开始时间
Mat tmpPrydown;
//#pragma omp parallel for
while (true)
{
if (pDlg->b_closeCam)//退出循环
break;
double t = ((double)cv::getTickCount() - t_start) / getTickFrequency();
if (t <= 0.1)//fps =10,主动降低速度
{
Sleep(100);
continue;
}
else
{
t_start = (double)cv::getTickCount();
}
//从directX中获得当前图像并显示出来
IplImage queryframe = pDlg->cameraDs.QueryFrame();
//在2.0版本中可以强转,在3.0中需要使用函数
Mat camframe = cvarrToMat(queryframe);
pDlg->showImage(camframe, IDC_CAM); //显示原始图像
////根据条件,决定是否采用算法
Mat dst;
Mat img;
cvtColor(camframe, img, COLOR_BGR2GRAY);
cvtColor(img, img, COLOR_GRAY2BGR);
if (pDlg->bMethod) //这里实现的是灰度转彩色
{
// extract L channel and subtract mean
Mat lab, L, input;
img.convertTo(img, CV_32F, 1.0 / 255);
cvtColor(img, lab, COLOR_BGR2Lab);
extractChannel(lab, L, 0);
resize(L, input, Size(W_in, H_in));
input -= 50;
// run the L channel through the network
Mat inputBlob = blobFromImage(input);
pDlg->net.setInput(inputBlob);
Mat result = pDlg->net.forward();
// retrieve the calculated a,b channels from the network output
Size siz(result.size[2], result.size[3]);
Mat a = Mat(siz, CV_32F, result.ptr(0, 0));
Mat b = Mat(siz, CV_32F, result.ptr(0, 1));
resize(a, a, img.size());
resize(b, b, img.size());
// merge, and convert back to BGR
Mat color, chn[] = { L, a, b };
merge(chn, 3, lab);
cvtColor(lab, dst, COLOR_Lab2BGR);
dst.convertTo(dst, CV_8UC3, 255); //保证输入到imageshow中的是8u rgb
}
else
{
dst = img.clone();
}
pDlg->showImage(dst, IDC_PIC); //显示网络处理图像
}
return 0;
}

 


这时就显示出来啦。基础的显示、采集工作就完毕了。

标签:src,Mat,img,bmi,blog,pDlg,bmiHeader,2022,GOMfctemplate
From: https://www.cnblogs.com/jsxyhelu/p/16976847.html

相关文章