目录
1、海康Demo代码
2、示例代码说明
1. 概述
2. 功能模块说明
2.1 设备枚举与选择
2.2 设备连接与配置
2.3 图像采集策略
2.4 图像采集与处理
2.5 资源释放
3. 代码流程分析
4. 注意事项
5. 示例代码运行环境
6. 示例代码输出示例
7. 示例代码的扩展方向
8. 结论
1、海康Demo代码
#include <stdio.h>
#include <Windows.h>
#include <process.h>
#include <conio.h>
#include "MvCameraControl.h"
// ch:等待按键输入 | en:Wait for key press
void WaitForKeyPress(void)
{
while(!_kbhit())
{
Sleep(10);
}
_getch();
}
bool PrintDeviceInfo(MV_CC_DEVICE_INFO* pstMVDevInfo)
{
if (NULL == pstMVDevInfo)
{
printf("The Pointer of pstMVDevInfo is NULL!
");
return false;
}
if (pstMVDevInfo->nTLayerType == MV_GIGE_DEVICE)
{
int nIp1 = ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0xff000000) >> 24);
int nIp2 = ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x00ff0000) >> 16);
int nIp3 = ((pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x0000ff00) >> 8);
int nIp4 = (pstMVDevInfo->SpecialInfo.stGigEInfo.nCurrentIp & 0x000000ff);
printf("CurrentIp: %d.%d.%d.%d
" , nIp1, nIp2, nIp3, nIp4);
printf("UserDefinedName: %s
" , pstMVDevInfo->SpecialInfo.stGigEInfo.chUserDefinedName);
}
else if (pstMVDevInfo->nTLayerType == MV_USB_DEVICE)
{
printf("UserDefinedName: %s
", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chUserDefinedName);
printf("Serial Number: %s
", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);
printf("Device Number: %d
", pstMVDevInfo->SpecialInfo.stUsb3VInfo.nDeviceNumber);
}
else if (pstMVDevInfo->nTLayerType == MV_GENTL_GIGE_DEVICE)
{
printf("UserDefinedName: %s
", pstMVDevInfo->SpecialInfo.stGigEInfo.chUserDefinedName);
printf("Serial Number: %s
", pstMVDevInfo->SpecialInfo.stGigEInfo.chSerialNumber);
printf("Model Name: %s
", pstMVDevInfo->SpecialInfo.stGigEInfo.chModelName);
}
else if (pstMVDevInfo->nTLayerType == MV_GENTL_CAMERALINK_DEVICE)
{
printf("UserDefinedName: %s
", pstMVDevInfo->SpecialInfo.stCMLInfo.chUserDefinedName);
printf("Serial Number: %s
", pstMVDevInfo->SpecialInfo.stCMLInfo.chSerialNumber);
printf("Model Name: %s
", pstMVDevInfo->SpecialInfo.stCMLInfo.chModelName);
}
else if (pstMVDevInfo->nTLayerType == MV_GENTL_CXP_DEVICE)
{
printf("UserDefinedName: %s
", pstMVDevInfo->SpecialInfo.stCXPInfo.chUserDefinedName);
printf("Serial Number: %s
", pstMVDevInfo->SpecialInfo.stCXPInfo.chSerialNumber);
printf("Model Name: %s
", pstMVDevInfo->SpecialInfo.stCXPInfo.chModelName);
}
else if (pstMVDevInfo->nTLayerType == MV_GENTL_XOF_DEVICE)
{
printf("UserDefinedName: %s
", pstMVDevInfo->SpecialInfo.stXoFInfo.chUserDefinedName);
printf("Serial Number: %s
", pstMVDevInfo->SpecialInfo.stXoFInfo.chSerialNumber);
printf("Model Name: %s
", pstMVDevInfo->SpecialInfo.stXoFInfo.chModelName);
}
else
{
printf("Not support.
");
}
return true;
}
static unsigned int __stdcall UpcomingThread(void* pUser)
{
Sleep(3000);//为了等MV_CC_GetImageBuffer调用后再发送软触发命令
printf("Trigger Software Once for MV_GrabStrategy_UpcomingImage
");
MV_CC_SetCommandValue(pUser, "TriggerSoftware");
return 0;
}
int main()
{
int nRet = MV_OK;
void* handle = NULL;
unsigned char * pData = NULL;
do
{
// ch:初始化SDK | en:Initialize SDK
nRet = MV_CC_Initialize();
if (MV_OK != nRet)
{
printf("Initialize SDK fail! nRet [0x%x]
", nRet);
break;
}
// ch:枚举设备 | en:Enum device
MV_CC_DEVICE_INFO_LIST stDeviceList = {0};
nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE | MV_GENTL_CAMERALINK_DEVICE | MV_GENTL_CXP_DEVICE | MV_GENTL_XOF_DEVICE, &stDeviceList);
if (MV_OK != nRet)
{
printf("Enum Devices fail! nRet [0x%x]
", nRet);
break;
}
if (stDeviceList.nDeviceNum > 0)
{
for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
{
printf("[device %d]:
", i);
MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];
if (NULL == pDeviceInfo)
{
break;
}
PrintDeviceInfo(pDeviceInfo);
}
}
else
{
printf("Find No Devices!
");
break;
}
printf("Please Input camera index(0-%d):", stDeviceList.nDeviceNum-1);
unsigned int nIndex = 0;
scanf_s("%d", &nIndex);
if (nIndex >= stDeviceList.nDeviceNum)
{
printf("Input error!
");
break;
}
// ch:选择设备并创建句柄 | en:Select device and create handle
nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);
if (MV_OK != nRet)
{
printf("Create Handle fail! nRet [0x%x]
", nRet);
break;
}
// ch:打开设备 | en:Open device
nRet = MV_CC_OpenDevice(handle);
if (MV_OK != nRet)
{
printf("Open Device fail! nRet [0x%x]
", nRet);
break;
}
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
if (stDeviceList.pDeviceInfo[nIndex]->nTLayerType == MV_GIGE_DEVICE)
{
int nPacketSize = MV_CC_GetOptimalPacketSize(handle);
if (nPacketSize > 0)
{
if(MV_CC_SetIntValueEx(handle,"GevSCPSPacketSize",nPacketSize) != MV_OK)
{
printf("Warning: Set Packet Size fail nRet [0x%x]!", nRet);
}
}
else
{
printf("Warning: Get Packet Size fail nRet [0x%x]!", nPacketSize);
}
}
// ch:设置软触发模式 | en:Set Trigger Mode and Set Trigger Source
nRet = MV_CC_SetEnumValueByString(handle, "TriggerMode", "On");
if (MV_OK != nRet)
{
printf("Set Trigger Mode fail! nRet [0x%x]
", nRet);
break;
}
nRet = MV_CC_SetEnumValueByString(handle, "TriggerSource", "Software");
if (MV_OK != nRet)
{
printf("Set Trigger Source fail! nRet [0x%x]
", nRet);
break;
}
unsigned int nImageNodeNum = 5;
// ch:设置缓存节点个数 | en:Set number of image node
nRet = MV_CC_SetImageNodeNum(handle, nImageNodeNum);
if (MV_OK != nRet)
{
printf("Set number of image node fail! nRet [0x%x]
", nRet);
break;
}
printf("
**************************************************************************
");
printf("* 0.MV_GrabStrategy_OneByOne; 1.MV_GrabStrategy_LatestImagesOnly; *
");
printf("* 2.MV_GrabStrategy_LatestImages; 3.MV_GrabStrategy_UpcomingImage; *
");
printf("**************************************************************************
");
printf("Please Input Grab Strategy:");
unsigned int nGrabStrategy = 0;
scanf_s("%d", &nGrabStrategy);
// ch:U3V相机不支持MV_GrabStrategy_UpcomingImage | en:U3V device not support UpcomingImage
if (nGrabStrategy == MV_GrabStrategy_UpcomingImage && MV_USB_DEVICE == stDeviceList.pDeviceInfo[nIndex]->nTLayerType)
{
printf("U3V device not support UpcomingImage
");
break;
}
switch(nGrabStrategy)
{
case MV_GrabStrategy_OneByOne:
{
printf("Grab using the MV_GrabStrategy_OneByOne default strategy
");
nRet = MV_CC_SetGrabStrategy(handle, MV_GrabStrategy_OneByOne);
if (MV_OK != nRet)
{
printf("Set Grab Strategy fail! nRet [0x%x]
", nRet);
break;
}
}
break;
case MV_GrabStrategy_LatestImagesOnly:
{
printf("Grab using strategy MV_GrabStrategy_LatestImagesOnly
");
nRet = MV_CC_SetGrabStrategy(handle, MV_GrabStrategy_LatestImagesOnly);
if (MV_OK != nRet)
{
printf("Set Grab Strategy fail! nRet [0x%x]
", nRet);
break;
}
}
break;
case MV_GrabStrategy_LatestImages:
{
printf("Grab using strategy MV_GrabStrategy_LatestImages
");
nRet = MV_CC_SetGrabStrategy(handle, MV_GrabStrategy_LatestImages);
if (MV_OK != nRet)
{
printf("Set Grab Strategy fail! nRet [0x%x]
", nRet);
break;
}
// ch:设置输出缓存个数 | en:Set Output Queue Size
nRet = MV_CC_SetOutputQueueSize(handle, 2);
if (MV_OK != nRet)
{
printf("Set Output Queue Size fail! nRet [0x%x]
", nRet);
break;
}
}
break;
case MV_GrabStrategy_UpcomingImage:
{
printf("Grab using strategy MV_GrabStrategy_UpcomingImage
");
nRet = MV_CC_SetGrabStrategy(handle, MV_GrabStrategy_UpcomingImage);
if (MV_OK != nRet)
{
printf("Set Grab Strategy fail! nRet [0x%x]
", nRet);
break;
}
unsigned int nThreadID = 0;
void* hThreadHandle = (void*) _beginthreadex( NULL , 0 , UpcomingThread , handle, 0 , &nThreadID );
if (NULL == hThreadHandle)
{
break;
}
}
break;
default:
printf("Input error!Use default strategy:MV_GrabStrategy_OneByOne
");
break;
}
// ch:开始取流 | en:Start grab image
nRet = MV_CC_StartGrabbing(handle);
if (MV_OK != nRet)
{
printf("Start Grabbing fail! nRet [0x%x]
", nRet);
break;
}
// ch:发送软触发命令 | en:Send Trigger Software command
for (unsigned int i = 0;i < nImageNodeNum;i++)
{
nRet = MV_CC_SetCommandValue(handle, "TriggerSoftware");
if (MV_OK != nRet)
{
printf("Send Trigger Software command fail! nRet [0x%x]
", nRet);
break;
}
Sleep(500);//如果帧率过小或TriggerDelay很大,可能会出现软触发命令没有全部起效而导致取不到数据的情况
}
MV_FRAME_OUT stOutFrame = {0};
if (nGrabStrategy != MV_GrabStrategy_UpcomingImage)
{
while(true)
{
nRet = MV_CC_GetImageBuffer(handle, &stOutFrame, 0);//超时时间设置成0,因为缓存列表中已经有数据存在
if (nRet == MV_OK)
{
printf("Get One Frame: Width[%d], Height[%d], FrameNum[%d]
",
stOutFrame.stFrameInfo.nExtendWidth, stOutFrame.stFrameInfo.nExtendHeight, stOutFrame.stFrameInfo.nFrameNum);
}
else
{
printf("Get Image fail! nRet [0x%x]
", nRet);
break;
}
nRet = MV_CC_FreeImageBuffer(handle, &stOutFrame);
if(nRet != MV_OK)
{
printf("Free Image Buffer fail! nRet [0x%x]
", nRet);
}
}
}
else//仅用于upcoming
{
nRet = MV_CC_GetImageBuffer(handle, &stOutFrame, 5000);//需要比较大的超时时间来获取即将到达的这帧数据
if (nRet == MV_OK)
{
printf("Get One Frame: Width[%d], Height[%d], FrameNum[%d]
",
stOutFrame.stFrameInfo.nExtendWidth, stOutFrame.stFrameInfo.nExtendHeight, stOutFrame.stFrameInfo.nFrameNum);
nRet = MV_CC_FreeImageBuffer(handle, &stOutFrame);
if(nRet != MV_OK)
{
printf("Free Image Buffer fail! nRet [0x%x]
", nRet);
}
}
else
{
printf("Get Image fail! nRet [0x%x]
", nRet);
}
}
// ch:停止取流 | en:Stop grab image
nRet = MV_CC_StopGrabbing(handle);
if (MV_OK != nRet)
{
printf("Stop Grabbing fail! nRet [0x%x]
", nRet);
break;
}
// ch:关闭设备 | en:Close device
nRet = MV_CC_CloseDevice(handle);
if (MV_OK != nRet)
{
printf("Close Device fail! nRet [0x%x]
", nRet);
break;
}
// ch:销毁句柄 | en:Destroy handle
nRet = MV_CC_DestroyHandle(handle);
if (MV_OK != nRet)
{
printf("Destroy Handle fail! nRet [0x%x]
", nRet);
break;
}
handle = NULL;
} while (0);
if (handle != NULL)
{
MV_CC_DestroyHandle(handle);
handle = NULL;
}
// ch:反初始化SDK | en:Finalize SDK
MV_CC_Finalize();
printf("Press a key to exit.
");
WaitForKeyPress();
return 0;
}
2、示例代码说明
1. 概述
本示例代码演示了如何使用海康相机SDK(MvCameraControl.h)进行设备枚举、连接、配置、图像采集和释放资源的完整流程。代码支持多种相机类型(如GigE、USB、CameraLink等),并展示了不同的图像采集策略(如逐帧采集、获取最新图像、获取即将到达的图像等)。通过本示例,用户可以快速了解如何与海康相机进行交互,并实现基本的图像采集功能。
2. 功能模块说明
2.1 设备枚举与选择
枚举设备:通过MV_CC_EnumDevices函数枚举所有连接的海康相机设备。支持的设备类型包括GigE、USB、CameraLink、CXP和XOF等。
打印设备信息:调用PrintDeviceInfo函数,根据设备类型(如GigE、USB等)打印设备的详细信息,如IP地址、用户定义名称、序列号等。
选择设备:用户通过输入设备索引(0到设备总数减1)选择要连接的相机设备。
2.2 设备连接与配置
创建设备句柄:使用MV_CC_CreateHandle函数根据用户选择的设备信息创建设备句柄。
打开设备:通过MV_CC_OpenDevice函数打开相机设备。
设置网络参数(仅限GigE相机):调用MV_CC_GetOptimalPacketSize获取最佳网络包大小,并通过MV_CC_SetIntValueEx设置GigE相机的包大小。
配置触发模式:
设置触发模式为“On”(MV_CC_SetEnumValueByString(handle, "TriggerMode", "On"))。
设置触发源为“Software”(MV_CC_SetEnumValueByString(handle, "TriggerSource", "Software"))。
设置图像缓存节点个数:通过MV_CC_SetImageNodeNum设置图像缓存节点的数量。
2.3 图像采集策略
用户可以选择以下四种图像采集策略之一:
MV_GrabStrategy_OneByOne:逐帧采集图像。
MV_GrabStrategy_LatestImagesOnly:仅获取最新图像。
MV_GrabStrategy_LatestImages:获取最新多帧图像。
MV_GrabStrategy_UpcomingImage:获取即将到达的图像(仅支持GigE相机)。
2.4 图像采集与处理
开始采集:调用MV_CC_StartGrabbing函数开始图像采集。
发送软触发命令:通过MV_CC_SetCommandValue(handle, "TriggerSoftware")发送软触发命令,触发相机采集图像。
获取图像数据:
对于非“即将到达的图像”策略,调用MV_CC_GetImageBuffer函数从缓存中获取图像数据。
对于“即将到达的图像”策略,设置较大的超时时间(如5000毫秒),等待即将到达的图像数据。
释放图像缓存:通过MV_CC_FreeImageBuffer函数释放获取的图像缓存。
2.5 资源释放
停止采集:调用MV_CC_StopGrabbing函数停止图像采集。
关闭设备:通过MV_CC_CloseDevice函数关闭相机设备。
销毁句柄:调用MV_CC_DestroyHandle函数销毁设备句柄。
反初始化SDK:调用MV_CC_Finalize函数完成SDK的反初始化操作。
3. 代码流程分析
初始化SDK:调用MV_CC_Initialize函数初始化SDK。
枚举设备:调用MV_CC_EnumDevices函数枚举所有连接的相机设备,并打印设备信息。
选择设备:用户输入设备索引,选择要连接的相机设备。
设备连接与配置:创建设备句柄、打开设备、设置网络参数(仅限GigE相机)、配置触发模式和图像缓存节点个数。
设置图像采集策略:用户选择图像采集策略。
图像采集:开始采集图像、发送软触发命令、获取图像数据、释放图像缓存。
资源释放:停止采集、关闭设备、销毁句柄、反初始化SDK。
等待按键退出:调用WaitForKeyPress函数等待用户按键后退出程序。
4. 注意事项
设备支持性:
U3V(USB3 Vision)设备不支持“即将到达的图像”策略(MV_GrabStrategy_UpcomingImage)。
不同类型的相机(如GigE、USB等)可能需要不同的配置参数。
图像采集超时时间:
对于“即将到达的图像”策略,需要设置较大的超时时间(如5000毫秒),以确保能够成功获取即将到达的图像。
对于其他策略,超时时间可以设置为0,因为缓存中已经有图像数据。
软触发命令间隔:
如果相机帧率较低或TriggerDelay较大,软触发命令之间需要有足够的间隔时间(如500毫秒),以确保触发命令能够正确生效。
资源释放顺序:
在程序结束前,必须按照正确的顺序释放资源(如停止采集、关闭设备、销毁句柄、反初始化SDK),以避免资源泄漏或程序崩溃。
5. 示例代码运行环境
硬件环境:
海康相机(支持GigE、USB、CameraLink、CXP或XOF接口)。
与相机匹配的计算机硬件(如网卡、USB接口等)。
软件环境:
操作系统:Windows(支持Windows XP及以上版本)。
编译工具:Visual Studio(支持2010及以上版本)。
海康相机SDK:确保已正确安装并配置海康相机SDK,包括头文件(MvCameraControl.h)和动态链接库(DLL)。
6. 示例代码输出示例
假设连接了一台GigE相机,运行程序后可能的输出如下:
[device 0]:
CurrentIp: 192.168.1.100
UserDefinedName: Camera1
Please Input camera index(0-0):0
Please Input Grab Strategy:
0.MV_GrabStrategy_OneByOne; 1.MV_GrabStrategy_LatestImagesOnly;
2.MV_GrabStrategy_LatestImages; 3.MV_GrabStrategy_UpcomingImage;
**************************************************************************
Please Input Grab Strategy:0
Grab using the MV_GrabStrategy_OneByOne default strategy
Get One Frame: Width[1920], Height[1080], FrameNum[1]
Get One Frame: Width[1920], Height[1080], FrameNum[2]
...
Press a key to exit.
7. 示例代码的扩展方向
图像处理功能:在获取图像数据后,可以添加图像处理算法(如边缘检测、特征提取等)。
多线程采集:实现多线程图像采集,提高采集效率。
网络传输:将采集的图像通过网络传输到其他设备进行处理或存储。
用户界面:开发图形用户界面(GUI),方便用户操作和配置相机参数。
8. 结论
本示例代码展示了如何使用海康相机SDK进行设备枚举、连接、配置、图像采集和资源释放的完整流程。通过学习本示例代码,用户可以快速掌握海康相机SDK的基本使用方法,并根据实际需求进行扩展和应用。
![[海康Demo] GrabStrategies - 宋马](https://bbs.songma.com/wp-content/uploads/2024/12/800.png)

















暂无评论内容