海康SDK開發步驟


本文出處:https://www.cnblogs.com/xiawuhao2013/p/9295781.html

 

使用工業相機采集圖像,首先需要對相機的相關參數進行設置。現在項目需要使用SDK進行二次開發。依照以下步驟進行:

1.枚舉設備 -> 2.創建句柄 -> 3.打開設備 -> 4.開始抓圖 -> 5.獲取一幀並保存圖像 -> 6.停止抓圖 -> 7.關閉設備 -> 8.銷毀句柄

 第一次使用海康相機SDK,初步按照以下流程進行開發:

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

a.設備連接  b.圖像采集顯示

設備連接接口流程:

 

主動取流流程圖

回調出流流程圖

 

第二步:學習實例代碼,查詢C接口定義

 1. 枚舉設備

 

1 int MV_CC_EnumDevices(unsigned int nTLayerType, \
              MV_CC_DEVICE_INFO_LIST *pstDevList);

參數:
nTLayerType [in] 傳輸層協議類型,按位表示,支持復選,可選協議類型如下:

pstDevList  [out]  查找到的設備信息列表

返回值:

成功,返回MV_OK (0);失敗,返回錯誤碼。

復制代碼
 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 }
復制代碼

2. 創建設備句柄

int MV_CC_CreateHandle(void **handle, const MV_CC_DEVIEC_INFO *pstDevInfo);

參數:

handle  [out]  設備句柄,輸出參數;

pstDevInfo  [in]  設備信息版本、MAC地址、傳輸層類型以及其它設備信息;

返回值:

成功,返回MV_OK (0);失敗,返回錯誤碼。

復制代碼
 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 }
復制代碼

3. 關閉設備

int MV_CC_CloseDevice(void *handle);

參數:

handle  [in]  設備句柄,MV_CC_CreateHandle或MV_CC_CreateHandleWithoutLog的[out]參數。

4. 釋放句柄

int MV_CC_DestroyHandle(void *handle);

 5. 注冊圖像數據回調函數,支持獲取chunk信息

int MV_CC_RegisterImageCallBackEx(void *handle, const char *pEventName, \
                  cbEvent cbEvent, void *pUser);

參數:

pEventName  [in]  事件名;

fEventCallBack  [in]  接收Event事件的回調函數

pUser  [in]  用戶自定義變量

回調函數

void(__stdcall *cbEvent)(MV_EVENT_OUT_INFO *pEventInfo, void *pUser);

回調函數參數:

pEventInfo  [out]  外部輸出Event Info;

pUser  [out]  用戶自定義變量;

注意:通過該接口設置事件回調,可以在回調函數里面獲取采集、曝光等事件信息。

6. 開始采集圖像

int MV_CC_StartGrabbing(void *handle);

7. 獲取一幀圖像數據

int MV_CC_GetOneFrame(void *handle, unsigned char *pData, \
            unsigned int nDataSize, \
           MV_FRAME_OUT_INFO *pFrameInfo
);

參數:

pData  [in]  用於保存圖像數據的緩存地址;

nDataSize  [in]  緩存區大小;

pFrameInfo  [out]  獲取到的幀信息;

int MV_CC_GetOneFrameTimeout(void *handle, \
                                     unsigned char *pData, \
                                     unsigned int nDataSize, \
                      MV_FRAME_OUT_INFO_EX *pFrameInfo, \
                      int nMsec);

參數:

nMsec  [in]  等待超時時間,單位為毫秒;

注意:該接口對於U3V、GIGE相機均可支持。

復制代碼
#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;
    }    
}
復制代碼

8. 獲取相機節點值

int MV_CC_GetIntValue(void *handle, const char *strKey, MVCC_INTVALUE *pIntValue);

參數:

strKey  [in]  節點名稱;

pIntValue  [out]  獲取到的節點值;

可以用來獲取需要的節點值。

 

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

day1.20180716

問題記錄:

1. 測試相機采圖時遇到問題:

首先,推測是圖像數據格式錯誤

 代碼摘要:

復制代碼
 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地址、子網掩碼、默認網關。

int MV_GIGE_ForceIpEx(void *handle, unsigned int nIP, \
          unsigned int nSubNetMask, \
          unsigned int nDefaultGateWay);

強制設置之后需要重新創建設備句柄,僅支持GigEVision相機。

如果設備未DHCP的狀態,調用該接口后設備將會重啟~

復制代碼
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);
復制代碼

2. 設置配置IP的方式

int MV_GIGE_SetIpConfig(void *handle, unsigned int nType);

參數nType:IP配置方式,定義如下

3. 相機的log文檔

int MV_CC_SetSDKLogPath(IN const char *pSDKLogPath);

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

1 ...
2 string strPath = "D:/Hik/SDK";
3 nRet = MV_CC_SetSDKLogPath(strPath.c_str());

 

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

接下來,做連續采集。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM