海康工业相机SDK+OpenCV实例(2):RawDataFormatConvert详解

海康工业相机SDK+OpenCV实例(2):

RawDataFormatConvert详解


文章目录

  • 海康工业相机SDK+OpenCV实例(2):
  • RawDataFormatConvert详解
  • 前言
  • 一、海康工业相机SDK详解
  • 二、OpenCV相关操作
  • 三、运行结果


前言

在前文讲解了海康工业相机SDK与OpenCV的安装与环境配置,本文接着讲解SDK给的OpenCV的demo,主要实现RawDataFormatConvert的功能,即将海康连续采集的图像转化为OpenCV的Mat格式并显示于屏幕。


一、海康工业相机SDK详解

在海康SDK安装位置,找到D:\Softwares\MVS\Development\Samples\OpenCV\VC的Samples_OpenCV.sln并打开,下面会先对SDK的调用相机的各功能进行详解:

1.1 首先定义句柄和相机操作的返回值,当相机操作出现问题时,需要将nRet,可以根据对应的返回值查询可能出现的问题。

    int nRet = MV_OK;
    void* handle = NULL;

1.2 列出当前的设备管理目录,输入对应值,选择相应的相机设备。

        // Enum device
        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)
        {
            printf("Enum Devices fail! nRet [0x%x]\n", nRet);
            break;
        }

        if (stDeviceList.nDeviceNum > 0)
        {
            for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
            {
                printf("[device %d]:\n", i);
                MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];
                if (NULL == pDeviceInfo)
                {
                    break;
                }
                PrintDeviceInfo(pDeviceInfo);
            }
        }
        else
        {
            printf("Find No Devices!\n");
            break;
        }

        // input the format to convert
        unsigned int nFormat = 0;
 
        // select device to connect
        printf("Please Input camera index(0-%d):", stDeviceList.nDeviceNum-1);
        unsigned int nIndex = 0;
        scanf("%d", &nIndex);
        if (nIndex >= stDeviceList.nDeviceNum)
        {
            printf("Input error!\n");
            break;
        }

1.3 创建句柄并打开相机设备

        // Select device and create handle
        nRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);
        if (MV_OK != nRet)
        {
            printf("Create Handle fail! nRet [0x%x]\n", nRet);
            break;
        }

        // open device
        nRet = MV_CC_OpenDevice(handle);
        if (MV_OK != nRet)
        {
            printf("Open Device fail! nRet [0x%x]\n", nRet);
            break;
        }

1.4 设置相机参数,图片的宽度与高度、相机的曝光时间与增益;返回相机参数,图片的宽度与高度、相机的曝光时间与增益。

        nRet = SetParameters(handle, WidthValue, HeightValue, ExposureTimeValue, GainValue);
        if (MV_OK != nRet)
        {
            printf("Set parameters fail! nRet [0x%x]\n", nRet);
            break;
        }

        nRet = GetParameters(handle);
        if (MV_OK != nRet)
        {
            printf("Get parameters fail! nRet [0x%x]\n", nRet);
            break;
        }

1.5 设置网络最佳的包大小,设置相机的触发模式

        // 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)
            {
                nRet = MV_CC_SetIntValue(handle,"GevSCPSPacketSize",nPacketSize);
                if(nRet != MV_OK)
                {
                    printf("Warning: Set Packet Size fail nRet [0x%x]!", nRet);
                }
            }
            else
            {
                printf("Warning: Get Packet Size fail nRet [0x%x]!", nPacketSize);
            }
        }

        // Set trigger mode as off
        nRet = MV_CC_SetEnumValue(handle, "TriggerMode", 0);
        if (MV_OK != nRet)
        {
            printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
            break;
        }

        // Get payload size
        MVCC_INTVALUE stParam;
        memset(&stParam, 0, sizeof(MVCC_INTVALUE));
        nRet = MV_CC_GetIntValue(handle, "PayloadSize", &stParam);
        if (MV_OK != nRet)
        {
            printf("Get PayloadSize fail! nRet [0x%x]\n", nRet);
            break;
        }
        g_nPayloadSize = stParam.nCurValue;

1.6 开启连续采集模式,并分配缓冲内存区

        // Start grab image
        nRet = MV_CC_StartGrabbing(handle);
        if (MV_OK != nRet)
        {
            printf("Start Grabbing fail! nRet [0x%x]\n", nRet);
            break;
        }

        MV_FRAME_OUT stImageInfo = {0};
        memset(&stImageInfo, 0, sizeof(MV_FRAME_OUT));
        unsigned char * pData = (unsigned char *)malloc(sizeof(unsigned char) * (g_nPayloadSize));
        if (pData == NULL)
        {
            printf("Allocate memory failed.\n");
            break;
        }

1.7 停止采集

        // Stop grab image
        nRet = MV_CC_StopGrabbing(handle);
        if (MV_OK != nRet)
        {
            printf("Stop Grabbing fail! nRet [0x%x]\n", nRet);
            break;
        }

1.8 关闭相机并摧毁句柄

        // Close device
        nRet = MV_CC_CloseDevice(handle);
        if (MV_OK != nRet)
        {
            printf("ClosDevice fail! nRet [0x%x]\n", nRet);
            break;
        }

        // Destroy handle
        nRet = MV_CC_DestroyHandle(handle);
        if (MV_OK != nRet)
        {
            printf("Destroy Handle fail! nRet [0x%x]\n", nRet);
            break;
        }

二、OpenCV相关操作

在RawDataFormatConvert中,最主要的功能是将连续采集的图片,从相机的缓冲区域转化OpenCV的Mat格式,并在屏幕上显示,因此我们可以利用Mat格式调用OpenCV的相关操作。

while (true)
        {
            clock_t startTime, endTime;
            startTime = clock();
            nRet = MV_CC_GetImageBuffer(handle, &stImageInfo, 1000);
            if (nRet == MV_OK)
            {
                printf("Get One Frame: Width[%d], Height[%d], nFrameNum[%d]\n",
                    stImageInfo.stFrameInfo.nWidth, stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nFrameNum);
            }
            else
            {
                printf("No data[0x%x]\n", nRet);
                free(pData);
                pData = NULL;
                break;
            }
            cv::Mat srcImage;
            srcImage = cv::Mat(stImageInfo.stFrameInfo.nHeight, stImageInfo.stFrameInfo.nWidth, CV_8UC1, stImageInfo.pBufAddr);
            cv::namedWindow("srcImage", 0);
            cv::resizeWindow("srcImage", 918, 768);
            cv::imshow("srcImage", srcImage);
            cv::waitKey(1);
            srcImage.release();
            nRet = MV_CC_FreeImageBuffer(handle, &stImageInfo);
            endTime = clock();
            std::cout << "Run Time:" << (double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << std::endl;
            std::cout<< std::endl;
        }

根据上述代码,我们将ImageBuffer区域的数据转化为Mat格式,并且根据CV_8UC1格式,可知图像应为灰度图,这要与相机图像格式对应。


三、运行结果

运行结果如图所示:
海康工业相机SDK+OpenCV实例(2):RawDataFormatConvert详解_第1张图片
海康工业相机SDK+OpenCV实例(2):RawDataFormatConvert详解_第2张图片


你可能感兴趣的:(海康SDK,opencv,c++,visual,studio,图像处理,计算机视觉)