海康彩色工业相机图像格式转换方法

  • 1.彩色相机是如何变成彩色的-Bayer的由来
  • 2.工业相机支持的图像格式
  • 3.图像格式转化
  • 4.一些其他的问题

1.彩色相机是如何变成彩色的-Bayer的由来

提到工业相机图像格式,尤其是彩色相机的图像格式,不得不先讲一下bayer图像格式,网上有很多介绍这种图像格式的文档,随意引用一篇简单介绍下,引用链接: 图像bayer格式介绍以及bayer插值原理.
大致原理呢,就是相机上面的图像传感器只能感受光强而无法感知光的波长,然而光的颜色却是由波长决定的,因此图像传感器是无法记录颜色的。
虽然可以在相机的内部内置三个图像传感器来分别记录红、绿、蓝三元色,然后将这三种颜色合并得到最终的彩色图像,但是这样做的成本太高。
因此,柯达这个公司,提出的解决方案就是,使用一个图像传感器,在图像传感器的前面,放置一个滤光层,滤光层的滤光点与图像传感器的像素一一对应,每个滤光点只能通过红、绿、蓝三种光其中之一;

通过规律性的排列不同颜色的滤光点,我们就能在传感器上面有规律的获得不同颜色的光强值,也就是R、G、B的灰度值;
根据不同于颜色的排列,我们把Bayer分为BayerRG、BayerBG、BayerGB、BayerBG四种

但是呢,这样得到一幅图像,其实仅仅是灰度图,它并不能表达呈现真实世界的图像

放大看

如果想要呈现真实的色彩世界,那么就需要弥补每个像素所缺少的其他色彩分量,用相邻的像素值补充进来,这个过程就叫做bayer差值,也叫“去马赛克”(如要简单理解原理,可以去看开篇引用的链接)

当然,相机实现彩色图像原理,肯定不止这一种,但是,出于成本、生产技术等因素,目前你所能接触到的大部分相机,工业相机,数码相机,原始数据,都是有bayer转换产生的;

2.工业相机支持的图像格式

前面讲了,传感器的彩色由来,那么就接下来讲讲工业相机支持的图像格式种类,以海康工业相机为例子

相机种类 图像格式 细分 说明
黑白相机 Mono Mono8、Mono10、Mono12,Mono10 Packed、Mono12 Packed
彩色相机 Bayer Bayer8、Bayer10、Bayer12 、Bayer10 Packed、Bayer12 Packed Bayer根据sensor遮挡层排列不同,分为BG、GR、GB、BR四种
彩色相机 YUV YUV 422 (YUYV) Packed、YUV 422 Packed
彩色相机 RGB RGB8 Packed、BGR8 Packed 两者的区别就是R、B排列是相反的

mono10、mono12:分别代表10位、12位黑白图像,在内存中以16位数据存储,不够的数据位填0补充
Mono10 Packed、Mono12 Packed:这种数据跟上面的mono10、mono12没有本质上的区别,差异就是,在数据排列上面,16位数据存储,原来补0的位置,被下一帧图像数据填充,这样的好处就是节约了传输带宽,坏处就是小小的增加了解码的难度

Bayer8、Bayer10、Bayer12:分别代表8位、10位、12位的彩色相机相机原始数据格式,传感器采样最原始的数据是Bayer12,Bayer8、Bayer10都是由Bayer12下采样过来的
Bayer10 Packed、Bayer12 Packed:与mono10 Packed,mono12 Packed一样的道理,数据排列方式不同

YUV 422 Packed、YUV 422 (YUYV) Packed:YUV是由bayer数据先转化为RGB,然后RGB转化为YUV数据得到的,其中Y代表亮度值,数据排列分别是UYVY、与YUYV两种,它们都是16位存储的,Packed就是数据填充方式

那么如何查询自己手上的工业相机,支持的图像格式,以海康工业相机为例,使用其MVS客户端,打开相机后,在相机属性中找到Pixel Format点击即可查看,切换图像格式,需要再非预览模式状态下

3.图像格式转化

以海康工业相机的格式转换例程为例,讲讲图像格式如何转化
先来看一下他们提供的代码

