前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >海康SDK开发步骤

海康SDK开发步骤

作者头像
vv彭
发布2020-10-27 11:21:49
4.8K0
发布2020-10-27 11:21:49
举报
文章被收录于专栏:c#学习笔记

本文出处:https://cloud.tencent.com/developer/article/1730933

使用工业相机采集图像,首先需要对相机的相关参数进行设置。现在项目需要使用SDK进行二次开发。依照以下步骤进行:

1.枚举设备 -> 2.创建句柄 -> 3.打开设备 -> 4.开始抓图 -> 5.获取一帧并保存图像 -> 6.停止抓图 -> 7.关闭设备 -> 8.销毁句柄

第一次使用海康相机SDK,初步按照以下流程进行开发:

第一步: 了解C接口流程。

a.设备连接  b.图像采集显示

设备连接接口流程:

主动取流流程图

回调出流流程图

第二步:学习实例代码,查询C接口定义

  1. 枚举设备
代码语言:javascript
复制
1 int MV_CC_EnumDevices(unsigned int nTLayerType, \
              MV_CC_DEVICE_INFO_LIST *pstDevList);

参数:

nTLayerType in 传输层协议类型,按位表示,支持复选,可选协议类型如下:

pstDevList  out  查找到的设备信息列表

返回值:

成功,返回MV_OK (0);失败,返回错误码。

代码语言:javascript
复制
 1 #include "MvCameraControl.h"
 2 
 3 void main()
 4 {
 5     unsigned int nTLayerType = MV_GIGE_DEVICE | MV_USB_DEVICE;
 6 
 7     MV_CC_DEVICE_INFO_LIST m_stDevList = {0};
 8     int nRet = MV_CC_EnumDevices(nTLayerType, &m_stDevList);
 9     if (MV_OK != nRet)
10     {
11         printf("error: EnumDevices fail [%x]\n", nRet);
12     }
13 }
  1. 创建设备句柄
代码语言:javascript
复制
int MV_CC_CreateHandle(void **handle, const MV_CC_DEVIEC_INFO *pstDevInfo);

参数:

handle  out  设备句柄,输出参数;

pstDevInfo  in  设备信息版本、MAC地址、传输层类型以及其它设备信息;

返回值:

成功,返回MV_OK (0);失败,返回错误码。

代码语言:javascript
复制
 1 #include "MvCameraControl.h"
 2 
 3 void main()
 4 {
 5     int nRet = -1;
 6     void*  m_handle = NULL;
 7 
 8     //枚举子网内指定的传输协议对应的所有设备
 9      unsigned int nTLayerType = MV_GIGE_DEVICE | MV_USB_DEVICE;
10     MV_CC_DEVICE_INFO_LIST m_stDevList = {0};
11     int nRet = MV_CC_EnumDevices(nTLayerType, &m_stDevList);
12     if (MV_OK != nRet)
13     {
14         printf("error: EnumDevices fail [%x]\n", nRet);
15         return;
16     }
17 
18     int i = 0;
19     if (m_stDevList.nDeviceNum == 0)
20     {
21         printf("no camera found!\n");
22         return;
23     }
24 
25     //选择查找到的第一台在线设备,创建设备句柄
26      int nDeviceIndex = 0;
27 
28     MV_CC_DEVICE_INFO m_stDevInfo = {0};
29     memcpy(&m_stDevInfo, m_stDevList.pDeviceInfo[nDeviceIndex], sizeof(MV_CC_DEVICE_INFO));
30 
31     nRet = MV_CC_CreateHandle(&m_handle, &m_stDevInfo);
32 
33     if (MV_OK != nRet)
34     {
35         printf("error: CreateHandle fail [%x]\n", nRet);
36         return;
37     }
38 
39     //...其他处理
40  
41     //销毁句柄,释放资源
42      nRet = MV_CC_DestroyHandle(m_handle);
43     if (MV_OK != nRet)
44     {
45         printf("error: DestroyHandle fail [%x]\n", nRet);
46         return;
47     }
48 }
  1. 关闭设备
代码语言:javascript
复制
int MV_CC_CloseDevice(void *handle);

参数:

handle  in  设备句柄,MV_CC_CreateHandle或MV_CC_CreateHandleWithoutLog的out参数。

  1. 释放句柄
代码语言:javascript
复制
int MV_CC_DestroyHandle(void *handle);
  1. 注册图像数据回调函数,支持获取chunk信息
代码语言:javascript
复制
int MV_CC_RegisterImageCallBackEx(void *handle, const char *pEventName, \
                  cbEvent cbEvent, void *pUser);

