海康球机控制函数VC (PTZ控制+对准具体坐标点)

    控制球机光轴运动到具体坐标的两种方式:设置PTZ参数方法、调用球机3D定位功能。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

【设置PTZ参数方法】

主要利用两个函数:设置参数NET_DVR_SetDVRConfig函数与读取参数NET_DVR_GetDVRConfig函数。

NET_DVR_SetDVRConfig(LONG lUserID, DWORD dwCommand,LONG lChannel, LPVOID lpInBuffer, DWORD dwInBufferSize);

NET_DVR_GetDVRConfig(LONG lUserID, DWORD dwCommand,LONG lChannel, LPVOID lpOutBuffer, DWORD dwOutBufferSize, LPDWORD lpBytesReturned);

函数示例:

1.位置坐标转换为角度+进制转换+设置参数

//PTZ参数求取
focus_adjust = 10;//焦距

y_degree = (target_y - std_rows / 2.0) > 0 ? -atan(-(std_rows / 2.0 - target_y) / (std_rows / 2) * tan(21.8 / 180 * PI)) * 180 / PI : atan(-(target_y - std_rows / 2.0) / (std_rows / 2) * tan(21.8 / 180 * PI)) * 180 / PI;

z_degree = ((target_x - std_cols / 2.0) > 0) ? atan((target_x - std_cols / 2.0) / (std_cols / 2) * tan(29.15 / 180 * PI)) * 180 / PI : (360 - atan((std_cols / 2.0 - target_x) / (std_cols / 2) * tan(29.15 / 180 * PI)) * 180 / PI);
		
z_degree = ((z_degree < 100) ? -z_degree : 360 - z_degree);

z_degree += 279;//补上球机初始角度
y_degree += 10;//补上球机初始角度

NET_DVR_PTZPOS m_ptzPos;
		
m_ptzPos.wAction = 1;
int z_idegree = z_degree * 10;
int y_idegree = y_degree * 10;
//进制转换
m_ptzPos.wPanPos = DEC2HEX_doc(z_idegree);
m_ptzPos.wTiltPos = DEC2HEX_doc(y_idegree);
m_ptzPos.wZoomPos = DEC2HEX_doc(focus_adjust);
//设置PTZ参数
if (!NET_DVR_SetDVRConfig(0, NET_DVR_SET_PTZPOS, 0, &m_ptzPos, sizeof(NET_DVR_PTZPOS))){
			auto a = NET_DVR_GetLastError();
			CString s; 
			s.Format("%d", a);
			AfxMessageBox(s);
		}

2.实时读取球机PTZ参数+判断是否完成设置

//判断是否完成移动
	NET_DVR_PTZPOS Pos_judge;
	Pos_judge.wAction = 1;
	DWORD tmp = 0;
	int flags_tmp=1;
	while (flags_tmp)
	{
		if (!NET_DVR_GetDVRConfig(0, NET_DVR_GET_PTZPOS, 0, &Pos_judge, sizeof(NET_DVR_PTZPOS), &tmp))
		{
			auto a = NET_DVR_GetLastError();
			CString s;
			s.Format("%d", a);
			AfxMessageBox(s);
		}
		else if(Pos_judge.wPanPos == m_ptzPos.wPanPos && Pos_judge.wTiltPos == m_ptzPos.wTiltPos && Pos_judge.wZoomPos == m_ptzPos.wZoomPos)
		{
			flags_tmp = 0;
		}
	}

备注:设置PTZ参数是一个并行过程,如果不加入结束判断,读取球机画面时将不是所设定参数状态下的图片,而是PTZ调整过程中的某一张图片。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

【调用球机3D定位功能】

主要包括两个函数:NET_DVR_PTZSelZoomIn与NET_DVR_PTZSelZoomIn_EX,两个参数不同但功能一样。

NET_DVR_PTZSelZoomIn(LONG lRealHandle, LPNET_DVR_POINT_FRAME pStruPointFrame);
NET_DVR_PTZSelZoomIn_EX(LONG lUserID, LONG lChannel, LPNET_DVR_POINT_FRAME pStruPointFrame);

参数介绍:

[in]lRealHandle                         NET_DVR_RealPlay或者NET_DVR_RealPlay_V30的返回值
[in]pStruPointFrame                 云台图像区域位置信息

[in]lUserID                                NET_DVR_Login_V40 的返回值
[in]lChannel                              通道号
[in]pStruPointFrame                 云台图像区域位置信息
 

//NET_DVR_POINT_FRAME
//云台图像区域位置信息。

struct{
  int    xTop;
  int    yTop;
  int    xBottom;
  int    yBottom;
  int    bCounter;
}NET_DVR_POINT_FRAME, *LPNET_DVR_POINT_FRAME;
Members
//xTop 方框起始点的x坐标 
//yTop 方框起始点的y坐标 
//xBottom 方框结束点的x坐标 
//yBottom 方框结束点的y坐标 
//bCounter 保留 



返回值: TRUE 表示成功,FALSE 表示失败。接口返回失败请调用NET_DVR_GetLastError 获取错误码,通
过错误码判断出错原因。


功能说明:该结构体中的坐标值与当前预览显示框的大小有关,现假设预览显示框为352*288,我们规定原点为预览显示框左上角的顶点,前四个参数计算方法如下:
xTop = 鼠标当前所选区域的起始点坐标的值*255/352;
xBottom = 鼠标当前所选区域的结束点坐标的值*255/352;
yTop = 鼠标当前所选区域的起始点坐标的值*255/288;
yBottom = 鼠标当前所选区域的结束点坐标的值*255/288;
缩小条件:xTop减去xBottom的值大于2。放大条件:xTop小于xBottom。

函数示例:

NET_DVR_POINT_FRAME  posdata;
	
posdata.xTop = (int)(target_tmp.x * 255 / std_cols );
	
posdata.xBottom = posdata.xTop ;// (int)((target_tmp.x + target_tmp.width) / std_cols * 255);
	
posdata. yTop = (int)(target_tmp.y * 255 / std_rows);

posdata.yBottom = posdata.yTop  ;// (int)((target_tmp.y + target_tmp.height) / std_rows * 255);

posdata.bCounter = 1;

if (!NET_DVR_PTZSelZoomIn_EX(0, 1, &posdata)){
	auto a = NET_DVR_GetLastError();
	CString s;
	s.Format("%d", a);
	AfxMessageBox(s);
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

【总结】

第一种方法某种意义上是第二种方法的开源版本,但坐标到角度的转换方法因人而异,误差也因人而异;而自带的3D功能坐标对准十分准确,效果很好,但这同样是一个并行过程,同时还不知道函数内部具体参数值,不能有效判断结束标志,所以为后续指令操作带来一个时间上的问题。

倘若大家有更好的球机对准方法,欢迎交流讨论。

如若有以下两个函数的开源代码,望大家能够分享,一起学习。

(NET_DVR_PTZSelZoomIn与NET_DVR_PTZSelZoomIn_EX)

猜你喜欢

转载自blog.csdn.net/leexin95/article/details/81131902