#include <stdio.h>
#include <Windows.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!\n");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);// ch:打印当前相机ip和用户自定义名字 | en:print current ip and user defined nameprintf("CurrentIp: %d.%d.%d.%d\n" , nIp1, nIp2, nIp3, nIp4);printf("UserDefinedName: %s\n\n" , pstMVDevInfo->SpecialInfo.stGigEInfo.chUserDefinedName);}else if (pstMVDevInfo->nTLayerType == MV_USB_DEVICE){printf("UserDefinedName: %s\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chUserDefinedName);printf("Serial Number: %s\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.chSerialNumber);printf("Device Number: %d\n\n", pstMVDevInfo->SpecialInfo.stUsb3VInfo.nDeviceNumber);}else{printf("Not support.\n");}return true;
}
bool IsColor(MvGvspPixelType enType)
{switch(enType){case PixelType_Gvsp_BGR8_Packed:case PixelType_Gvsp_YUV422_Packed:case PixelType_Gvsp_YUV422_YUYV_Packed:case PixelType_Gvsp_BayerGR8:case PixelType_Gvsp_BayerRG8:case PixelType_Gvsp_BayerGB8:case PixelType_Gvsp_BayerBG8:case PixelType_Gvsp_BayerGB10:case PixelType_Gvsp_BayerGB10_Packed:case PixelType_Gvsp_BayerBG10:case PixelType_Gvsp_BayerBG10_Packed:case PixelType_Gvsp_BayerRG10:case PixelType_Gvsp_BayerRG10_Packed:case PixelType_Gvsp_BayerGR10:case PixelType_Gvsp_BayerGR10_Packed:case PixelType_Gvsp_BayerGB12:case PixelType_Gvsp_BayerGB12_Packed:case PixelType_Gvsp_BayerBG12:case PixelType_Gvsp_BayerBG12_Packed:case PixelType_Gvsp_BayerRG12:case PixelType_Gvsp_BayerRG12_Packed:case PixelType_Gvsp_BayerGR12:case PixelType_Gvsp_BayerGR12_Packed:return true;default:return false;}
}
bool IsMono(MvGvspPixelType enType)
{switch(enType){case PixelType_Gvsp_Mono10:case PixelType_Gvsp_Mono10_Packed:case PixelType_Gvsp_Mono12:case PixelType_Gvsp_Mono12_Packed:return true;default:return false;}
}
int main()
{int nRet = MV_OK;void* handle = NULL;unsigned char *pConvertData = NULL;unsigned int nConvertDataSize = 0;do {// ch:枚举设备 | en:Enum deviceMV_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;}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!\n");break;}// ch:选择设备并创建句柄 | en:Select device and create handlenRet = MV_CC_CreateHandle(&handle, stDeviceList.pDeviceInfo[nIndex]);if (MV_OK != nRet){printf("Create Handle fail! nRet [0x%x]\n", nRet);break;}// ch:打开设备 | en:Open devicenRet = MV_CC_OpenDevice(handle);if (MV_OK != nRet){printf("Open Device fail! nRet [0x%x]\n", 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){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);}}nRet = MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_OFF);if (MV_OK != nRet){printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);break;}// ch:开始取流 | en:Start grab imagenRet = MV_CC_StartGrabbing(handle);if (MV_OK != nRet){printf("Start Grabbing fail! nRet [0x%x]\n", nRet);break;}MV_FRAME_OUT stImageInfo = {0};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);MvGvspPixelType enDstPixelType = PixelType_Gvsp_Undefined;unsigned int nChannelNum = 0;char chFileName[MAX_PATH] = {0};//如果是彩色则转成RGB8if (IsColor(stImageInfo.stFrameInfo.enPixelType)){nChannelNum = 3;enDstPixelType = PixelType_Gvsp_RGB8_Packed;sprintf(chFileName, "AfterConvert.rgb");}//如果是黑白则转换成Mono8else if (IsMono(stImageInfo.stFrameInfo.enPixelType)){nChannelNum = 1;enDstPixelType = PixelType_Gvsp_Mono8;sprintf(chFileName, "AfterConvert.gray");}else{printf("Don't need to convert!\n");}         if (enDstPixelType != PixelType_Gvsp_Undefined){pConvertData = (unsigned char*)malloc(stImageInfo.stFrameInfo.nWidth * stImageInfo.stFrameInfo.nHeight * nChannelNum);if (NULL == pConvertData){printf("malloc pConvertData fail!\n");nRet = MV_E_RESOURCE;break;}nConvertDataSize = stImageInfo.stFrameInfo.nWidth * stImageInfo.stFrameInfo.nHeight * nChannelNum;// ch:像素格式转换 | en:Convert pixel format MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {0};stConvertParam.nWidth = stImageInfo.stFrameInfo.nWidth;                 //ch:图像宽 | en:image widthstConvertParam.nHeight = stImageInfo.stFrameInfo.nHeight;               //ch:图像高 | en:image heightstConvertParam.pSrcData = stImageInfo.pBufAddr;                         //ch:输入数据缓存 | en:input data bufferstConvertParam.nSrcDataLen = stImageInfo.stFrameInfo.nFrameLen;         //ch:输入数据大小 | en:input data sizestConvertParam.enSrcPixelType = stImageInfo.stFrameInfo.enPixelType;    //ch:输入像素格式 | en:input pixel formatstConvertParam.enDstPixelType = enDstPixelType;                         //ch:输出像素格式 | en:output pixel formatstConvertParam.pDstBuffer = pConvertData;                               //ch:输出数据缓存 | en:output data bufferstConvertParam.nDstBufferSize = nConvertDataSize;                       //ch:输出缓存大小 | en:output buffer sizenRet = MV_CC_ConvertPixelType(handle, &stConvertParam);if (MV_OK != nRet){printf("Convert Pixel Type fail! nRet [0x%x]\n", nRet);break;}FILE* fp = NULL;errno_t err = fopen_s(&fp, chFileName, "wb");if (0 != err || NULL == fp){printf("Open file failed\n");nRet = MV_E_RESOURCE;break;}fwrite(stConvertParam.pDstBuffer, 1, stConvertParam.nDstLen, fp);fclose(fp);printf("Convert pixeltype succeed\n");}MV_CC_FreeImageBuffer(handle, &stImageInfo);}else{printf("Get Image fail! nRet [0x%x]\n", nRet);}// ch:停止取流 | en:Stop grab imagenRet = MV_CC_StopGrabbing(handle);if (MV_OK != nRet){printf("Stop Grabbing fail! nRet [0x%x]\n", nRet);break;}// ch:关闭设备 | en:Close devicenRet = MV_CC_CloseDevice(handle);if (MV_OK != nRet){printf("Close Device fail! nRet [0x%x]\n", nRet);break;}// ch:销毁句柄 | en:Destroy handlenRet = MV_CC_DestroyHandle(handle);if (MV_OK != nRet){printf("Destroy Handle fail! nRet [0x%x]\n", nRet);break;}} while (0);if (pConvertData){free(pConvertData);pConvertData = NULL;}if (nRet != MV_OK){if (handle != NULL){MV_CC_DestroyHandle(handle);handle = NULL;}}printf("Press a key to exit.\n");WaitForKeyPress();return 0;
}

关键的几句代码如下,要看MV_CC_GetImageBuffer函数后面,拿到一帧图像之后,调用MV_CC_ConvertPixelType进行图像转换图像格式,在其SDK开发文档中,我们可以看见这个函数作用范围

格式转换的总体思路如下:

Created with Raphaël 2.2.0相机拍照采集一帧图像彩色格式?格式转换目标格式:RGB格式转换输出Mono or RGB图像黑白格式?格式转换目标格式:Mono8yesnoyes

第一步,黑白彩色相机判断;

  • 示例代码中,是根据帧结构体来判断的,如下所示
//如果是彩色则转成RGB8
//IsColor这个函数,列举了相机支持的所有彩色图像格式
//然后再与stImageInfo.stFrameInfo结构体里面相机传递上来的enPixelType做对比判断
if (IsColor(stImageInfo.stFrameInfo.enPixelType))
{//----//转换的目标格式设置为RGBenDstPixelType = PixelType_Gvsp_RGB8_Packed;//部分使用OpenCV的朋友,这里要修改成PixelType_Gvsp_BGR8_Packed
}
//如果是黑白则转成mono8
//IsMono这个函数,列举了相机支持的所有黑白图像格式
//然后再与stImageInfo.stFrameInfo结构体里面相机传递上来的enPixelType做对比判断
else if (IsMono(stImageInfo.stFrameInfo.enPixelType))
{//----//转换的目标格式设置为mon8enDstPixelType = PixelType_Gvsp_Mono8;
}

第二步,调用接口进行图像格式转换,这里的变量enDstPixelType就是目标格式

if (enDstPixelType != PixelType_Gvsp_Undefined)
{pConvertData = (unsigned char*)malloc(stImageInfo.stFrameInfo.nWidth * stImageInfo.stFrameInfo.nHeight * nChannelNum);if (NULL == pConvertData){printf("malloc pConvertData fail!\n");nRet = MV_E_RESOURCE;break;}nConvertDataSize = stImageInfo.stFrameInfo.nWidth * stImageInfo.stFrameInfo.nHeight * nChannelNum;// ch:像素格式转换 | en:Convert pixel format MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {0};stConvertParam.nWidth = stImageInfo.stFrameInfo.nWidth;                 //ch:图像宽 | en:image widthstConvertParam.nHeight = stImageInfo.stFrameInfo.nHeight;               //ch:图像高 | en:image heightstConvertParam.pSrcData = stImageInfo.pBufAddr;                         //ch:输入数据缓存 | en:input data bufferstConvertParam.nSrcDataLen = stImageInfo.stFrameInfo.nFrameLen;         //ch:输入数据大小 | en:input data sizestConvertParam.enSrcPixelType = stImageInfo.stFrameInfo.enPixelType;    //ch:输入像素格式 | en:input pixel format//这里就是目标格式stConvertParam.enDstPixelType = enDstPixelType;                         //ch:输出像素格式 | en:output pixel format//输出的mono8或者RGB8数据stConvertParam.pDstBuffer = pConvertData;                               //ch:输出数据缓存 | en:output data bufferstConvertParam.nDstBufferSize = nConvertDataSize;                       //ch:输出缓存大小 | en:output buffer sizenRet = MV_CC_ConvertPixelType(handle, &stConvertParam);if (MV_OK != nRet){printf("Convert Pixel Type fail! nRet [0x%x]\n", nRet);break;}FILE* fp = NULL;errno_t err = fopen_s(&fp, chFileName, "wb");if (0 != err || NULL == fp){printf("Open file failed\n");nRet = MV_E_RESOURCE;break;}fwrite(stConvertParam.pDstBuffer, 1, stConvertParam.nDstLen, fp);fclose(fp);printf("Convert pixeltype succeed\n");}
}

需要注意的是,如果你想使用10bit、12bit的数据,那么你需要先在相机端,设置相机的图像格式为mono10、mono12等,这样拿到的raw数据才会是其他位数,同时,不去做格式转换;上面格式转换的目的是转换成常用的8bit数据

4.一些其他的问题

  1. mono8 、mono10、mono12之间的区别
    首先,要了解一个灰阶的概念,通常来说,液晶屏幕上人们肉眼所见的一个点,即一个像素,它是由红、绿、蓝(RGB)三原色组成的。每一个基色,其背后的光源都可以显现出不同的亮度级别。而灰阶代表了由最暗到最亮之间不同亮度的层次级别。
    在数字信息存贮中,计算设备用2进制数来表示,每个0或1就是一个位(bit)。 假设1代表黑、0代表白,在黑白双色系统中最少有2bit。单基色为nbit,画面位数就为2 ⁿbit,位数越大,灰度越多,颜色也越多,彩色系统中同理。视频画面10bit含义就是画面能以10为二进制数的数量控制色彩层次(即灰阶)。通常8bit相当于256级灰阶——即常说得24位真彩色;而10bit就相当于1024级灰阶。三基色混合成彩色,增加1 bit就意味色彩数增加8倍。10bit就相当于1024的三次方——1073741824,约为10.7亿色。远大于8bit的1670万色。
    那么,mono8,就是2^8=256灰阶,因此你看见的黑白mono8图像,灰度值范围时0-255;
    同理,mono10,mono12分别是2^10、 2^12, 图像灰度值范围0-1024、0-4096,但是如果你将图像数据存储下来,在计算机内存里面,只能按照8、16、24、32等位深存储的,那么10、12位数据就会被补0,灰度范围就会被拉伸到2^16,也就是0-65536

2.Bayer转RGB,注意事项

  • bayer插值算法差异
    海康提供的sdk接口中,提供了3种不同的bayer转RGB算法,调用MV_CC_SetBayerCvtQuality()接口实现,接口调用在其Opendevice函数之后即可
BayerCvtQuality Value 备注
0 快速 速度最快,图像边缘有锯齿感
1 均衡 效果适中
2 最优 图像效果最好,速度最慢,cpu 消耗较高

下图来看一下不同插值算法的效果,从上到下,依次是快速,均衡,最优
当对格式转换速度有要求时,可以尝试下不同插值算法,从中做取舍

3.其他的格式转换方法

  • halcon
    halcon也提供了算子做图像格式转化:cfa_to_rgb (ImageCFA, RGBImage, ‘bayer_gb’, ‘bilinear’),最后一个参数“bilinear”就是不同的插值算法,也有三种选择可配【halcon参考文档】,同样的,不同的插值算法也有不同的优劣势,用户需要自行测试;
    bayer格式需要看相机输出什么,需要根据相机参数进行填写
/*************************************************************************  @fn     ConvertBayer8ToHalcon()*  @brief  Bayer8转换为Halcon格式数据*  @param  Hobj                   [OUT]          转换后的输出Hobject数据*  @param  nHeight                [IN]           图像高度*  @param  nWidth                 [IN]           图像宽度*  @param  nPixelType             [IN]           源数据格式*  @param  pData                  [IN]           源数据*  @return 成功,返回STATUS_OK;错误,返回STATUS_ERROR ************************************************************************/
int ConvertBayer8ToHalcon(Halcon::Hobject *Hobj, int nHeight, int nWidth, MvGvspPixelType nPixelType, unsigned char *pData)
{if(NULL == Hobj || NULL == pData){return MV_E_PARAMETER;}gen_image1(Hobj, "byte", nWidth, nHeight, (Hlong)pData);if (nPixelType == PixelType_Gvsp_BayerGR8){cfa_to_rgb(*Hobj, Hobj, "bayer_gr", "bilinear");}else if (nPixelType == PixelType_Gvsp_BayerRG8){cfa_to_rgb(*Hobj, Hobj, "bayer_rg", "bilinear");}else if (nPixelType == PixelType_Gvsp_BayerGB8){cfa_to_rgb(*Hobj, Hobj, "bayer_gb", "bilinear");}else if (nPixelType == PixelType_Gvsp_BayerBG8){cfa_to_rgb(*Hobj, Hobj, "bayer_bg", "bilinear");}return MV_OK;
}
  • OpenCV
    使用OpenCV提供的接口,也能将bayer数据快速转化为RGB/BGRcvtColor(source, destination, CV_BayerRG2BGR),但是似乎没有更多的插值方法可以选择
 Mat bayer2rgb;bayer2rgb.create(ImageBuffer.rows,ImageBuffer.cols,CV_8UC3);cvtColor(ImageBuffer,bayer2rgb,CV_BayerRG2BGR);//BayerRG需要事先知道bayer数据的种类//OpenCV要使用BGR而非RGB,如果要转RGB,CV_BayerRG2BGR需要替换为CV_BayerRG2RGB

  • 其他的方法

    还有很多bayer转RGB的接口,暂时没遇到或者没有学到,靠大家来分享,共同学习

海康彩色工业相机图像格式转换方法(Bayer转RGB)相关推荐

  1. 海康机器人工业相机sdk简介

    海康机器人工业相机SDK获取与简单介绍 SDK下载 SDK组成 1.头文件 2.静态库/lib库 3.动态库 4.开发文档 5.示例程序 SDK下载 在海康机器人的官网下载中心-> 海康机器人下 ...

  2. 海康机器人工业相机常用参数功能设置与获取(持续更新全-C语言)

    海康机器人工业相机常用参数功能设置与获取(C语言) 前言 相机属性树 1.设备控制/DeviceControl 1.1相机序列号获取/DeviceSerialNumber 1.2相机自定义命名设置与获 ...

  3. MS VS+HIK海康机器人工业相机环境配置

    MS VS+HIK海康机器人工业相机环境配置 一.配置之前的准备工作 二 .配置环境 1.系统环境变量配置 2.项目属性配置 三.环境验证 一.配置之前的准备工作 在具体配置之前,务必下载安装好所需文 ...

  4. C++下OPENCV驱动调用海康GigE工业相机

    系列文章目录 第一章 Ubuntu22下OpenCV4.6.0+contrib模块编译安装 第二章 ubuntu22下C++ kdevelop环境搭建:OpenCV示例 第三章 C++下OPENCV驱 ...

  5. 不带网口的笔记本电脑使用海康GigE工业相机

    不带网口的笔记本电脑使用海康GigE工业相机 现在的笔记本都向轻薄型发展,基本都不带网线接口了.而一般程序开发人员都是使用的笔记本进行程序开发,因为笔记本携带方便嘛.我自己在工作中就遇到了,笔记本无法 ...

  6. Python 实现海康机器人工业相机 MV-CU060-10GM 的实时显示视频流及拍照功能

    一.背景介绍 1.最近项目中需要给客户对接海康机器人工业相机 MV-CU060-10GM: 2.客户要求通过部署的管理平台,可以在页面上实现如下功能: 1)相机视频流开始预览: 2)相机视频流停止预览 ...

  7. Python下Opencv尝试调用海康GIGE工业相机

    环境 一.相机型号(海康): HIKVison MV-CE013-50GC 二.win10 x86_64 三.Python3.6.5.OpenCV3.4 四.需要结合海康SDK 拿到的童鞋,估计要慌了 ...

  8. Bayer到RGB,格式转换原理及具体实现

    缘起 使用海康彩色相机,采集到的图像数据是Bayer GR8格式的,如果在相机参数中改为其它彩色格式,那就是相机内部完成格式转化,就会导致采集帧率变慢.一般情况下这种方式是简单实用的,但如果想要追求更 ...

  9. Python调用海康工业相机:包含相机参数修改、彩色原图显示(不失真)

    [引言] 海康相机作为目前工业检测.视觉定位等领域应用较为广泛的国产品牌相机,其搭配有一套专用视觉软件VM,而在完成具有复杂场景.复杂任务的科研项目时依靠其VM算法平台提供的视觉算法往往无法满足项目要 ...

