본문 바로가기

개발/Computer Vision

Hikvision 산업용 카메라 OpenCV C++로 사용해보기 - 2 -

Hikvision 산업용 카메라 OpenCV C++로 사용해보기 - 1 -

 


3. 프로젝트 환경 설정

전 포스팅에서 MVS를 설치하고 카메라 제어 흐름을 이해했다.

그렇다면 Visual Studio를 실행한 후 개발 셋팅에 들어가자.

Visual Studio C++ 프로젝트를 생성한 후 프로젝트 설정에 들어가서 환경 설정을 해야 한다.

(OpenCV는 라이브러리 버전에 맞게 셋팅하면 된다.)

 

C/C++ - 일반 - 추가 포함 디렉터리

먼저 프로젝트 설정에 들어가서 MVS 라이브러리 경로를 추가해주자.

C/C++ - 일반 - 추가 포함 디렉터리

C:\Program Files (x86)\MVS\Development\Includes 

 

 

링커 - 일반 - 추가 라이브러리 디렉터리

링커 - 일반 - 추가 라이브러리 디렉터리

C:\Program Files (x86)\MVS\Development\Libraries\win64

 

 

링커 - 입력 - 추가 종속성

링커 - 입력 - 추가 종속성

MvCameraControl.lib


4. Visual Studio C++을 사용하여 직접 카메라 제어하기

개발 셋팅은 끝났으니 본격적으로 C++을 사용해서 카메라를 제어해보자.

 

1) 카메라 핸들 생성 (MV_CC_CreateHandle), 카메라 연결 (MV_CC_OpenDevice)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void* CreateCamera(string cameraname)
{
    int        nRet    = MV_OK;                    // status 
    void*    handle    = NULL;                        // camera handle
 
    // Enum device
    MV_CC_DEVICE_INFO_LIST stDeviceList;                            // device list
    memset(&stDeviceList, 0sizeof(MV_CC_DEVICE_INFO_LIST));        // initialize
    
    nRet = MV_CC_EnumDevices(MV_USB_DEVICE, &stDeviceList);            // get device list
    if (MV_OK != nRet)
        printf("Enum Devices fail! nRet [0x%x]\n", nRet);
 
    if (stDeviceList.nDeviceNum > 0)            // exists connected device 
    {                    
        for (int i = 0; i < stDeviceList.nDeviceNum; i++) {
            // get camera model name
            String modelname((char*)stDeviceList.pDeviceInfo[i]->SpecialInfo.stUsb3VInfo.chModelName);        
            
            // compare and create handle
            if (modelname == cameraname) {
                nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[i]);
                break;
            }
        }
 
        // open device
        nRet = MV_CC_OpenDevice(handle);            
        if (MV_OK != nRet)
            printf("Open Device fail! nRet [0x%x]\n", nRet);
 
        return handle;
    }else
        return NULL;
}
cs

연결된 카메라 검색, 카메라 핸들 생성, 카메라 오픈까지 한 번에 처리 하는 함수.

물론 이렇게 기능을 묶지 않아도 되지만 대개 같이 쓰이기 때문에 추후 개발할 때 편하다.

 

 

2) 촬영 시작 (MV_CC_StartGrabbing)

1
2
3
4
5
6
7
8
9
10
11
void GrabCamera(void* handle)
{
    int nRet = MV_OK;
 
    // Start grab image
    nRet = MV_CC_StartGrabbing(handle);
    if (MV_OK != nRet)
    {
        printf("Start Grabbing fail! nRet [0x%x]\n", nRet);
    }
}
 

이 부분은 간단하다.

앞에서 생성해준 카메라 핸들값을 함수에 전달해주면 카메라는 촬영을 시작하게 된다.

 

 

3) 프레임 데이터 획득 (MV_CC_GetOneFrameTimeout)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// cache size 
unsigned int        g_nPayloadSize = 1440 * 1080;           
 
// cache address of picture data
unsigned char*        pData = (unsigned char *)malloc(sizeof(unsigned char* (g_nPayloadSize));        
 
// convert data stream in Mat format
Mat Convert2Mat(MV_FRAME_OUT_INFO_EX* pstImageInfo, unsigned char* pData)
{
    Mat srcImage;
 
    srcImage = Mat(pstImageInfo->nHeight, pstImageInfo->nWidth, CV_8U, pData);
    cvtColor(srcImage, srcImage, COLOR_BayerRG2RGB);
 
    return srcImage;
}
 
Mat GetMatFrame(void* handle)
{
    MV_FRAME_OUT_INFO_EX stImageInfo = { 0 };
    memset(&stImageInfo, 0sizeof(MV_FRAME_OUT_INFO_EX));
 
    Mat image;
 
    MV_CC_GetOneFrameTimeout(handle, pData, g_nPayloadSize, &stImageInfo, 1000);
    image = Convert2Mat(&stImageInfo, pData);
 
    return image;
}

데이터 획득 과정도 그리 어렵지 않다. 

유의할 점은 MV_GetOneFrameTimeout 함수를 쓸 때 pData와 g_nPayloadSize 변수는 한 번 초기화를 해주어야 한다.

아무래도 카메라 데이터는 이미지이기 때문에 일반적인 데이터보다 사이즈가 매우 크다.

그렇기 때문에 프로그래밍을 할 때 이미지 데이터를 처리할 변수는 초기화나 메모리 관리를 제대로 해주어야 한다.

Convert2Mat 함수는 OpenCV를 사용해본 사람이면 바로 이해가 가능할 것이다.

pData에 저장된 이미지 데이터를 Mat 타입으로 변환해주는 함수다.

cvtColor 함수는 카메라 픽셀 설정에 따라 다르게 해주어야 한다.

카메라 타입 설정이 RGB나 BayerRG, 또는 그 외의 타입인지 확인하자.

 

 

4) 카메라 중지 (MV_CC_StopGrabbing)

1
2
3
4
5
6
7
8
9
10
11
void StopCamera(void* handle)
{
    int nRet = MV_OK;
 
    // Stop grab image
    nRet = MV_CC_StopGrabbing(handle);
    if (MV_OK != nRet)
    {
        printf("Stop Grabbing fail! nRet [0x%x]\n", nRet);
    }
}

카메라 Grab을 중지한다.

이 함수 사용 이후로는 카메라 데이터를 획득할 수 없다.

 

 

5) 카메라 연결 해제 (MV_CC_CloseDevice), 리소스 해제 (MV_CC_DestroyHandle)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void CloseCamera(void* handle)
{
    int nRet = MV_OK;
 
    // Close device
    nRet = MV_CC_CloseDevice(handle);
    if (MV_OK != nRet)
    {
        printf("ClosDevice fail! nRet [0x%x]\n", nRet);
    }
 
    // Destroy handle
    nRet = MV_CC_DestroyHandle(handle);
    if (MV_OK != nRet)
    {
        printf("Destroy Handle fail! nRet [0x%x]\n", nRet);
    }
}

카메라 연결을 해제하고 관련 리소스를 제거한다. 

완벽하게 카메라와의 모든 연결이 끊어지게 된다.