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

海康机器人工业相机常用参数功能设置与获取(C语言)

前言

本文简单直接粗糙的介绍下海康工业相机常用的参数的设置方法与获取方法
1.海康工业SDK简介:海康机器人工业相机sdk简介
2.海康工业相机参数设置获取通用方法:海康工业相机参数设置与获取
如果不心急,就先简单阅读上述两篇博客,可以更加熟悉海康的工业相机sdk的整体构成
参数实在是太多,有空慢慢更新啦…

相机属性树

1.设备控制/DeviceControl

1.1相机序列号获取/DeviceSerialNumber

	MVCC_STRINGVALUE stStrValue;
	memset(&stStrValue, 0, sizeof(MVCC_STRINGVALUE));
	nRet = MV_CC_GetStringValue(handle, "DeviceSerialNumber", &stStrValue);
	if (MV_OK != nRet)
	{
    
    
		printf("Get DeviceSerialNumber fail! nRet [0x%x]\n", nRet);
	}
	printf("Current DeviceSerialNumber [%s]\n", stStrValue.chCurValue);
	

结果:
在这里插入图片描述

1.2相机自定义命名设置与获取/DeviceUserID

	nRet = MV_CC_SetStringValue(handle, "DeviceUserID", "UserIDChanged");
	if (MV_OK != nRet)
	{
    
    
		printf("Set DeviceUserID fail! nRet [0x%x]\n", nRet);
	}
	MVCC_STRINGVALUE stStrValue;
	memset(&stStrValue, 0, sizeof(MVCC_STRINGVALUE));
	nRet = MV_CC_GetStringValue(handle, "DeviceUserID", &stStrValue);
	if (MV_OK != nRet)
	{
    
    
		printf("Get DeviceUserID fail! nRet [0x%x]\n", nRet);
	}
	printf("Rename DeviceUserID [%s]\n", stStrValue.chCurValue);	

结果:
在这里插入图片描述

1.3相机上电时间获取/DeviceUptime

	MVCC_INTVALUE_EX stIntValue = {
    
    0};
    nRet = MV_CC_GetIntValueEx(handle, "DeviceUptime", &stIntValue);
    if (MV_OK != nRet)
    {
    
    
        printf("Get DeviceUptime fail! nRet [0x%x]\n", nRet);
    }
	printf("DeviceUptime [%d]\n", stIntValue.nCurValue);

结果:
在这里插入图片描述

2.相机格式控制/ImageFormatControl

2.1获取相机图像最大宽、高值

	MVCC_INTVALUE_EX nWidthMaxValue= = {
    
    0},nHeightMaxValue = {
    
    0};	
	//如需获取当前相机图像宽高,需要将WidthMax替换成Width	
    nRet = MV_CC_GetIntValueEx(handle, "WidthMax", &nWidthMaxValue);
    if (MV_OK != nRet)
    {
    
    
    	printf("Get WidthMax fail! nRet [0x%x]\n", nRet);
    }
    //如需获取当前相机图像宽高,需要将HeightMax替换成Height
	nRet = MV_CC_GetIntValueEx(handle, "HeightMax", &nHeightMaxValue);
    if (MV_OK != nRet)
    {
    
    
         printf("Get HeightMax fail! nRet [0x%x]\n", nRet);
    }

2.2设置相机图像ROI区域