参数:

pEventName  in  事件名;

fEventCallBack  in  接收Event事件的回调函数

pUser  in  用户自定义变量

回调函数

代码语言:javascript
复制
void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser);

回调函数参数:

pEventInfo  out  外部输出Event Info;

pUser  out  用户自定义变量;

注意:通过该接口设置事件回调,可以在回调函数里面获取采集、曝光等事件信息。

  1. 开始采集图像
代码语言:javascript
复制
int MV_CC_StartGrabbing(void *handle);
  1. 获取一帧图像数据
代码语言:javascript
复制
int MV_CC_GetOneFrame(void *handle, unsigned char *pData, \
            unsigned int nDataSize, \
           MV_FRAME_OUT_INFO *pFrameInfo
); 

参数:

pData  in  用于保存图像数据的缓存地址;

nDataSize  in  缓存区大小;

pFrameInfo  out  获取到的帧信息;

代码语言:javascript
复制
int MV_CC_GetOneFrameTimeout(void *handle, \
                                     unsigned char *pData, \
                                     unsigned int nDataSize, \
                      MV_FRAME_OUT_INFO_EX *pFrameInfo, \
                      int nMsec);

参数:

nMsec  in  等待超时时间,单位为毫秒;

注意:该接口对于U3V、GIGE相机均可支持。

代码语言:javascript
复制
#include "MvCameraControl.h"

void main()
{
    int nRet = -1;
    void* m_handle = NULL;

    //枚举子网内指定的传输协议对应的所有设备
     unsigned int nTLayerType = MV_GIGE_DEVICE | MV_USB_DEVICE;
    MV_CC_DEVICE_INFO_LIST m_stDevList = {0};
    int nRet = MV_CC_EnumDevices(nTLayerType, &m_stDevList);
    if (MV_OK != nRet)
    {
        printf("error: EnumDevices fail [%x]\n", nRet);
        return;
    }

    int i = 0;
    if (m_stDevList.nDeviceNum == 0)
    {
        printf("no camera found!\n");
        return;
    }

    //选择查找到的第一台在线设备,创建设备句柄
    int nDeviceIndex = 0;

    MV_CC_DEVICE_INFO m_stDevInfo = {0};
    memcpy(&m_stDevInfo, m_stDevList.pDeviceInfo[nDeviceIndex], sizeof(MV_CC_DEVICE_INFO));

    nRet = MV_CC_CreateHandle(&m_handle, &m_stDevInfo);

    if (MV_OK != nRet)
    {
        printf("error: CreateHandle fail [%x]\n", nRet);
        return;
    }

    //连接设备
     nRet = MV_CC_OpenDevice(m_handle, nAccessMode, nSwitchoverKey);
    if (MV_OK != nRet)
    {
        printf("error: OpenDevice fail [%x]\n", nRet);
        return;
    }
    //...其他处理 

    //开始采集图像
     nRet = MV_CC_StartGrabbing(m_handle);
    if (MV_OK != nRet)
    {
        printf("error: StartGrabbing fail [%x]\n", nRet);
        return;
    }

    //获取一帧数据的大小
    MVCC_INTVALUE stIntvalue = {0};
    nRet = MV_CC_GetIntValue(m_handle, "PayloadSize", &stIntvalue);
    if (nRet != MV_OK)
    {
        printf("Get PayloadSize failed! nRet [%x]\n", nRet);
        return;
    }
    int nBufSize = stIntvalue.nCurValue; //一帧数据大小

    unsigned int    nTestFrameSize = 0;
    unsigned char*  pFrameBuf = NULL;
    pFrameBuf = (unsigned char*)malloc(nBufSize);

    MV_FRAME_OUT_INFO_EX stInfo;
    memset(&stInfo, 0, sizeof(MV_FRAME_OUT_INFO_EX));

    //上层应用程序需要根据帧率,控制好调用该接口的频率
    //此次代码仅供参考,实际应用建议另建线程进行图像帧采集和处理
     while(1)
    {
        if (nTestFrameSize > 99) 
        {
            break;
        }
        nRet = MV_CC_GetOneFrameTimeout(m_handle, pFrameBuf, nBufSize, &stInfo, 1000);
        if (MV_OK != nRet)
        {
            Sleep(10);
        }
        else
        {
            //...图像数据处理
            nTestFrameSize++;
        }
    }

    //...其他处理

    //停止采集图像 
     nRet = MV_CC_StopGrabbing(m_handle);
    if (MV_OK != nRet)
    {
        printf("error: StopGrabbing fail [%x]\n", nRet);
        return;
    }

    //关闭设备,释放资源
     nRet = MV_CC_CloseDevice(m_handle);
    if (MV_OK != nRet)
    {
        printf("error: CloseDevice fail [%x]\n", nRet);
        return;
    }

    //销毁句柄,释放资源
     nRet = MV_CC_DestroyHandle(m_handle);
    if (MV_OK != nRet)
    {
        printf("error: DestroyHandle fail [%x]\n", nRet);
        return;
    }    
}
  1. 获取相机节点值
