@@ -540,68 +540,83 @@ def visualize_object_predictions(
540540 # set text_size for category names
541541 text_size = text_size or rect_th / 3
542542
543- # add masks to image if present
543+ # add masks or obb polygons to image if present
544544 for object_prediction in object_prediction_list :
545545 # deepcopy object_prediction_list so that original is not altered
546546 object_prediction = object_prediction .deepcopy ()
547- # visualize masks if present
548- if object_prediction .mask is not None :
549- # deepcopy mask so that original is not altered
550- mask = object_prediction .mask .bool_mask
551- # set color
552- if colors is not None :
553- color = colors (object_prediction .category .id )
554- # draw mask
555- rgb_mask = apply_color_mask (mask , color or (0 , 0 , 0 ))
556- image = cv2 .addWeighted (image , 1 , rgb_mask , 0.6 , 0 )
557-
558- # add bboxes to image if present
559- for object_prediction in object_prediction_list :
560- # deepcopy object_prediction_list so that original is not altered
561- object_prediction = object_prediction .deepcopy ()
562-
563- bbox = object_prediction .bbox .to_xyxy ()
564- category_name = object_prediction .category .name
565- score = object_prediction .score .value
566-
547+ # arange label to be displayed
548+ label = f"{ object_prediction .category .name } "
549+ if not hide_conf :
550+ label += f" { object_prediction .score .value :.2f} "
567551 # set color
568552 if colors is not None :
569553 color = colors (object_prediction .category .id )
570- # set bbox points
571- point1 , point2 = (int (bbox [0 ]), int (bbox [1 ])), (int (bbox [2 ]), int (bbox [3 ]))
572- # visualize boxes
573- cv2 .rectangle (
574- image ,
575- point1 ,
576- point2 ,
577- color = color or (0 , 0 , 0 ),
578- thickness = rect_th ,
579- )
580-
581- if not hide_labels :
582- # arange bounding box text location
583- label = f"{ category_name } "
584-
585- if not hide_conf :
586- label += f" { score :.2f} "
587-
588- box_width , box_height = cv2 .getTextSize (label , 0 , fontScale = text_size , thickness = text_th )[
589- 0
590- ] # label width, height
591- outside = point1 [1 ] - box_height - 3 >= 0 # label fits outside box
592- point2 = point1 [0 ] + box_width , point1 [1 ] - box_height - 3 if outside else point1 [1 ] + box_height + 3
593- # add bounding box text
594- cv2 .rectangle (image , point1 , point2 , color or (0 , 0 , 0 ), - 1 , cv2 .LINE_AA ) # filled
595- cv2 .putText (
554+ # visualize masks or obb polygons if present
555+ has_mask = object_prediction .mask is not None
556+ is_obb_pred = False
557+ if has_mask :
558+ segmentation = object_prediction .mask .segmentation
559+ if len (segmentation ) == 1 and len (segmentation [0 ]) == 8 :
560+ is_obb_pred = True
561+
562+ if is_obb_pred :
563+ points = np .array (segmentation ).reshape ((- 1 , 1 , 2 )).astype (np .int32 )
564+ cv2 .polylines (image , [points ], isClosed = True , color = color or (0 , 0 , 0 ), thickness = rect_th )
565+
566+ if not hide_labels :
567+ lowest_point = points [points [:, :, 1 ].argmax ()][0 ]
568+ box_width , box_height = cv2 .getTextSize (label , 0 , fontScale = text_size , thickness = text_th )[0 ]
569+ outside = lowest_point [1 ] - box_height - 3 >= 0
570+ text_bg_point1 = (lowest_point [0 ], lowest_point [1 ] - box_height - 3 if outside else lowest_point [1 ] + 3 )
571+ text_bg_point2 = (lowest_point [0 ] + box_width , lowest_point [1 ])
572+ cv2 .rectangle (image , text_bg_point1 , text_bg_point2 , color or (0 , 0 , 0 ), thickness = - 1 , lineType = cv2 .LINE_AA )
573+ cv2 .putText (
574+ image ,
575+ label ,
576+ (lowest_point [0 ], lowest_point [1 ] - 2 if outside else lowest_point [1 ] + box_height + 2 ),
577+ 0 ,
578+ text_size ,
579+ (255 , 255 , 255 ),
580+ thickness = text_th ,
581+ )
582+ else :
583+ # draw mask
584+ rgb_mask = apply_color_mask (object_prediction .mask .bool_mask , color or (0 , 0 , 0 ))
585+ image = cv2 .addWeighted (image , 1 , rgb_mask , 0.6 , 0 )
586+
587+ # add bboxes to image if is_obb_pred=False
588+ if not is_obb_pred :
589+ bbox = object_prediction .bbox .to_xyxy ()
590+
591+ # set bbox points
592+ point1 , point2 = (int (bbox [0 ]), int (bbox [1 ])), (int (bbox [2 ]), int (bbox [3 ]))
593+ # visualize boxes
594+ cv2 .rectangle (
596595 image ,
597- label ,
598- (point1 [0 ], point1 [1 ] - 2 if outside else point1 [1 ] + box_height + 2 ),
599- 0 ,
600- text_size ,
601- (255 , 255 , 255 ),
602- thickness = text_th ,
596+ point1 ,
597+ point2 ,
598+ color = color or (0 , 0 , 0 ),
599+ thickness = rect_th ,
603600 )
604601
602+ if not hide_labels :
603+ box_width , box_height = cv2 .getTextSize (label , 0 , fontScale = text_size , thickness = text_th )[
604+ 0
605+ ] # label width, height
606+ outside = point1 [1 ] - box_height - 3 >= 0 # label fits outside box
607+ point2 = point1 [0 ] + box_width , point1 [1 ] - box_height - 3 if outside else point1 [1 ] + box_height + 3
608+ # add bounding box text
609+ cv2 .rectangle (image , point1 , point2 , color or (0 , 0 , 0 ), - 1 , cv2 .LINE_AA ) # filled
610+ cv2 .putText (
611+ image ,
612+ label ,
613+ (point1 [0 ], point1 [1 ] - 2 if outside else point1 [1 ] + box_height + 2 ),
614+ 0 ,
615+ text_size ,
616+ (255 , 255 , 255 ),
617+ thickness = text_th ,
618+ )
619+
605620 # export if output_dir is present
606621 if output_dir is not None :
607622 # export image with predictions
@@ -614,7 +629,7 @@ def visualize_object_predictions(
614629 return {"image" : image , "elapsed_time" : elapsed_time }
615630
616631
617- def get_coco_segmentation_from_bool_mask (bool_mask ) :
632+ def get_coco_segmentation_from_bool_mask (bool_mask : np . ndarray ) -> List [ List [ float ]] :
618633 """
619634 Convert boolean mask to coco segmentation format
620635 [
@@ -712,12 +727,13 @@ def get_coco_segmentation_from_obb_points(obb_points: np.ndarray) -> List[List[f
712727 obb_points: np.ndarray
713728 OBB points tensor from ultralytics.engine.results.OBB
714729 Shape: (4, 2) containing 4 points with (x,y) coordinates each
730+
715731 Returns:
716732 List[List[float]]: Polygon points in COCO format
717- [[x1, y1, x2, y2, x3, y3, x4, y4, x1, y1 ], [...], ...]
733+ [[x1, y1, x2, y2, x3, y3, x4, y4], [...], ...]
718734 """
719735 # Convert from (4,2) to [x1,y1,x2,y2,x3,y3,x4,y4] format
720- points = obb_points .reshape (- 1 ).tolist ()
736+ points = obb_points .reshape (- 1 ).tolist () #
721737
722738 # Create polygon from points and close it by repeating first point
723739 polygons = []
0 commit comments