注意事项:相机设置图像宽高时,相机不能取流:需要在startgrabing之前设置或者stopgrabing之后设置

	unsigned int m_Width=1000,m_Height=1000;//要设置的步进值
	//offset,设置的偏移值,图像左上角为原点,一般需要是2的倍数,不能是奇数
	unsigned int m_OffsetX=256,m_OffsetY=256;
	//获取图像宽高最大最小值,获取步进值
	MVCC_INTVALUE_EX nWidthValue= {
    
    0},nHeightValue = {
    
    0};	
	//获取相机支持的宽高最大值	
	nRet = MV_CC_GetIntValueEx(handle, "Width", &nWidthValue);
	nRet = MV_CC_GetIntValueEx(handle, "Height", &nHeightValue);
	if(m_Width>nWidthValue.nMax||
		m_Height > nHeightValue.nMax||
		m_Width<nWidthValue.nMin||
		m_Height < nHeightValue.nMin||
		(m_Width+m_OffsetX)>nWidthValue.nMax||		//偏移值+设置值必须小于宽高的最大值
		(m_Height +m_OffsetY)>nHeightValue.nMax||)
	{
    
    
		//判断有没有超出范围,超出范围就报错!!!
		 printf("Set Image Width or Height out of range !!\n", nRet);
	}else 
	{
    
    
		//避免offset有偏移值,导致后续设置宽高失败
		nRet = MV_CC_SetIntValue(handle,"OffsetX",0);
		nRet = MV_CC_SetIntValue(handle,"OffsetY",0);
		if((m_Width%nWidthValue.nInc)==0&&(m_Height%nHeightValue.nInc)==0)//符合步进值才设置进去
		{
    
    	
			nRet = MV_CC_SetIntValue(handle,"Width",m_Width);
			if(nRet != MV_OK)
            {
    
    
               	printf("Warning: Set Width  fail nRet [0x%x]!", nRet);
            }
			nRet = MV_CC_SetIntValue(handle,"Height",m_Height);
			if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set Height  fail nRet [0x%x]!", nRet);
            }
            nRet = MV_CC_SetIntValue(handle,"OffsetX",m_OffsetX);
            if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set OffsetX fail nRet [0x%x]!", nRet);
            }
			nRet = MV_CC_SetIntValue(handle,"OffsetY",m_OffsetY);
			if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set OffsetY fail nRet [0x%x]!", nRet);
            }
		}else
		{
    
    
			//不符合步进,减去余数再去设置宽高,此时设置的宽高与原宽高有差异
			nRet = MV_CC_SetIntValue(handle,"Width",m_Width-m_Width%nWidthValue.nInc);
			if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set Width  fail nRet [0x%x]!", nRet);
            }
			nRet = MV_CC_SetIntValue(handle,"Height",m_Height-m_Height%nHeightValue.nInc);
			if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set Height  fail nRet [0x%x]!", nRet);
             }
           	nRet = MV_CC_SetIntValue(handle,"OffsetX",m_OffsetX);
            if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set OffsetX fail nRet [0x%x]!", nRet);
            }
			nRet = MV_CC_SetIntValue(handle,"OffsetY",m_OffsetY);
			if(nRet != MV_OK)
            {
    
    
                printf("Warning: Set OffsetY fail nRet [0x%x]!", nRet);
            }
		}		
	}

2.3恢复相机图像ROI区域,恢复最大值

	MVCC_INTVALUE_EX nWidthMaxValue= {
    
    0},nHeightMaxValue = {
    
    0};		
	nRet = MV_CC_GetIntValueEx(handle, "WidthMax", &nWidthMaxValue);
	if (MV_OK != nRet)
	{
    
    
		printf("Get WidthMax fail! nRet [0x%x]\n", nRet);
	}
	nRet = MV_CC_GetIntValueEx(handle, "HeightMax", &nHeightMaxValue);
	if (MV_OK != nRet)
	{
    
    
		printf("Get HeightMax fail! nRet [0x%x]\n", nRet);
	}	
	//一定要先还原相机的偏移值,再去设置相机宽高
	nRet = MV_CC_SetIntValue(handle,"OffsetX",0);
	nRet = MV_CC_SetIntValue(handle,"OffsetY",0);
	nRet = MV_CC_SetIntValue(handle,"Width",nWidthMaxValue.nCurValue);//设置为最大值
	if(nRet != MV_OK)
	{
    
    
		printf("Warning: Set Width  fail nRet [0x%x]!", nRet);
	}
	nRet = MV_CC_SetIntValue(handle,"Height",nHeightMaxValue.nCurValue);//设置为最大值
	if(nRet != MV_OK)
	{
    
    
		printf("Warning: Set Height  fail nRet [0x%x]!", nRet);
	}

2.4获取相机支持的图像格式

MV_XML_NODE_FEATURE stNodeFeature;
MV_XML_FEATURE_Enumeration stFeatureEnm;
memset(&stNodeFeature,0,sizeof(MV_XML_NODE_FEATURE));
memset(&stFeatureEnm, 0, sizeof(MV_XML_FEATURE_Enumeration));
strncpy(stNodeFeature.strName, "PixelFormat", strlen("PixelFormat"));
stNodeFeature.enType = IFT_IEnumeration;
nRet = MV_XML_GetNodeFeature(handle,&stNodeFeature,&stFeatureEnm);
if (MV_OK != nRet)
{
    
    
	return nRet;
}else
{
    
    
	for (int i = 0; i < stFeatureEnm.nSymbolicNum; i++)
	{
    
    
		printf("PixelFormat:%s \r\n", stFeatureEnm.strSymbolic[i]);//打印出相机支持的所有像素格式
				
	}
	for (int i = 0; i < stFeatureEnm.nSymbolicNum; i++)
	{
    
    
		if (strcmp(stFeatureEnm.strSymbolic[i] ,"BayerBG8")==0|| 
			strcmp(stFeatureEnm.strSymbolic[i], "BayerRG8")==0|| 
			strcmp(stFeatureEnm.strSymbolic[i], "BayerGB8")==0|| 
			strcmp(stFeatureEnm.strSymbolic[i], "BayerGR8")==0||
			strcmp(stFeatureEnm.strSymbolic[i], "RGB8Packed")==0|| 
			strcmp(stFeatureEnm.strSymbolic[i], "BGR8Packed")==0)//比较相机参数格式,这里仅比较了bayer与RGB
		{
    
    
			printf("This is a Color camera \n");
			break;
		}
	}
}

