@@ -677,98 +677,6 @@ def to_display_pixmap(frame: np.ndarray) -> QPixmap:
677677 q_img = QImage (frame .data , w , h , bytes_per_line , QImage .Format .Format_RGB888 ).copy ()
678678 return QPixmap .fromImage (q_img )
679679
680- def _create_tiled_frame (self ) -> np .ndarray :
681- """Create a tiled frame from all camera frames.
682-
683- The tiled frame is scaled to fit within a maximum canvas size
684- while maintaining aspect ratio of individual camera frames.
685- """
686- if not self ._frames :
687- return np .zeros ((480 , 640 , 3 ), dtype = np .uint8 )
688-
689- frames_list = [self ._frames [idx ] for idx in sorted (self ._frames .keys ())]
690- num_frames = len (frames_list )
691-
692- if num_frames == 0 :
693- return np .zeros ((480 , 640 , 3 ), dtype = np .uint8 )
694-
695- # Determine grid layout
696- if num_frames == 1 :
697- rows , cols = 1 , 1
698- elif num_frames == 2 :
699- rows , cols = 1 , 2
700- elif num_frames <= 4 :
701- rows , cols = 2 , 2
702- else :
703- rows , cols = 2 , 2 # Limit to 4
704-
705- # Maximum canvas size to fit on screen (leaving room for UI elements)
706- max_canvas_width = 1200
707- max_canvas_height = 800
708-
709- # Calculate tile size based on frame aspect ratio and available space
710- first_frame = frames_list [0 ]
711- frame_h , frame_w = first_frame .shape [:2 ]
712- frame_aspect = frame_w / frame_h if frame_h > 0 else 1.0
713-
714- # Calculate tile dimensions that fit within the canvas
715- tile_w = max_canvas_width // cols
716- tile_h = max_canvas_height // rows
717-
718- # Maintain aspect ratio of original frames
719- tile_aspect = tile_w / tile_h if tile_h > 0 else 1.0
720-
721- if frame_aspect > tile_aspect :
722- # Frame is wider than tile slot - constrain by width
723- tile_h = int (tile_w / frame_aspect )
724- else :
725- # Frame is taller than tile slot - constrain by height
726- tile_w = int (tile_h * frame_aspect )
727-
728- # Ensure minimum size
729- tile_w = max (160 , tile_w )
730- tile_h = max (120 , tile_h )
731-
732- # Create canvas
733- canvas = np .zeros ((rows * tile_h , cols * tile_w , 3 ), dtype = np .uint8 )
734-
735- # Get sorted camera IDs for consistent ordering
736- cam_ids = sorted (self ._frames .keys ())
737- frames_list = [self ._frames [cam_id ] for cam_id in cam_ids ]
738-
739- # Place each frame in the grid
740- for idx , frame in enumerate (frames_list [: rows * cols ]):
741- row = idx // cols
742- col = idx % cols
743-
744- # Ensure frame is 3-channel
745- frame = MultiCameraController .ensure_color_bgr (frame )
746-
747- # Resize to tile size
748- resized = MultiCameraController .apply_resize (frame , tile_w , tile_h , allow_upscale = True )
749-
750- # Add camera ID label
751- if idx < len (cam_ids ):
752- label = cam_ids [idx ]
753- cv2 .putText (
754- resized ,
755- label ,
756- (10 , 30 ),
757- cv2 .FONT_HERSHEY_SIMPLEX ,
758- 0.7 ,
759- (0 , 255 , 0 ),
760- 2 ,
761- )
762-
763- # Place in canvas
764- y_start = row * tile_h
765- y_end = y_start + tile_h
766- x_start = col * tile_w
767- x_end = x_start + tile_w
768- canvas [y_start :y_end , x_start :x_end ] = resized
769-
770- return canvas
771-
772680 def _on_camera_started (self , camera_id : str ) -> None :
773681 """Handle camera start event."""
774682 self ._started_cameras .add (camera_id )
@@ -831,20 +739,3 @@ def _on_camera_error(self, camera_id: str, message: str) -> None:
831739 if camera_id not in self ._started_cameras :
832740 self ._failed_cameras [camera_id ] = message
833741 self .camera_error .emit (camera_id , message )
834-
835- def get_frame (self , camera_id : str ) -> np .ndarray | None :
836- """Get the latest frame from a specific camera."""
837- with self ._frame_lock :
838- return self ._frames .get (camera_id )
839-
840- def get_all_frames (self ) -> dict [str , np .ndarray ]:
841- """Get the latest frames from all cameras."""
842- with self ._frame_lock :
843- return dict (self ._frames )
844-
845- def get_tiled_frame (self ) -> np .ndarray | None :
846- """Get a tiled view of all camera frames."""
847- with self ._frame_lock :
848- if self ._frames :
849- return self ._create_tiled_frame ()
850- return None
0 commit comments