最新文章

  1. Hitpoint:外贸企业如何选择合适的ERP系统
  2. 数据归一化matlab及python 实现
  3. [转载MSDN]IIS 7.0中的Live Smooth Streaming -入门
  4. 基于实战开发垂直搜索引擎_基于DDD的微服务设计和开发实战
  5. 算法竞赛入门经典 第五章总结1
  6. 两个服务器之间怎么传输大量数据速度快 java socket_千兆网络的传输速度能超过125MB/s么?...
  7. 如何阻止通过Outlook用户发送WORD或EXCEL变成带Winmail.dat文件附件的邮件
  8. dorehtml.php,帝国cms后台实现刷新多栏目内容页的方法详解
  9. UVA11351 Last Man Standing【约瑟夫环+数学】
  10. jquery 插件开发小组
  11. 计算机网络ppt_计算机网络--女娲补天
  12. u盘在磁盘管理可以显示 但是电脑中找不到_电脑无法识别U盘?5步操作让办公族轻松搞定!...
  13. php mysql join查询结果_PHP mySQL表JOIN查询 - 最有效的方法?
  14. visio设置图片默认大小_visio怎么调整图片大小、间距-visio调整图片大小、间距的方法 - 河东软件园...
  15. 万物并作,吾以观复|OceanBase 政企行业实践
  16. pcr扩增的原理和步骤
  17. 制作zencart模板的几个步骤
  18. 批量修改文件名,图文教学,2分钟简单学会
  19. 利用Rustlings对Rust语言进行学习
  20. 2019人工智能行业的25大趋势预测

热门文章

  1. 【面试真题】腾讯2018秋招前端正式试题(含答案)
  2. stata 保存到word
  3. Thinkpad MORFFHL鼠标滑鼠接收器配对 thinkpad laser wireless mouse
  4. linux c在线运行,C语言在线运行
  5. 学习笔记 | 多水平logistics模型
  6. 中国经济为着陆做准备
  7. Crack密码验证小实验
  8. matlab指数积分函数,如何使用matlab拟合指数分布函数?
  9. 【附源码】Java计算机毕业设计勤工俭学管理小程序(程序+LW+部署)
  10. 移动硬盘文件丢失怎么恢复