结果:
黑白相机:![在这里插入图片描述](https://img-blog.csdnimg.cn/81aa4d9a473442bcb28dc8114137f7c9.png)彩色相机:

2.5修改相机图像格式

	//设置Enum型参数-相机图像格式
	//注意点1:相机图像格式设置时,只有在MV_CC_Startgrab接口调用前才能设置,取流过程中,不能修改图像格式
	nRet = MV_CC_SetEnumValue(handle, "PixelFormat", PixelType_Gvsp_Mono12);
	if (MV_OK != nRet)
	{
    
    
		printf("error: Set PixelFormat fail [%x]\n", nRet);
	}

2.6打开/关闭相机自带测试图像

2.6.1关闭测试图像(默认状态)

	nRet = MV_CC_SetEnumValue(handle, "TestPattern", 0);
	if (MV_OK != nRet)
	{
    
    
		printf("Set TestPattern fail! nRet [0x%x]\n", nRet);
		break;
	}

2.6.2打开测试图像

	nRet = MV_CC_SetEnumValue(handle, "TestPattern", 9);
	//0:off,9:ColorBar,14:ObliqueMonoBar,17:TestImage1
	if (MV_OK != nRet)
	{
    
    
		printf("Set TestPattern fail! nRet [0x%x]\n", nRet);
		break;
	}

效果:
在这里插入图片描述

2.7打开/关闭相机图像X镜像、Y镜像

	nRet = MV_CC_SetBoolValue(handle, "ReverseX", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set ReverseX fail! nRet [0x%x]\n", nRet);
	}
	//Y镜像需要注意两点
	//1.部分相机不支持,所以可能设置不了,具体看相机规格书spec
	//2.Y镜像需要停止采集状态下设置,不像X镜像一样可以实时设置,一般在MV_CC_StartGrabbing接口之前调用
	nRet = MV_CC_SetBoolValue(handle, "ReverseY", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set ReverseY fail! nRet [0x%x]\n", nRet);
	}

效果:
在这里插入图片描述

2.8打开/关闭相机嵌入式图像水印功能

相机的图像水印信息,用于打印记录相机内部信息,水印信息在取流接口中,图像结构体里面获取
相机水印的本质原理是取代图像头部开始的小部分有效信息,占用约40个字节的真实数据信息,供信息传输,不造成图像数据大小的变化
在这里插入图片描述

参数 关键词 参数值
时间戳 Timestamp 0
增益 Gain 1
曝光 Exposure 2
平均亮度 BrightnessInfo 3
白平衡 WhiteBalance 4
帧号 Framecounter 5
触发计数 ExtTriggerCount 6
IO输入输出电平状态 LineInputOutput 7
ROI区域 ROIPosition 8
	//必须停止采集状态下设置,一般在MV_CC_StartGrabbing接口之前调用
	//开启相机图像水印,如下,打开了Exposure、BrightnessInfo、Framecounter
	nRet = MV_CC_SetEnumValue(handle, "FrameSpecInfoSelector", 2);//Exposure
	nRet = MV_CC_SetBoolValue(handle, "FrameSpecInfo", true);
	nRet = MV_CC_SetEnumValue(handle, "FrameSpecInfoSelector", 3);//BrightnessInfo
	nRet = MV_CC_SetBoolValue(handle, "FrameSpecInfo", true);
	nRet = MV_CC_SetEnumValue(handle, "FrameSpecInfoSelector", 5);//Framecounter
	nRet = MV_CC_SetBoolValue(handle, "FrameSpecInfo", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set FrameSpecInfofail! nRet [0x%x]\n", nRet);
	}

效果:
主动取流中,图像结构体中获取水印信息
在这里插入图片描述
关闭水印功能

	//必须停止采集状态下设置,一般在MV_CC_StartGrabbing接口之前调用
	nRet = MV_CC_SetEnumValue(handle, "FrameSpecInfoSelector", 5);//Framecounter
	nRet = MV_CC_SetBoolValue(handle, "FrameSpecInfo", false);

3.采集控制/AcquisitionControl

3.1采集模式设置

参数 关键词 参数值 说明
单帧采集 SingleFrame 0 一般用于visionpro等特殊软件,正常不推荐使用这个模式
连续采集 Continuous 2 常用的模式,软触发的单帧采集,硬触发采集,连续拍照,都使用这个模式
	nRet = MV_CC_SetEnumValue(handle, "AcquisitionMode", 2);
	if (MV_OK != nRet)
	{
    
    
		printf("Set FrameSpecInfofail! nRet [0x%x]\n", nRet);
	}

3.2多帧采集设置/AcquisitionBurstFrameCount

AcquisitionBurstFrameCount:在触发模式下,触发一次,采集多少帧,默认为1;
假设设置为2,相机收到一个信号,自动采集两帧,采集频率根据帧率变化

	nRet = MV_CC_SetIntValue(handle,"AcquisitionBurstFrameCount",1);
	if(nRet != MV_OK)
	{
    
    
		printf("Warning: Set AcquisitionBurstFrameCountfail nRet [0x%x]!", nRet);
	}

3.3帧率控制/AcquisitionFrameRate

	//设置相机帧率,需注意不要超过相机支持的最大的帧率(相机规格书),超过了也没有意义
	nRet =MV_CC_SetFloatValue(handle, "AcquisitionFrameRate", 5);
	if(nRet != MV_OK)
	{
    
    
		printf("Warning: Set AcquisitionBurstFrameCountfail nRet [0x%x]!", nRet);
	}
	//帧率控制使能,true表示打开,false标识关闭
	nRet = MV_CC_SetBoolValue(handle, "AcquisitionFrameRateEnable", true);
	if(nRet != MV_OK)
	{
    
    
		printf("Warning: Set AcquisitionBurstFrameCountfail nRet [0x%x]!", nRet);
	}

3.4触发模式设置

3.4.1软触发设置/Software

	// ch:设置触发模式为on 
	nRet = MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
	}
	// ch:设置触发源为软触发
	nRet = MV_CC_SetEnumValue(handle, "TriggerSource",MV_TRIGGER_SOURCE_SOFTWARE);//TriggerSource:7
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Source fail! nRet [0x%x]\n", nRet);
	}

