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

初始化相机类文件

c 复制代码
#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型命令,如 UserSetSave
	int CommandExecute(IN const char* strKey);

	
public:
	int nRet;
	void* m_hDevHandle; // 初始化设备句柄为空
};
c 复制代码
#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;

	// 初始化SDK
	nRet = 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;  // 优先尝试JPEG
	stSaveParam.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 image
	nRet = MV_CC_StopGrabbing(m_hDevHandle);
	if (MV_OK != nRet)
	{
		AfxMessageBox(_T("Stop Grabbing fail! \n"));
		
	}

	// ch:关闭设备 | Close device
	nRet = MV_CC_CloseDevice(m_hDevHandle);
	if (MV_OK != nRet)
	{
		AfxMessageBox(_T("ClosDevice fail\n"));
	
	}

	// ch:销毁句柄 | Destroy handle
	nRet = 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);
}

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

c 复制代码
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());
	}
}
相关推荐
2301_8035545222 分钟前
c++和c的不同
java·c语言·c++
Darkwanderor23 分钟前
c++STL-通用(反向)迭代器适配器
c++
Magnum Lehar42 分钟前
3d游戏引擎的Utilities模块实现
c++·算法·游戏引擎
青瓦梦滋1 小时前
【语法】C++的多态
开发语言·c++
Darkwanderor5 小时前
一般枚举题目合集
c++·算法
源远流长jerry5 小时前
右值引用和移动语义
c++
szxinmai主板定制专家5 小时前
RK3588 串行解串板,支持8路GMSL相机
数码相机
@我漫长的孤独流浪5 小时前
最短路与拓扑(2)
数据结构·c++·算法
半熟芝士味5 小时前
自动泊车技术—相机模型
数码相机