代码语言:javascript
复制
int MV_CC_GetIntValue(void *handle, const char *strKey, MVCC_INTVALUE *pIntValue);

参数:

strKey  in  节点名称;

pIntValue  out  获取到的节点值;

可以用来获取需要的节点值。

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

day1.20180716

问题记录:

  1. 测试相机采图时遇到问题:

首先,推测是图像数据格式错误

代码摘要:

代码语言:javascript
复制
 1 //像素格式转换输入输出参数            
 2 MV_CC_PIXEL_CONVERT_PARAM stParam;
 3 memset(&stParam, 0, sizeof(MV_CC_PIXEL_CONVERT_PARAM));
 4                               
 5 //源数据                 
 6 stParam.pSrcData       = m_pFrameBuf;              //原始图像数据
 7 stParam.nSrcDataLen    = stInfo.nFrameLen;         //原始图像数据长度
 8 stParam.enSrcPixelType = stInfo.enPixelType;       //原始图像数据的像素格式
 9 stParam.nWidth         = stInfo.nWidth;            //图像宽
10 stParam.nHeight        = stInfo.nHeight;           //图像高     
11 
12 //目标数据
13 stParam.enDstPixelType = PixelType_Gvsp_Mono8;     //需要保存的像素格式类型,转换成MONO8格式
14 stParam.nDstBufferSize;    //存储节点的大小
15 unsigned char* pImage  = (unsigned char*)malloc(stParam.nDstBufferSize);
16 stParam.pDstBuffer;     //输出数据缓冲区,存放转换之后的数据           
17 
18 nRet = MV_CC_ConvertPixelType(m_handle, &stParam);
19 if(MV_OK != nRet)
20 {
21   m_pImgBuf = (unsigned char *)malloc (stParam.nDstBufferSize);
22   memcpy(m_pImgBuf, stParam.pDstBuffer, stParam.nDstBufferSize);
23   break;
24 }
25 
26 free(pImage);
27 
28 
29 显示:
30 gen_image1(&g_img, "byte", g_uiWidth, g_uiHeight, pimgPointer);
31 open_window (0, 0, (Hlong)g_uiWidth, (Hlong)g_uiHeight, (Hlong)g_uiID, "visible", "", &g_window);
32 disp_image(g_img, g_window);

检查图像格式,为单色8位图像,没有错误。

检查halcon接口的创建图像,发现错误定义图像的尺寸大小。

所以,应该在打开相机后查询相机的ROI参数。改正后,单帧图像采集功能正常。

笔记:

  1. IP设置

强制设置相机网络参数,包括IP地址、子网掩码、默认网关。

代码语言:javascript
复制
int MV_GIGE_ForceIpEx(void *handle, unsigned int nIP, \
          unsigned int nSubNetMask, \
          unsigned int nDefaultGateWay);

强制设置之后需要重新创建设备句柄,仅支持GigEVision相机。

如果设备未DHCP的状态,调用该接口后设备将会重启~

代码语言:javascript
复制
int nRet = MV_CC_EnumDevices(nTLayerType, &m_stDevList);
...
nRet = MV_CC_CreateHandle(&m_handle, &m_stDevInfo);
...
// 设置设备网络属性
unsigned int nIP = ...    
// 这里。需要知道怎么把IP地址表示为unsigned int
...
nRet = MV_GIGE_ForceIpEx(m_handle, nIP, nSubNetMask, nDefaultGateWay);
...
// 重新创建设备句柄
nRet = MV_CC_CreateHandle(&m_handle, &m_stDevInfo);
  1. 设置配置IP的方式
代码语言:javascript
复制
int MV_GIGE_SetIpConfig(void *handle, unsigned int nType);

参数nType:IP配置方式,定义如下

  1. 相机的log文档
代码语言:javascript
复制
int MV_CC_SetSDKLogPath(IN const char *pSDKLogPath);

设置好路径后,可以在指定路径下存放sdk日志。

代码语言:javascript
复制
1 ...
2 string strPath = "D:/Hik/SDK";
3 nRet = MV_CC_SetSDKLogPath(strPath.c_str());

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

接下来,做连续采集。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档