在需要拍摄图片的时刻,执行command命令,执行一次,相机拍摄一张图片(需在startgrabing命令开启后才行)

	nRet = MV_CC_SetCommandValue(handle, "TriggerSoftware");//相机拍照
	if (MV_OK != nRet)
	{
    
    
		printf("TriggerSoftware fail! nRet [0x%x]\n", nRet);
	}

3.4.2硬触发设置/line

硬触发要配合硬触发接线,配合的参数还有很多,参考:海康工业相机功能模块-IO输入输出控制
包括:
1、触发模式:TriggerMode设置为1,开启触发模式
2、触发源选择:TriggerSource设置为0,选择line0,也可以选择line2,或者选择anyway;line0、line2取决于硬件电路接线,anyway支持软触发、硬触发同时使用,需要看相机是否支持
3、沿信号TriggerActivation:默认上升沿触发(可以不设置)
4、触发缓存TriggerCacheEnable:默认不开启。当相机同时收到两个触发信号时,不开启此功能,相机只会响应1个信号,出一张图;开启后,相机会自动缓存第二个信号,上个信号处理完毕后,立即处理缓存信号
5、触发延时TriggerDelay:收到信号后,固定延迟一段时间再曝光
6、滤波设置 LineDebouncerTime:去除信号毛刺抖动,根据实际情况进行调节

	// ch:设置触发模式为on 
	nRet = MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
	}
	// ch:设置触发源为line硬触发
	nRet = MV_CC_SetEnumValue(handle, "TriggerSource",MV_TRIGGER_SOURCE_LINE0);//line0:0,line2:2
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Source fail! nRet [0x%x]\n", nRet);
	}

3.4.3任意触发设置/Anyway

Anyway即相机可以响应软触发命令,也可以响应line0、line2的硬触发信号
注意需要使用此功能时,需要了解相机是否支持该功能

	// ch:设置触发模式为on 
	nRet = MV_CC_SetEnumValue(handle, "TriggerMode", MV_TRIGGER_MODE_ON);
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
	}
	// ch:设置触发源为anyway
	nRet = MV_CC_SetEnumValue(handle, "TriggerSource",24);//line0:0,line2:2,anyway:24
	if (MV_OK != nRet)
	{
    
    
		printf("Set Trigger Source fail! nRet [0x%x]\n", nRet);
	}

3.5曝光设置

3.5.1手动曝光设置

	nRet = MV_CC_SetEnumValue(handle, "ExposureMode",0);//0:Timed
	nRet = MV_CC_SetFloatValue(handle, "ExposureTime", 1000);
	if (MV_OK != nRet)
	{
    
    
		printf("Set ExposureTime fail nRet [0xd%]\n!", nRet);
	}

3.5.2自动曝光设置

	nRet = MV_CC_SetEnumValue(handle, "ExposureMode",0);//0:Timed
	//ExposureAuto
	nRet = MV_CC_SetFloatValue(handle, "ExposureAuto", 2);//0:off 1:once 2:Continuous
	if (MV_OK != nRet)
	{
    
    
		printf("Set ExposureAuto fail nRet [0xd%]\n!", nRet);
	}else{
    
    
		//只有自动曝光或者自动增益开启后,Brightness亮度值方可设置
		nRet = MV_CC_SetIntValue(handle,"Brightness",160);
		if(nRet != MV_OK)
		{
    
    
			printf("Set BrightnessnRet [0x%x]!", nRet);
		}
	}

