From 600234883aae5b91a544d08981af9821f4620df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Castro?= Date: Fri, 9 Feb 2024 13:03:44 -0300 Subject: [PATCH] Add option to set image width and height in the UI --- demos/multi_camera/demo.py | 14 ++++++++++ norfair/common_reference_ui.py | 51 ++++++++++++++++++++++++++-------- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/demos/multi_camera/demo.py b/demos/multi_camera/demo.py index 14b6039b..c0c9ef14 100644 --- a/demos/multi_camera/demo.py +++ b/demos/multi_camera/demo.py @@ -166,6 +166,18 @@ def run(): default=[360, 288], help="Output resolution for each subblock", ) + parser.add_argument( + "--ui-width", + type=int, + default=None, + help="Image width in the UI", + ) + parser.add_argument( + "--ui-height", + type=int, + default=None, + help="Image height in the UI", + ) parser.add_argument( "--use-motion-estimator-footage", action="store_true", @@ -345,6 +357,8 @@ def mask_generator(frame): motion_estimator_footage=motion_estimator_footage, motion_estimator_reference=motion_estimator_reference, mask_generator=mask_generator, + image_width=args.ui_width, + image_height=args.ui_height, ) if args.save_transformation: with open(pickle_path, "wb") as file: diff --git a/norfair/common_reference_ui.py b/norfair/common_reference_ui.py index 633b6652..ed9705e3 100644 --- a/norfair/common_reference_ui.py +++ b/norfair/common_reference_ui.py @@ -44,12 +44,24 @@ global button_ignore +def resize_image(image, desired_width=None, desired_height=None): + aspect_ratio = image.height / image.width + + if (desired_width is None) and (desired_height is not None): + desired_width = int(desired_height / aspect_ratio) + elif (desired_width is not None) and (desired_height is None): + desired_height = int(aspect_ratio * desired_width) + + return image.resize((desired_width, desired_height), Image.LANCZOS) + + def set_reference( reference: str, footage: str, transformation_getter: TransformationGetter = None, mask_generator=None, - desired_size=700, + image_width=None, + image_height=None, motion_estimator_footage=None, motion_estimator_reference=None, ): @@ -88,8 +100,11 @@ def set_reference( - mask_generator: optional function that creates a mask (np.ndarray) from a PIL image. This mask is then provided to the corresponding MotionEstimator to avoid sampling points within the mask. - - desired_size: int, optional - How large you want the clickable windows in the UI to be. + - image_width: int, optional + Width of the image of the UI. If the height is not provided, then it will be calculated so that the aspect ratio is preserved. + + - image_height: int, optional + Height of the image of the UI. If the width is not provided, then it will be calculated so that the aspect ratio is preserved. - motion_estimator_footage: MotionEstimator, optional When using videos for the footage, you can provide a MotionEstimator to relate the coordinates in all the frames in the video. @@ -149,7 +164,13 @@ def set_reference( skipper = {} - radius = max(int(desired_size / 100), 1) + radius = None + if (image_width is None) and (image_height is None): + image_height = 450 + elif (image_width is not None) and (image_height is None): + radius = max(int(image_width / 100), 1) + if radius is None: + radius = max(int(image_height / 100), 1) points = {} points_sampled = len(points) @@ -412,7 +433,8 @@ def handle_annotation(event): footage_original_height = image.height footage_original_size = (footage_original_width, footage_original_height) - image.thumbnail((desired_size, desired_size)) + image = resize_image(image, desired_width=image_width, desired_height=image_height) + footage_photo = ImageTk.PhotoImage(image) footage_canvas_width = footage_photo.width() footage_canvas_height = footage_photo.height() @@ -420,8 +442,8 @@ def handle_annotation(event): canvas_footage = tk.Canvas( frame_images, - width=footage_photo.width(), - height=footage_photo.height(), + width=footage_canvas_width, + height=footage_canvas_height, bg="gray", ) footage_image_container = canvas_footage.create_image( @@ -516,7 +538,8 @@ def reference_coord_chosen_in_footage(event): reference_original_height = image.height reference_original_size = (reference_original_width, reference_original_height) - image.thumbnail((desired_size, desired_size)) + image = resize_image(image, desired_width=image_width, desired_height=image_height) + reference_photo = ImageTk.PhotoImage(image) reference_canvas_width = reference_photo.width() reference_canvas_height = reference_photo.height() @@ -524,8 +547,8 @@ def reference_coord_chosen_in_footage(event): canvas_reference = tk.Canvas( frame_images, - width=reference_photo.width(), - height=reference_photo.height(), + width=reference_canvas_width, + height=reference_canvas_height, bg="gray", ) reference_image_container = canvas_reference.create_image( @@ -650,7 +673,9 @@ def handle_reset_video(event): skipper[video_type]["current_frame"] = 1 image = Image.fromarray(image) - image.thumbnail((desired_size, desired_size)) + image = resize_image( + image, desired_width=image_width, desired_height=image_height + ) image = ImageTk.PhotoImage(image) skipper[video_type]["canvas"].itemconfig( @@ -710,7 +735,9 @@ def handle_skip_frame(event): if change_image: image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)) - image.thumbnail((desired_size, desired_size)) + image = resize_image( + image, desired_width=image_width, desired_height=image_height + ) image = ImageTk.PhotoImage(image) skipper[video_type]["canvas"].itemconfig(