控制球机光轴运动到具体坐标的两种方式:设置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)