3.5.3超短曝光设置

		//标准曝光模式
		nRet = MV_CC_SetEnumValue(handle, "ExposureMode",0);//0:Timed
		nRet = MV_CC_SetEnumValue(handle, "ExposureTimeMode", 0);//0:Standard,1:UltraShort
        if (MV_OK != nRet)
        {
    
    
            printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
        }else
		{
    
    
			printf("ExposureTimeMode :Standard\n");
			//需要注意曝光值范围
			nRet = MV_CC_SetFloatValue(handle, "ExposureTime", 1000);
			if (MV_OK != nRet)
			{
    
    
				printf("Set ExposureTime fail nRet [0xd%]\n!", nRet);
			}
		}
		//超短曝光模式
		nRet = MV_CC_SetEnumValue(handle, "ExposureTimeMode", 1);//0:standard,1:UltraShort
        if (MV_OK != nRet)
        {
    
    
            printf("Set Trigger Mode fail! nRet [0x%x]\n", nRet);
        }else
		{
    
    
			printf("ExposureTimeMode :UltraShort\n");
			//需要注意曝光值范围
			nRet = MV_CC_SetFloatValue(handle, "ExposureTime", 12);
			if (MV_OK != nRet)
			{
    
    
				printf("Set ExposureTime fail nRet [0xd%]\n!", nRet);
			}
		}

3.6HDR多曝光增益切换

	unsigned ExpValue[4]={
    
    2000,3000,2500,1300};
	unsigned GainValue[4]={
    
    0,1,2,3};
	for (int i = 0; i < 4; i++)
	{
    
    
		nRet = MV_CC_SetIntValue(handle,"HDRSelector",i);//设置为最大值
		if(nRet != MV_OK)
		{
    
    
			printf("Warning: Set HDRSelector  fail nRet [0x%x]!", nRet);
		}
		nRet = MV_CC_SetIntValue(handle,"HDRShutter",ExpValue[i]);//设置为最大值
		if(nRet != MV_OK)
		{
    
    
			printf("Warning: Set HDRShutter  fail nRet [0x%x]!", nRet);
		}
		nRet =MV_CC_SetFloatValue(handle, "HDRGain", GainValue[i]);
		if(nRet != MV_OK)
		{
    
    
			printf("Warning: Set HDRGain nRet [0x%x]!", nRet);
		}
	}

4.模拟控制/AnalogControl

