当前位置: 首页 > ai >正文

MFC 调用海康相机进行软触发

初始化相机类文件

#pragma once
#include "MvCameraControl.h"
class CMvCamera
{
public:CMvCamera();~CMvCamera();//初始化相机int InitCamera();int SaveCurrentImage(CString filePath);//关闭相机void CloseCamera();//设置int SetEnumValue(IN const char* strKey, IN unsigned int nValue);// ch:执行一次Command型命令,如 UserSetSaveint CommandExecute(IN const char* strKey);public:int nRet;void* m_hDevHandle; // 初始化设备句柄为空
};
#include "pch.h"
#include "CMvCamera.h"CMvCamera::CMvCamera()
{
}CMvCamera::~CMvCamera()
{CloseCamera();if (m_hDevHandle != NULL){MV_CC_DestroyHandle(m_hDevHandle);m_hDevHandle = NULL;}
}int CMvCamera::InitCamera()
{nRet = MV_OK;m_hDevHandle = NULL;// 初始化SDKnRet = MV_CC_Initialize();if (MV_OK != nRet){AfxMessageBox(_T("初始化失败"));return 0;}// 枚举设备MV_CC_DEVICE_INFO_LIST stDeviceList;memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);if (MV_OK != nRet){AfxMessageBox(_T("枚举设备失败"));return 0;}// 检查是否找到设备if (stDeviceList.nDeviceNum > 0){for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++){MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];if (NULL == pDeviceInfo){break;}}}else{AfxMessageBox(_T("没有找到设备"));return 0;}unsigned int nIndex = 0; // 选择第一个设备// 创建设备句柄nRet = MV_CC_CreateHandle(&m_hDevHandle, stDeviceList.pDeviceInfo[nIndex]);if (MV_OK != nRet){AfxMessageBox(_T("创建句柄失败"));return 0;}// 打开设备nRet = MV_CC_OpenDevice(m_hDevHandle);if (MV_OK != nRet){AfxMessageBox(_T("打开设备失败"));return 0;}// 对于GigE相机,设置最佳包大小if (stDeviceList.pDeviceInfo[nIndex]->nTLayerType == MV_GIGE_DEVICE){int nPacketSize = MV_CC_GetOptimalPacketSize(m_hDevHandle);if (nPacketSize > 0){nRet = MV_CC_SetIntValue(m_hDevHandle, "GevSCPSPacketSize", nPacketSize);if (nRet != MV_OK){AfxMessageBox(_T("Warning: Set Packet Size fail"));return 0;}}else{AfxMessageBox(_T("Warning: Get Packet Size fail"));return 0;}}// 设置触发模式为开启nRet = MV_CC_SetEnumValue(m_hDevHandle, "TriggerMode", 1);if (MV_OK != nRet){AfxMessageBox(_T("Set Trigger Mode fail!"));return 0;}// 设置触发源为软件触发nRet = MV_CC_SetEnumValue(m_hDevHandle, "TriggerSource", MV_TRIGGER_SOURCE_SOFTWARE);if (MV_OK != nRet){AfxMessageBox(_T("Set Trigger Source fail!"));return 0;}// 开始取流nRet = MV_CC_StartGrabbing(m_hDevHandle);if (MV_OK != nRet){AfxMessageBox(_T("Start Grabbing fail!"));return 0;}return 1; // 初始化成功}int CMvCamera::SaveCurrentImage(CString filePath) 
{MV_FRAME_OUT stOutFrame = { 0 };nRet = MV_CC_GetImageBuffer(m_hDevHandle, &stOutFrame, 1000);if (nRet != MV_OK) {AfxMessageBox(_T("获取图像失败!"));return -1;}// 分配输出缓冲区unsigned int nBufferSize = stOutFrame.stFrameInfo.nWidth * stOutFrame.stFrameInfo.nHeight * 4 + 2048;unsigned char* pImageBuf = new unsigned char[nBufferSize];MV_SAVE_IMAGE_PARAM_EX stSaveParam = { 0 };stSaveParam.pData = stOutFrame.pBufAddr;stSaveParam.nDataLen = stOutFrame.stFrameInfo.nFrameLen;stSaveParam.enPixelType = stOutFrame.stFrameInfo.enPixelType;stSaveParam.nWidth = stOutFrame.stFrameInfo.nWidth;stSaveParam.nHeight = stOutFrame.stFrameInfo.nHeight;stSaveParam.pImageBuffer = pImageBuf;stSaveParam.nBufferSize = nBufferSize;stSaveParam.enImageType = MV_Image_Jpeg;  // 优先尝试JPEGstSaveParam.nJpgQuality = 95;stSaveParam.iMethodValue = 2;  // 最优插值nRet = MV_CC_SaveImageEx2(m_hDevHandle, &stSaveParam);if (MV_OK != nRet) {delete[] pImageBuf;MV_CC_FreeImageBuffer(m_hDevHandle, &stOutFrame);CString strError;strError.Format(_T("转换失败! 错误码: 0x%X"), nRet);AfxMessageBox(strError);return -2;}// 保存到文件CFile file;if (!file.Open(filePath, CFile::modeCreate | CFile::modeWrite)) {delete[] pImageBuf;MV_CC_FreeImageBuffer(m_hDevHandle, &stOutFrame);AfxMessageBox(_T("创建文件失败!"));return -3;}file.Write(pImageBuf, stSaveParam.nImageLen);file.Close();// 释放资源delete[] pImageBuf;MV_CC_FreeImageBuffer(m_hDevHandle, &stOutFrame);return 0;
}void CMvCamera::CloseCamera()
{// ch:停止取流 | en:Stop grab imagenRet = MV_CC_StopGrabbing(m_hDevHandle);if (MV_OK != nRet){AfxMessageBox(_T("Stop Grabbing fail! \n"));}// ch:关闭设备 | Close devicenRet = MV_CC_CloseDevice(m_hDevHandle);if (MV_OK != nRet){AfxMessageBox(_T("ClosDevice fail\n"));}// ch:销毁句柄 | Destroy handlenRet = MV_CC_DestroyHandle(m_hDevHandle);if (MV_OK != nRet){AfxMessageBox(_T("Destroy Handle fail!\n"));}m_hDevHandle = NULL;}int CMvCamera::SetEnumValue(IN const char * strKey, IN unsigned int nValue)
{return MV_CC_SetEnumValue(m_hDevHandle, strKey, nValue);
}int CMvCamera::CommandExecute(IN const char * strKey)
{return MV_CC_SetCommandValue(m_hDevHandle, strKey);
}

点击按钮进行软触发拍照显示

void CHalconImgTestDlg::OnBnClickedGetimg()
{// 执行软件触发int nRet = m_oMvCamera->CommandExecute("TriggerSoftware");if (MV_OK != nRet){AfxMessageBox(_T("执行软件触发失败"));return;}// 获取图像MV_FRAME_OUT stOutFrame = { 0 };nRet = MV_CC_GetImageBuffer(m_oMvCamera->m_hDevHandle, &stOutFrame, 1000);if (nRet != MV_OK){AfxMessageBox(_T("获取图像失败!"));return;}// 转换为Halcon图像HalconCpp::HObject hImage;nRet = theApp.ConverMono8ToHalcon(&hImage, stOutFrame.stFrameInfo.nHeight,stOutFrame.stFrameInfo.nWidth, stOutFrame.pBufAddr);// 释放图像缓冲区MV_CC_FreeImageBuffer(m_oMvCamera->m_hDevHandle, &stOutFrame);if (nRet != MV_OK){AfxMessageBox(_T("转换到Halcon图像失败!"));return;}// 显示图像HTuple hv_WindowHandle;HWND hWnd = GetDlgItem(IDC_IMG)->m_hWnd;// 检查窗口是否已创建if (!HDevWindowStack::IsOpen()){// 创建新窗口OpenWindow(0, 0, stOutFrame.stFrameInfo.nWidth / 2, stOutFrame.stFrameInfo.nHeight / 2,(Hlong)hWnd, "visible", "", &hv_WindowHandle);HDevWindowStack::Push(hv_WindowHandle);}// 在现有窗口中显示图像if (HDevWindowStack::IsOpen()){DispObj(hImage, HDevWindowStack::GetActive());}
}

在这里插入图片描述

http://www.xdnf.cn/news/6022.html

相关文章:

  • 在Electron中实现文件下载、保存和执行功能的完整教程
  • C++类和对象:运行符重载、取地址运算符重载、const 修饰的类如何作为参数
  • SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频
  • 2025年PMP 学习十三 第9章 项目资源管理(9.1,9.2)
  • Jenkins里构建一个简单流水线
  • Web 架构之会话保持深度解析
  • 关于 js:9. Node.js 后端相关
  • 移动网页调试工具实战:从 Chrome 到 WebDebugX 的效率演进
  • 数据结构 栈和队列
  • Pytorch的Dataloader使用详解
  • 技术中台-核心技术介绍(微服务、云原生、DevOps等)
  • 计算机视觉最不卷的方向:三维重建学习路线梳理
  • 安装npm:npm未随Node.js一起安装
  • NeurIPS Paper Checklist中文翻译
  • ubuntu20.04系统搭建k8s1.28集群-docker作为容器运行时
  • 视网膜屏幕:重新定义数字显示的革命性技术
  • Go 语言 net/http 包使用:HTTP 服务器、客户端与中间件
  • 游戏引擎学习第278天:将实体存储移入世界区块
  • RabbitMq消息阻塞,立即解决方案
  • 使用Thrust库实现异步操作与回调函数
  • spark数据清洗
  • 代码随想录训练营第二十三天| 572.另一颗树的子树 104.二叉树的最大深度 559.N叉树的最大深度 111.二叉树的最小深度
  • 编程日志5.5
  • 第8章-9 优化技巧2
  • 2025年Flutter项目管理技能要求
  • 数据库系统概论(八)SQL单表查询语言超详细讲解(附带例题表格对比带你一步步掌握)
  • 智能体制作学习笔记1——智能体
  • 【前端】:单 HTML 去除 Word 批注
  • 实战案例:采集 51job 企业招聘信息
  • [特殊字符] VMware虚拟机挂起后Docker容器MySQL无法连接的解决方案