Use absolute instead of relative zooming

This commit is contained in:
Josh Hawkins 2023-09-02 17:25:36 -05:00
parent c6970c9d78
commit 26347ed23a
2 changed files with 27 additions and 41 deletions

View File

@ -230,8 +230,8 @@ class PtzAutoTracker:
continue continue
else: else:
if abs(zoom) > 0: if zoom > 0:
self.onvif._zoom_relative(camera, zoom, 1) self.onvif._zoom_absolute(camera, zoom, 1)
# on some cameras with cheaper motors it seems like small values can cause jerky movement # on some cameras with cheaper motors it seems like small values can cause jerky movement
# TODO: double check, might not need this # TODO: double check, might not need this
@ -290,16 +290,16 @@ class PtzAutoTracker:
# ensure zooming level is in range # ensure zooming level is in range
# if so, check if bounding box is 10% of an edge # if so, check if bounding box is 10% of an edge
# if so, try zooming in, otherwise try zooming out # if so, try zooming in, otherwise try zooming out
if -1 <= zoom_level < 1: if 0 < zoom_level <= 1:
if ( if (
bb_left > 0.1 * camera_width bb_left > 0.1 * camera_width
and bb_right < 0.9 * camera_width and bb_right < 0.9 * camera_width
and bb_top > 0.1 * camera_height and bb_top > 0.1 * camera_height
and bb_bottom < 0.9 * camera_height and bb_bottom < 0.9 * camera_height
): ):
zoom = 0.1 # Zoom in zoom = min(1.0, zoom_level + 0.1)
else: else:
zoom = -0.1 # Zoom out zoom = max(0.0, zoom_level - 0.1)
self._enqueue_move(camera, obj.obj_data["frame_time"], 0, 0, zoom) self._enqueue_move(camera, obj.obj_data["frame_time"], 0, 0, zoom)

View File

@ -140,7 +140,7 @@ class OnvifController:
move_request.Speed = ptz.GetStatus({"ProfileToken": profile.token}).Position move_request.Speed = ptz.GetStatus({"ProfileToken": profile.token}).Position
self.cams[camera_name]["relative_move_request"] = move_request self.cams[camera_name]["relative_move_request"] = move_request
# setup relative moving request for autotracking # setup absolute moving request for autotracking zooming
move_request = ptz.create_type("AbsoluteMove") move_request = ptz.create_type("AbsoluteMove")
move_request.ProfileToken = profile.token move_request.ProfileToken = profile.token
self.cams[camera_name]["absolute_move_request"] = move_request self.cams[camera_name]["absolute_move_request"] = move_request
@ -175,9 +175,12 @@ class OnvifController:
if ptz_config.Spaces and ptz_config.Spaces.RelativeZoomTranslationSpace: if ptz_config.Spaces and ptz_config.Spaces.RelativeZoomTranslationSpace:
supported_features.append("zoom-r") supported_features.append("zoom-r")
if ptz_config.Spaces and ptz_config.Spaces.AbsoluteZoomPositionSpace:
supported_features.append("zoom-a")
self.cams[camera_name][ self.cams[camera_name][
"relative_zoom_range" "absolute_zoom_range"
] = ptz_config.Spaces.RelativeZoomTranslationSpace[0] ] = ptz_config.Spaces.AbsoluteZoomPositionSpace[0]
self.cams[camera_name]["zoom_limits"] = configs.ZoomLimits self.cams[camera_name]["zoom_limits"] = configs.ZoomLimits
if fov_space_id is not None: if fov_space_id is not None:
@ -335,12 +338,12 @@ class OnvifController:
onvif.get_service("ptz").ContinuousMove(move_request) onvif.get_service("ptz").ContinuousMove(move_request)
def _zoom_relative(self, camera_name: str, zoom, speed) -> None: def _zoom_absolute(self, camera_name: str, zoom, speed) -> None:
if "zoom-r" not in self.cams[camera_name]["features"]: if "zoom-a" not in self.cams[camera_name]["features"]:
logger.error(f"{camera_name} does not support ONVIF RelativeMove zooming.") logger.error(f"{camera_name} does not support ONVIF AbsoluteMove zooming.")
return return
logger.debug(f"{camera_name} called RelativeMove: zoom: {zoom}") logger.debug(f"{camera_name} called AbsoluteMove: zoom: {zoom}")
if self.cams[camera_name]["active"]: if self.cams[camera_name]["active"]:
logger.warning( logger.warning(
@ -356,30 +359,24 @@ class OnvifController:
].value = datetime.datetime.now().timestamp() ].value = datetime.datetime.now().timestamp()
self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0 self.ptz_metrics[camera_name]["ptz_stop_time"].value = 0
onvif: ONVIFCamera = self.cams[camera_name]["onvif"] onvif: ONVIFCamera = self.cams[camera_name]["onvif"]
move_request = self.cams[camera_name]["relative_move_request"] move_request = self.cams[camera_name]["absolute_move_request"]
# function takes in -1 to 1 for zoom, interpolate to the relative values of the camera. # function takes in 0 to 1 for zoom, interpolate to the values of the camera.
zoom = numpy.interp( zoom = numpy.interp(
zoom, zoom,
[-1, 1], [0, 1],
[ [
self.cams[camera_name]["relative_zoom_range"]["XRange"]["Min"], self.cams[camera_name]["absolute_zoom_range"]["XRange"]["Min"],
self.cams[camera_name]["relative_zoom_range"]["XRange"]["Max"], self.cams[camera_name]["absolute_zoom_range"]["XRange"]["Max"],
], ],
) )
move_request.Speed = {"Zoom": speed} move_request.Speed = {"Zoom": speed}
move_request.Position = {"Zoom": zoom}
move_request.Translation.PanTilt.x = 0 logger.debug(f"Absolute zoom: {zoom}")
move_request.Translation.PanTilt.y = 0
move_request.Translation.Zoom.x = zoom
logger.debug(f"Relative zoom: {zoom}") onvif.get_service("ptz").AbsoluteMove(move_request)
onvif.get_service("ptz").RelativeMove(move_request)
# reset after the move request
move_request.Translation.Zoom.x = 0
self.cams[camera_name]["active"] = False self.cams[camera_name]["active"] = False
@ -462,21 +459,10 @@ class OnvifController:
if self.config.cameras[camera_name].onvif.autotracking.zooming: if self.config.cameras[camera_name].onvif.autotracking.zooming:
# interpolate the actual zoom level reported by the camera into the relative zoom range # interpolate the actual zoom level reported by the camera into the relative zoom range
self.ptz_metrics[camera_name]["ptz_zoom_level"].value = numpy.interp( self.ptz_metrics[camera_name][
status.Position.Zoom.x, "ptz_zoom_level"
[ ].value = status.Position.Zoom.x
self.cams[camera_name]["zoom_limits"]["Range"]["XRange"]["Min"], logger.debug(f"Camera zoom level: {status.Position.Zoom.x}")
self.cams[camera_name]["zoom_limits"]["Range"]["XRange"]["Max"],
],
[
self.cams[camera_name]["relative_zoom_range"]["XRange"]["Min"],
self.cams[camera_name]["relative_zoom_range"]["XRange"]["Max"],
],
)
logger.debug(f"Actual zoom level: {status.Position.Zoom.x}")
logger.debug(
f"Relative zoom level: {self.ptz_metrics[camera_name]['ptz_zoom_level'].value}"
)
return { return {
"pan": status.Position.PanTilt.x, "pan": status.Position.PanTilt.x,