4.1模拟增益设置

	nRet = MV_CC_SetFloatValue(handle, "Gain", 1;
	if (MV_OK != nRet)
	{
    
    
		printf("Set Gainfail fail nRet [0xd%]\n", nRet);
	}

4.2数字增益设置

	//打开数字增益使能
	nRet = MV_CC_SetBoolValue(handle, "DigitalShiftEnable", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set DigitalShiftEnable fail! nRet [0x%x]\n", nRet);
	}
	//设置数字增益,范围-6~6db
	nRet = MV_CC_SetFloatValue(handle, "DigitalShift", 1);
	if (MV_OK != nRet)
	{
    
    
		printf("Set DigitalShift fail !nRet [0xd%]\n", nRet);
	}

4.3伽马设置/Gamma

	//1.打开数字增益使能
	nRet = MV_CC_SetBoolValue(handle, "GammaEnable", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set GammaEnable fail! nRet [0x%x]\n", nRet);
	}
	//2.设置gamma类型,user:1,sRGB:2
	nRet = MV_CC_SetEnumValue(handle, "GammaSelector", 1);
	if (MV_OK != nRet)
	{
    
    
		printf("Set GammaSelector fail! nRet [0x%x]\n", nRet);
	}
	//3.设置gamma值,推荐范围0.5-2,1为线性拉伸
	nRet = MV_CC_SetFloatValue(handle, "Gamma", 1);
	if (MV_OK != nRet)
	{
    
    
		printf("Set Gamma failed! nRet [0xd%]\n", nRet);
	}

4.4锐度设置/Sharpness

4.4.1相机锐度设置

工业相机本身内部处理,支持锐度设置(相机硬件ISP处理)
锐度需要注意相机图像格式,例如YUV、RGB、MONO10、MONO12等格式就不支持锐度,就需要通过其他方式实现

	//打开锐度使能
	nRet = MV_CC_SetBoolValue(handle, "SharpnessEnable", true);
	if (MV_OK != nRet)
	{
    
    
		printf("Set SharpnessEnable failed! nRet [0x%x]\n", nRet);
	}
	//设置锐度,范围0-100
	nRet = MV_CC_SetFloatValue(handle, "Sharpness", 1);
	if (MV_OK != nRet)
	{
    
    
		printf("Set Sharpness failed nRet [0xd%]\n", nRet);
	}

4.4.2SDK锐度设置

当相机硬件在某些情况不支持锐度处理时,海康SDK提供了软件层面的锐度接口调用
仅支持mono8格式与RGB格式,其他图像格式需要先行转化成这两种格式

static  unsigned int __stdcall WorkThread(void* pUser)
{
    
    
    int nRet = MV_OK;
	unsigned char *pConvertData = NULL;
	unsigned char *pSharpenData = NULL;
    unsigned int nConvertDataSize = 0;
    MV_FRAME_OUT stImageInfo = {
    
    0};					//图像帧信息结构体
    MV_DISPLAY_FRAME_INFO stDisplayInfo = {
    
    0};		//用于显示的
	MV_CC_PIXEL_CONVERT_PARAM stConvertParam = {
    
    0}; //用于格式转化的
	MV_CC_SHARPEN_PARAM stSharpenParam ={
    
    0};	    //用于锐度的
    while(1)
    {
    
    
        nRet = MV_CC_GetImageBuffer(pUser, &stImageInfo, 1000);//取一帧图像
        if (nRet == MV_OK)
        {
    
    
            printf("Get Image Buffer: Width[%d], Height[%d], FrameNum[%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};
            //如果是彩色则转成RGB8
            //isColor,isMono函数,看相机图像格式介绍章节
            if (IsColor(stImageInfo.stFrameInfo.enPixelType))//判断相机图像原始数据格式是什么
            {
    
    
                nChannelNum = 3;
                enDstPixelType = PixelType_Gvsp_RGB8_Packed;
                sprintf(chFileName, "AfterConvert.rgb");
            }
            //如果是黑白则转换成Mono8
            else 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)
            {
    
    
				if (NULL == pConvertData)
				{
    
    
				//分配一块区域用于格式转化
					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 
              
                stConvertParam.nWidth = stImageInfo.stFrameInfo.nWidth;                 //ch:图像宽 | en:image width
                stConvertParam.nHeight = stImageInfo.stFrameInfo.nHeight;               //ch:图像高 | en:image height
                stConvertParam.pSrcData = stImageInfo.pBufAddr;                         //ch:输入数据缓存 | en:input data buffer
                stConvertParam.nSrcDataLen = stImageInfo.stFrameInfo.nFrameLen;         //ch:输入数据大小 | en:input data size
                stConvertParam.enSrcPixelType = stImageInfo.stFrameInfo.enPixelType;    //ch:输入像素格式 | en:input pixel format
                stConvertParam.enDstPixelType = enDstPixelType;                         //ch:输出像素格式 | en:output pixel format
                stConvertParam.pDstBuffer = pConvertData;                               //ch:输出数据缓存 | en:output data buffer
                stConvertParam.nDstBufferSize = nConvertDataSize;                       //ch:输出缓存大小 | en:output buffer size
                nRet = MV_CC_ConvertPixelType(pUser, &stConvertParam);//图像格式转化
                if (MV_OK != nRet)
                {
    
    
                    printf("Convert Pixel Type fail! nRet [0x%x]\n", nRet);
                    break;
				}else
				{
    
    
					 printf("Convert Pixel Type ok!\n");
				}		
			}
			if(g_Sharpen)//全局变量,用于判断要不要做锐化
			{
    
    
				if (NULL == pSharpenData)
				{
    
    
					pSharpenData = (unsigned char*)malloc(stImageInfo.stFrameInfo.nWidth * stImageInfo.stFrameInfo.nHeight * nChannelNum);
					if (NULL == pSharpenData)
					{
    
    
						printf("malloc pConvertData fail!\n");
						nRet = MV_E_RESOURCE;
						break;
					}
				}
				stSharpenParam.nWidth = stImageInfo.stFrameInfo.nWidth;
				stSharpenParam.nHeight = stImageInfo.stFrameInfo.nHeight;
				stSharpenParam.enPixelType = enDstPixelType;				//像素格式变化,用转化后的图像格式传入
				stSharpenParam.pSrcBuf = stConvertParam.pDstBuffer;			//输入
				stSharpenParam.nSrcBufLen = stConvertParam.nDstBufferSize;//数据大小变化
				stSharpenParam.pDstBuf = pSharpenData;						//输出,后续处理要用这个数据啦
				stSharpenParam.nDstBufSize = stConvertParam.nDstBufferSize;	//数据大小变化
				stSharpenParam.nSharpenAmount = m_nSharpenAmount;
				stSharpenParam.nSharpenRadius = m_nSharpenRadius;
				stSharpenParam.nSharpenThreshold = m_nSharpenThreshold;
				nRet = MV_CC_ImageSharpen(pUser, &stSharpenParam);
				if (MV_OK != nRet)
				{
    
    
					printf("Image Sharpen fail! nRet [0x%x]\n", nRet);
					break;
				}else
				{
    
    
					 printf("Sharpen :50 ok!\n");
				}
			}
			T2=qMyMilliseconds();//计时函数,可以删除
			printf("Grab ok!,costtime:%f\n",T2-T1);
            if (g_hwnd)
            {
    
    
                stDisplayInfo.hWnd = g_hwnd;
                stDisplayInfo.pData = pSharpenData;
                stDisplayInfo.nDataLen = nConvertDataSize;
                stDisplayInfo.nWidth = stImageInfo.stFrameInfo.nWidth;
                stDisplayInfo.nHeight = stImageInfo.stFrameInfo.nHeight;
                stDisplayInfo.enPixelType = enDstPixelType;//像素格式变化
                nRet =MV_CC_DisplayOneFrame(pUser, &stDisplayInfo);
            }
			MV_SAVE_IMG_TO_FILE_PARAM stSaveFileParam;//存图测试,可以删除,不调用
			memset(&stSaveFileParam, 0, sizeof(MV_SAVE_IMG_TO_FILE_PARAM));
			stSaveFileParam.enImageType = MV_Image_Bmp; // ch:需要保存的图像类型 | en:Image format to save
			stSaveFileParam.enPixelType = enDstPixelType;  // ch:相机对应的像素格式 | en:Camera pixel type
			stSaveFileParam.nWidth      = stImageInfo.stFrameInfo.nWidth;         // ch:相机对应的宽 | en:Width
			stSaveFileParam.nHeight     = stImageInfo.stFrameInfo.nHeight;          // ch:相机对应的高 | en:Height
			stSaveFileParam.nDataLen    = nConvertDataSize;
			stSaveFileParam.pData       = pSharpenData;
			stSaveFileParam.iMethodValue = 0;
			 // ch:jpg图像质量范围为(50-99], png图像质量范围为[0-9] | en:jpg image nQuality range is (50-99], png image nQuality range is [0-9]
			if (MV_Image_Bmp == stSaveFileParam.enImageType)
			{
    
    
				sprintf_s(stSaveFileParam.pImagePath, 256, "Image_w%d_h%d_fn%03d_%d_%d_%d.bmp", stSaveFileParam.nWidth, stSaveFileParam.nHeight, stImageInfo.stFrameInfo.nFrameNum,m_nSharpenAmount,m_nSharpenAmount,m_nSharpenThreshold);
			}
			nRet = MV_CC_SaveImageToFile(pUser,&stSaveFileParam);
			if(nRet != MV_OK)
            {
    
    
                printf("MV_CC_SaveImageToFile fail! nRet [0x%x]\n", nRet);
            }else
				{
    
    
					 printf("MV_CC_SaveImageToFile  ok!\n");
				}

            nRet = MV_CC_FreeImageBuffer(pUser, &stImageInfo);
            if(nRet != MV_OK)
            {
    
    
                printf("Free Image Buffer fail! nRet [0x%x]\n", nRet);
            }
        }
        else
        {
    
    
            //printf("Get Image fail! nRet [0x%x]\n", nRet);
        }
        if(g_bExit)
        {
    
    
            break;
        }
    }

    return 0;
}

4.5白平衡设置/BalanceWhiteAuto

4.5.1 自动白平衡

	//开启自动白平衡
	nRet = MV_CC_SetEnumValue(handle, "BalanceWhiteAuto", 1);
	if (MV_OK != nRet)
	{
    
    
		printf("Set BalanceWhiteAuto  fail! nRet [0x%x]\n", nRet);
	}
	//取流之后,自动白平衡采集一段时间,相机自动调整
	//调整完毕后后,关闭自动白平衡,即可
	sleep(2000);
	//关闭自动白平衡
	nRet = MV_CC_SetEnumValue(handle, "BalanceWhiteAuto", 0);
	if (MV_OK != nRet)
	{
    
    
		printf("Set BalanceWhiteAuto  fail! nRet [0x%x]\n", nRet);
	}

4.5.2 手动白平衡

	//关闭自动白平衡
	nRet = MV_CC_SetEnumValue(handle, "BalanceWhiteAuto", 0);
	if (MV_OK != nRet)
	{
    
    
		printf("Set BalanceWhiteAuto  fail! nRet [0x%x]\n", nRet);
		break;
	}
	//手动白平衡设置
	int BalanceRatio_Value[3]={
    
    1100,1024,1800};//R、G、B
	for (int i = 0; i < 3; i++)
	{
    
    
		nRet = MV_CC_SetEnumValue(handle, "BalanceRatioSelector", i);
		nRet = MV_CC_SetIntValue(handle, "BalanceRatio",BalanceRatio_Value[i]);
	}

5.数字IO控制/DigitalIOControl

5.1IO输出控制

相机IO控制,主要用于控制IO信号输出,详情参考文章IO输出部分:海康工业相机功能模块-IO输入输出控制

5.2IO输出输出事件介绍

IO输出也可以由相机控制,在相机工作的不同的时间段,给出一个输出信号,控制外部设备,海康工业相机支持的IO事件包括如下几种

事件源名称 关键词 参数值 功能说明
曝光开始 ExposureStartActive 0 sensor开始曝光时,输出信号
采集开始 AcquisitionStartActive 1 数据开始读出时输出信号,帧读出开始时刻
采集结束 AcquisitionStopActive 2 数据结束读出时输出信号,帧读出结束时刻
出图开始 FrameBurstStartActive 3 图像数据开始通过链路发送时刻输出信号,brust>2才有信号输出,往往没啥用
出图结束 FrameBurstEndActive 4 图像数据通过链路发送结束时刻输出信号,brust>2才有信号输出,往往没啥用
软触发输出 SoftTriggerActive 5 软件调用command命令时刻,输出,用户自主可控
硬触发输出 HardTriggerActive 6 相机输入信号line0\2收到输入信号时,输出一个输出信号
计数器输出 TimerActive 7 计时器,计算line0、line2收到指定信号个数,输出一个输出信号
触发等待输出 FrameTriggerWait 8 相机可以被触发,可以曝光采集时,触发信号

常用的有曝光开始、软触发输出、硬触发输出
举例:

	//参数初始化
	nRet = MV_CC_SetEnumValue(handle, "LineSelector", 2);	//选择对应的硬件输出源
	//0:Line0 1:Line1 2:Line2 
	nRet = MV_CC_SetEnumValue(handle, "LineMode", 8);		//仅line2需要设置
	//0:Input 1:Output 8:Strobe 
	nRet = MV_CC_SetEnumValue(handle, "LineSource", 5);
	//0:ExposureStartActive 5:SoftTriggerActive  6:HardTriggerActive
	int DurationValue=1000,DelayValue=100,PreDelayValue=0;//us
	nRet = MV_CC_SetIntValue(handle, "StrobeLineDuration",DurationValue);//脉宽持续时间
	nRet = MV_CC_SetIntValue(handle, "StrobeLineDelay",DelayValue);//strobe延时,从曝光开始,延时多久输出
	nRet = MV_CC_SetIntValue(handle, "StrobeLinePreDelay",PreDelayValue);//strobe提前输出,曝光延后开始
	nRet = MV_CC_SetBoolValue(handle, "StrobeEnable",TRUE);
//Strobe输出使能,使能之后,上面配置参数生效,IO输出与LineSource同步
//-------------------------------------------------------------------------------------
//输出IO信号命令,需要时,调用此行代码,相机通过line2输出一个周期1100us的方波,有效脉宽1000us
nRet = MV_CC_SetCommandValue(m_handle, "LineTriggerSoftware");

6.动作命令控制/ActionControl

7.文件访问控制/FileAccessControl

8.事件监视/EventControl

8.1曝光结束时间

9.数据块控制/ChunkDataControl

10.传输层控制/TransportLayerControl

10.1心跳时间设置

//mv_cc_Opendevice之后调用
//推荐值3000-60000ms,不建议低于3000ms,容易掉线
nRet = MV_CC_SetIntValue(handle,"GevHeartbeatTimeout",3000);//单位ms
if(nRet != MV_OK)
{
    
    
	printf("Warning: Set Width  fail nRet [0x%x]!", nRet);
}

11.用户集控制/UserSetControl

11.1保存参数到相机

保存参数到userset,确保相机掉电后,参数不消失

//初始化部分,放在Opendevice之后即可
nRet = MV_CC_SetEnumValue(handle, "UserSetSelector", 1);//支持1、2、3组,3组不同参数保存
if (MV_OK != nRet)
{
    
    
	printf("error: SetEnumValue UserSetSelector fail [%x]\n", nRet);
}
nRet = MV_CC_SetEnumValue(handle, "UserSetDefault", 1);//选择上电后,默认加载那一组参数
if (MV_OK != nRet)
{
    
    
	printf("error: SetEnumValue UserSetDefault fail [%x]\n", nRet);
}
//大部分参数修改完成后,调用此命令进行保存,不建议频繁调用
nRet = MV_CC_SetCommandValue(m_handle, "UserSetSave");//保存命令
if (MV_OK != nRet)
{
    
    
	printf("error: SetCommandValue fail [%x]\n", nRet);
}

11.2恢复出厂默认参数

//相机停止采集后才能调用
nRet = MV_CC_SetEnumValue(handle, "UserSetSelector", 0);//1、2、3是用户自己保存的参数,0是相机出厂参数
if (MV_OK != nRet)
{
    
    
	printf("error: SetEnumValue UserSetSelector fail [%x]\n", nRet);
}
nRet = MV_CC_SetCommandValue(m_handle, "UserSetLoad");//加载0组参数
if (MV_OK != nRet)
{
    
    
	printf("error: SetCommandValue fail [%x]\n", nRet);
}

猜你喜欢

转载自blog.csdn.net/qq_23107577/article/details/121077409