1.新建对话框资源
2.给新建对话框添加类
3.修改项目平台属性 为x64,为opencv配置库(详见往期文章)
https://mp.csdn.net/mp_blog/creation/editor/136943624
4.为新加类添加头文件,添加函数如下
https://mp.csdn.net/mp_blog/creation/editor/136944656
// OpencvDlg.h : 头文件 声明
#pragma once
//#include<atlconv.h>
//#include <atlstr.h>
#include "opencv2/opencv.hpp"
#include <opencv2/highgui/highgui_c.h>
using namespace cv;
// COpencvDlg 对话框
class COpencvDlg : public CDialogEx
{
DECLARE_DYNAMIC(COpencvDlg)
public:
COpencvDlg(CWnd* pParent = NULL); // 标准构造函数
virtual ~COpencvDlg();
// 对话框数据
enum { IDD = IDD_DIALOG_OPENCV };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
CString m_Cstring_Path;// 此变量用于接受“获取图片位置”
void DrawMat(cv::Mat& img, UINT nID);//用于在Picture框体中显示图像
//参数1:opencv即将读的图,
//参数2:需要展示的Picture Control的ID
afx_msg void OnBnClickedButtonGray();
virtual BOOL OnInitDialog();
cv::Mat m_src;//用于存放源图像数据
cv::Mat m_dst;//用于存放处理后图像数据
afx_msg void OnBnClickedButtonSrc();
};
// OpencvDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "MFC_Grabimage.h"
#include "OpencvDlg.h"
#include "afxdialogex.h"
// COpencvDlg 对话框
IMPLEMENT_DYNAMIC(COpencvDlg, CDialogEx)
COpencvDlg::COpencvDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(COpencvDlg::IDD, pParent)
{
}
COpencvDlg::~COpencvDlg()
{
}
void COpencvDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(COpencvDlg, CDialogEx)
ON_BN_CLICKED(IDC_BUTTON_GRAY, &COpencvDlg::OnBnClickedButtonGray)
ON_BN_CLICKED(IDC_BUTTON_SRC, &COpencvDlg::OnBnClickedButtonSrc)
END_MESSAGE_MAP()
// COpencvDlg 消息处理程序
//用于显示图像
//参数1:opencv即将读的图,
//参数2:需要展示的Picture Control的ID
void COpencvDlg::DrawMat(cv::Mat& img, UINT nID)
{
cv::Mat imgTmp;
CRect rect;
GetDlgItem(nID)->GetClientRect(&rect); // 获取控件大小
cv::resize(img, imgTmp, cv::Size(rect.Width(), rect.Height()));// 缩放Mat并备份
// 转一下格式 ,这段可以放外面,
switch (imgTmp.channels())
{
case 1:
cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道
break;
case 3:
cv::cvtColor(imgTmp, imgTmp, CV_BGR2BGRA); // BGR三通道
break;
default:
break;
}
int pixelBytes = imgTmp.channels() * (imgTmp.depth() + 1); // 计算一个像素多少个字节
// 制作bitmapinfo(数据头)
BITMAPINFO bitInfo;
bitInfo.bmiHeader.biBitCount = 8 * pixelBytes;
bitInfo.bmiHeader.biWidth = imgTmp.cols;
bitInfo.bmiHeader.biHeight = -imgTmp.rows;
bitInfo.bmiHeader.biPlanes = 1;
bitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitInfo.bmiHeader.biCompression = BI_RGB;
bitInfo.bmiHeader.biClrImportant = 0;
bitInfo.bmiHeader.biClrUsed = 0;
bitInfo.bmiHeader.biSizeImage = 0;
bitInfo.bmiHeader.biXPelsPerMeter = 0;
bitInfo.bmiHeader.biYPelsPerMeter = 0;
// Mat.data + bitmap数据头 -> MFC
CDC* pDC = GetDlgItem(nID)->GetDC();
::StretchDIBits(
pDC->GetSafeHdc(),
0, 0, rect.Width(), rect.Height(),
0, 0, rect.Width(), rect.Height(),
imgTmp.data,
&bitInfo,
DIB_RGB_COLORS,
SRCCOPY
);
ReleaseDC(pDC);
}
BOOL COpencvDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
//为何此处的初始化 不显示?
if (!m_Cstring_Path.IsEmpty())
{
USES_CONVERSION;//和下一行的W2A的目的一样,是为了CString类型转const String
m_src = imread(W2A(m_Cstring_Path), 1);
if (m_src.empty())
{
MessageBox(_T("图像m_src为空"));
}
DrawMat(m_src, IDC_PICTURE_REC);
}
else
{
MessageBox(_T("图像路径为空"));
}
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void COpencvDlg::OnBnClickedButtonSrc()
{
// TODO: 在此添加控件通知处理程序代码
if (!m_Cstring_Path.IsEmpty())
{
USES_CONVERSION;//和下一行的W2A的目的一样,是为了CString类型转const String
m_src = imread(W2A(m_Cstring_Path), 1);
if (m_src.empty())
{
MessageBox(_T("111图像m_src为空"));
}
DrawMat(m_src, IDC_PICTURE_REC);
}
else
{
MessageBox(_T("111图像路径为空"));
}
}
void COpencvDlg::OnBnClickedButtonGray()
{
// TODO: 在此添加控件通知处理程序代码
if (m_src.empty())
{
return;
}
cv::cvtColor(m_src, m_dst, cv::COLOR_RGB2GRAY);
DrawMat(m_dst, IDC_PICTURE_DES);
}
5.在void CMFC_GrabimageDlg::OnBnClickedButtonOpencv()下添加代码,全文代码如下
// MFC_GrabimageDlg.h : 头文件
//
#pragma once
#include"MvCameraControl.h"
#include "afxwin.h"
#include "OpencvDlg.h"
// CMFC_GrabimageDlg 对话框
class CMFC_GrabimageDlg : public CDialogEx
{
// 构造
public:
CMFC_GrabimageDlg(CWnd* pParent = NULL); // 标准构造函数
~CMFC_GrabimageDlg(); //
// 对话框数据
enum { IDD = IDD_MFC_GRABIMAGE_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
void* handle;//用于存放相机句柄
MV_SAVE_IAMGE_TYPE m_enSaveImageType;//用于存储保存图片的类型
MV_DISPLAY_FRAME_INFO stDisplayInfo;//原始数据转换
int m_imagenum;//图像采集的帧号
MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;//用于保存图片的数据类型结构体 偷懒未加m_
afx_msg void OnBnClickedButtonOpen();
afx_msg void OnBnClickedButtonClose();
afx_msg void OnBnClickedButtonGrabimage();
CStatic m_picture;
afx_msg void OnBnClickedButtonSave();
afx_msg void OnBnClickedRadioBmp();
afx_msg void OnBnClickedRadioIpg();
afx_msg void OnBnClickedRadioPng();
afx_msg void OnBnClickedRadioTif();
afx_msg void OnBnClickedButtonOpencv();
COpencvDlg m_dlg;
};
// MFC_GrabimageDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "MFC_Grabimage.h"
#include "MFC_GrabimageDlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CMFC_GrabimageDlg 对话框
CMFC_GrabimageDlg::CMFC_GrabimageDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMFC_GrabimageDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
handle = NULL;
m_enSaveImageType = MV_Image_Bmp;//先默认为bmp格式,后续添加单选按钮来获取,保存的图像类型格式
}
void CMFC_GrabimageDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PICTURE, m_picture);
}
BEGIN_MESSAGE_MAP(CMFC_GrabimageDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_OPEN, &CMFC_GrabimageDlg::OnBnClickedButtonOpen)
ON_BN_CLICKED(IDC_BUTTON_CLOSE, &CMFC_GrabimageDlg::OnBnClickedButtonClose)
ON_BN_CLICKED(IDC_BUTTON_GRABIMAGE, &CMFC_GrabimageDlg::OnBnClickedButtonGrabimage)
ON_BN_CLICKED(IDC_BUTTON_SAVE, &CMFC_GrabimageDlg::OnBnClickedButtonSave)
ON_BN_CLICKED(IDC_RADIO_BMP, &CMFC_GrabimageDlg::OnBnClickedRadioBmp)
ON_BN_CLICKED(IDC_RADIO_IPG, &CMFC_GrabimageDlg::OnBnClickedRadioIpg)
ON_BN_CLICKED(IDC_RADIO_PNG, &CMFC_GrabimageDlg::OnBnClickedRadioPng)
ON_BN_CLICKED(IDC_RADIO_TIF, &CMFC_GrabimageDlg::OnBnClickedRadioTif)
ON_BN_CLICKED(IDC_BUTTON_OPENCV, &CMFC_GrabimageDlg::OnBnClickedButtonOpencv)
END_MESSAGE_MAP()
// CMFC_GrabimageDlg 消息处理程序
BOOL CMFC_GrabimageDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。 当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
// 默认选中IDC_RADIO_BMP
CheckRadioButton(IDC_RADIO_BMP, IDC_RADIO_TIF, IDC_RADIO_BMP);//单选按钮设置
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CMFC_GrabimageDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。 对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CMFC_GrabimageDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CMFC_GrabimageDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMFC_GrabimageDlg::OnBnClickedButtonOpen()
{
// TODO: 在此添加控件通知处理程序代码
//https://blog.csdn.net/weixin_44840658/article/details/89174782
//枚举相机
//先定义一个设备列表,用来存放枚举到的设备
MV_CC_DEVICE_INFO_LIST cam_List;//列表 用于存放枚举到的相机列表
//枚举
int nRet = MV_OK;
nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE, &cam_List);
if (MV_OK != nRet)
{
MessageBox(_T("枚举相机失败"));
return ;
}
else//找到相机
{
//枚举到相机后,就可以获取到相机的一些设备信息
//打印设备的SN码、设备名称、制造商
//获取枚举到的相机数量
int cam_num = cam_List.nDeviceNum;
CString str;
str.Format(_T("相机数量:%d"), cam_num);
MessageBox(str);
//留给后边研究,没有运行成功
MV_CC_DEVICE_INFO* p_cam_Info = cam_List.pDeviceInfo[0];
//相机相关参数输出
//PrintDeviceInfo(p_cam_Info);
//检查指定设备是否可访问
int MV_A = MV_CC_IsDeviceAccessible(p_cam_Info, MV_ACCESS_Control);
if (!MV_A)
{
MessageBox(_T("设备不允许访问!"));
return;
}
else
{
MessageBox(_T("设备允许访问!"));
}
}
//创建相机句柄
int nRet2 = MV_OK;
nRet2 = MV_CC_CreateHandle(&handle, cam_List.pDeviceInfo[0]);//枚举相机列表中的第一个相机
if (MV_OK != nRet2)
{
MessageBox(_T("创建句柄失败!"));
return;
}
//打开相机
int nRet3 = MV_OK;
nRet3 = MV_CC_OpenDevice(handle);
if (MV_OK != nRet3)
{
MessageBox(_T("相机打开失败!"));
return;
}
}
void CMFC_GrabimageDlg::OnBnClickedButtonClose()
{
// TODO: 在此添加控件通知处理程序代码
//关闭相机
int nRet4 = MV_OK;
nRet4 = MV_CC_CloseDevice(handle);
if (MV_OK != nRet4)
{
MessageBox(_T("相机关闭失败!"));
return;
}
else
{
MessageBox(_T("相机关闭成功!"));
}
//销毁句柄
if (handle != NULL)
{
MV_CC_DestroyHandle(handle);
handle = NULL;
}
}
void CMFC_GrabimageDlg::OnBnClickedButtonGrabimage()
{
// TODO: 在此添加控件通知处理程序代码
int nRet = MV_OK;
//开始取流
// Start grab image
nRet = MV_CC_StartGrabbing(handle);
if (MV_OK != nRet)
{
MessageBox(_T("取流失败!!"));
return ;
}
MV_FRAME_OUT stImageInfo = { 0 };
//MV_DISPLAY_FRAME_INFO stDisplayInfo = { 0 };
stDisplayInfo = { 0 };
HWND p_hwnd = m_picture.m_hWnd;//获取控件的窗口句柄
CRect rect;
m_picture.GetClientRect(&rect);
int width = rect.Width(); // 控件的宽度
int height = rect.Height(); // 控件的高度
nRet = MV_CC_GetImageBuffer(handle, &stImageInfo, 1000);
if (nRet == MV_OK)
{
CString str;
str.Format(_T("相机采集图像的宽度:%d"), stImageInfo.stFrameInfo.nWidth);
MessageBox(str);
str.Format(_T("相机采集图像的高度:%d"), stImageInfo.stFrameInfo.nHeight);
MessageBox(str);
m_imagenum = stImageInfo.stFrameInfo.nFrameNum;
str.Format(_T("相机采集图像的帧号:%d"), m_imagenum);
MessageBox(str);
//将图片显示在PictureCtrl控件窗口上
if (p_hwnd)
{
stDisplayInfo.hWnd = p_hwnd;
stDisplayInfo.pData = stImageInfo.pBufAddr;// 指向图像数据的指针
stDisplayInfo.nDataLen = stImageInfo.stFrameInfo.nFrameLen;//数据长度
stDisplayInfo.nWidth = stImageInfo.stFrameInfo.nWidth; // 图像的宽度(像素)
//stDisplayInfo.nWidth = width; // 图像的宽度(像素)用控件的宽度来代替
stDisplayInfo.nHeight = stImageInfo.stFrameInfo.nHeight; // 图像的高度(像素
//stDisplayInfo.nHeight = height;// 图像的高度(像素)用控件的高度来代替
stDisplayInfo.enPixelType = stImageInfo.stFrameInfo.enPixelType; // 像素类型,如黑白、RGB、Bayer等
MV_CC_DisplayOneFrame(handle, &stDisplayInfo);//显示图像
}
MV_CC_FreeImageBuffer(handle, &stImageInfo);
//需要用 MV_CC_FreeImageBuffer() 接口将pstFrame内的数据指针权限进行释放
}
else
{
MessageBox(_T("没有数据!"));
}
//停止采集
// Stop grab image
nRet = MV_CC_StopGrabbing(handle);
if (MV_OK != nRet)
{
MessageBox(_T("停止采集失败!"));
return ;
}
}
CMFC_GrabimageDlg::~CMFC_GrabimageDlg()
{
handle=NULL;
}
void CMFC_GrabimageDlg::OnBnClickedButtonSave()
{
// TODO: 在此添加控件通知处理程序代码
//MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;
memset(&stSaveFileParam, 0, sizeof(MV_SAVE_IMG_TO_FILE_PARAM));
stSaveFileParam.enImageType = m_enSaveImageType; // ch:需要保存的图像类型 | en:Image format to save
stSaveFileParam.enPixelType = stDisplayInfo.enPixelType; // ch:相机对应的像素格式 | en:Camera pixel type
stSaveFileParam.nWidth = stDisplayInfo.nWidth; // ch:相机对应的宽 | en:Width
stSaveFileParam.nHeight = stDisplayInfo.nHeight; // ch:相机对应的高 | en:Height
stSaveFileParam.nDataLen = stDisplayInfo.nDataLen;
stSaveFileParam.pData = stDisplayInfo.pData;
stSaveFileParam.iMethodValue = 0;
// ch:jpg图像质量范围为(50-99], png图像质量范围为[0-9] | en:jpg image nQuality range is (50-99], png image nQuality range is [0-9]
if (MV_Image_Bmp == stSaveFileParam.enImageType)
{
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);
//这段代码使用了 `sprintf_s` 函数来格式化一个字符串,该字符串将用于存储图像文件的路径。`sprintf_s` 是一个安全版本的 `sprintf` 函数,用于格式化输出到一个字符数组中,它可以防止缓冲区溢出。
//让我们详细分析一下这段代码:
//sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_stImageInfo.nFrameNum);
// `stSaveFileParam.pImagePath`: 这是指向字符数组的指针,该数组将用来存储生成的文件路径字符串。这个数组应该足够大以容纳生成的字符串。
//`256`: 这个数字是 `pImagePath` 指向的字符数组的大小,单位是字节。`sprintf_s` 需要知道目标缓冲区的大小,以避免写入超出边界。
// `"Image_w%d_h%d_fn%03d.bmp"`: 这是格式化字符串,其中包含占位符 `%d` 和 `%03d`。`%d` 用于插入十进制整数,而 `%03d` 表示一个至少三位数的十进制数,不足部分用前导零填充。
// `stSaveFileParam.nWidth`: 这是一个整数值,表示图像的宽度,它将被插入到第一个 `%d` 占位符的位置。
// `stSaveFileParam.nHeight`: 这也是一个整数值,表示图像的高度,它将被插入到第二个 `%d` 占位符的位置。
// `m_stImageInfo.nFrameNum`: 这是帧号,一个整数值,它将被插入到 `%03d` 占位符的位置,表示图像的序号,并确保至少有三位数字,不足则用零填充。
//整个字符串 `"Image_w%d_h%d_fn%03d.bmp"` 将会被格式化成类似于 `"Image_w640_h480_fn001.bmp"` 的形式,其中 `w640`、`h480` 和 `fn001` 分别代表图像的宽度、高度和帧号。
//这样做的目的是为了生成一个唯一的文件名,便于在保存图像时区分不同的图像文件,尤其是当有多张图像需要按顺序保存时。这种格式化字符串的方式在处理大量图像文件或需要动态生成文件名时非常常见。
}
else if (MV_Image_Jpeg == stSaveFileParam.enImageType)
{
stSaveFileParam.nQuality = 80;
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.jpg", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);
}
else if (MV_Image_Tif == stSaveFileParam.enImageType)
{
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.tif", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);
}
else if (MV_Image_Png == stSaveFileParam.enImageType)
{
stSaveFileParam.nQuality = 8;
sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d.png", stSaveFileParam.nWidth, stSaveFileParam.nHeight, m_imagenum);
}
int nRet = MV_CC_SaveImageToFile(handle, &stSaveFileParam);
if (MV_OK != nRet)
{
MessageBox(_T("图像保存失败!"));
return;
}
}
void CMFC_GrabimageDlg::OnBnClickedRadioBmp()
{
// TODO: 在此添加控件通知处理程序代码
m_enSaveImageType = MV_Image_Bmp;//设置图片为bmp格式
}
void CMFC_GrabimageDlg::OnBnClickedRadioIpg()
{
// TODO: 在此添加控件通知处理程序代码
m_enSaveImageType = MV_Image_Jpeg;//设置图片为jpg格式
}
void CMFC_GrabimageDlg::OnBnClickedRadioPng()
{
// TODO: 在此添加控件通知处理程序代码
m_enSaveImageType = MV_Image_Png;//设置图片为png格式
}
void CMFC_GrabimageDlg::OnBnClickedRadioTif()
{
// TODO: 在此添加控件通知处理程序代码
m_enSaveImageType = MV_Image_Tif;//设置图片为tif格式
}
void CMFC_GrabimageDlg::OnBnClickedButtonOpencv()
{
// TODO: 在此添加控件通知处理程序代码
m_dlg.m_Cstring_Path=stSaveFileParam.pImagePath;//将保存的图片位置 传递给m_dlg.m_Cstring_Path
//或者直接用下边的数据筛选
MessageBox(m_dlg.m_Cstring_Path);
//https://blog.csdn.net/weixin_45794330/article/details/137377075
if (m_dlg.DoModal() == IDOK)//如果模态对话框打开进行如下操作
{
}
}