这是对前一篇《海康球机控制函数VC (PTZ控制+对准具体坐标点)》的补充。
在前一篇文章中介绍的设置PTZ参数法,总是基于最初设定的基准坐标而言的,而不是基于每个当前帧而言的。(可参见前一篇文章https://blog.youkuaiyun.com/leexin95/article/details/81131902)
所以,本文是设置PTZ参数法的改进--基于动态相对量的设置PTZ参数法,用于连续多次地持续的将球机光轴对准目标。
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
【算法思想】
设定参数值 = 当前状态 + 坐标相对量;
获取当前状态下的PTZ参数作为基准,利用当前帧中的坐标位置求取相对PT参数,二者之和即为设置参数值。
【代码实现】
///
NET_DVR_PTZPOS m_ptzPosCurrent;
DWORD dwtmp = 0;
DWORD tmp_zd, tmp_yd;
//获取当前PTZ状态
if (!NET_DVR_GetDVRConfig(0, NET_DVR_GET_PTZPOS, 0, &m_ptzPosCurrent, sizeof(NET_DVR_PTZPOS), &dwtmp)){
auto a = NET_DVR_GetLastError();
CString s;
s.Format("GET:%d", a);
AfxMessageBox(s);
}
//转换为十进制用于运算
tmp_zd = (m_ptzPosCurrent.wPanPos / 4096) * 1000 + ((m_ptzPosCurrent.wPanPos % 4096) / 256) * 100 + ((m_ptzPosCurrent.wPanPos % 256) / 16) * 10 + (m_ptzPosCurrent.wPanPos % 16);
tmp_yd = (m_ptzPosCurrent.wTiltPos / 4096) * 1000 + ((m_ptzPosCurrent.wTiltPos % 4096) / 256) * 100 + ((m_ptzPosCurrent.wTiltPos % 256) / 16) * 10 + (m_ptzPosCurrent.wTiltPos % 16);
tmp_zd = tmp_zd / 10;
tmp_yd = tmp_yd / 10;
tmp_zd %= 360;
tmp_yd %= 360;
/
//计算坐标的相对量
y_degree = (point.y - rt.Height() / 2.0) > 0 ? -atan(-(rt.Height() / 2.0 - point.y) / (rt.Height() / 2) * tan(21.8 / 180 * PI)) * 180 / PI : atan(-(point.y - rt.Height() / 2.0) / (rt.Height() / 2) * tan(21.8 / 180 * PI)) * 180 / PI;
z_degree = ((point.x - rt.Width() / 2.0) > 0) ? atan((point.x - rt.Width() / 2.0) / (rt.Width() / 2) * tan(29.15 / 180 * PI)) * 180 / PI : (360 - atan((rt.Width() / 2.0 - point.x) / (rt.Width() / 2) * tan(29.15 / 180 * PI)) * 180 / PI);
z_degree = ((z_degree < 100) ? -z_degree : 360 - z_degree);
//
//相对量与当前基准叠加
z_degree += tmp_zd;
y_degree += tmp_yd;
//转换为十六进制用于控制球机
NET_DVR_PTZPOS m_ptzPos;
m_ptzPos.wAction = 1;
DWORD z_idegree = z_degree * 10;
DWORD y_idegree = y_degree * 10;
m_ptzPos.wPanPos = (z_idegree / 1000) * 4096 + ((z_idegree % 1000) / 100) * 256 + ((z_idegree % 100) / 10) * 16 + z_idegree % 10;
m_ptzPos.wTiltPos = (y_idegree / 1000) * 4096 + ((y_idegree % 1000) / 100) * 256 + ((y_idegree % 100) / 10) * 16 + y_idegree % 10;
m_ptzPos.wZoomPos =(10/ 1000) * 4096 + ((10 % 1000) / 100) * 256 + ((10 % 100) / 10) * 16 + 10 % 10;
//设置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("SET:%d", a);
AfxMessageBox(s);
}
海康球机demo中自带的3D定位功能是相对量的,改进后的算法与其功能几乎一致,其中调焦策略可以通过
m_ptzPos.wZoomPos =(10/ 1000) * 4096 + ((10 % 1000) / 100) * 256 + ((10 % 100) / 10) * 16 + 10 % 10;
来设定,加入判断即可,可自行发挥。
【总结】
改进后的方法--“基于动态相对量的设置PTZ参数法”,功能与3D定位功能一致,但存在较小的误差(几个像素),其原因可能有以下几个:
1.存在畸变;
2.坐标转换为角度的算法存在一定的误差;
3.球机机械原因,球机PT角度精确到1度,在1度的区间内小幅度的移动是共用一个相同的PT参数。