Arrange a nested list of MxN numpy arrays into a single image grid with column annotations. Args: images (list of list of np.array): Nested list containing the image arrays. annotations (list of str): List of annotations for each column. font (int): Font type for the annotation
(images, annotations, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, font_color=(255, 255, 255), thickness=2)
| 655 | |
| 656 | |
| 657 | def create_image_grid_with_annotations(images, annotations, font=cv2.FONT_HERSHEY_SIMPLEX, font_scale=1, font_color=(255, 255, 255), thickness=2): |
| 658 | """ |
| 659 | Arrange a nested list of MxN numpy arrays into a single image grid with column annotations. |
| 660 | |
| 661 | Args: |
| 662 | images (list of list of np.array): Nested list containing the image arrays. |
| 663 | annotations (list of str): List of annotations for each column. |
| 664 | font (int): Font type for the annotations. |
| 665 | font_scale (float): Font scale for the annotations. |
| 666 | font_color (tuple): Font color for the annotations. |
| 667 | thickness (int): Thickness of the font. |
| 668 | |
| 669 | Returns: |
| 670 | np.array: The resulting image grid with annotations. |
| 671 | """ |
| 672 | # Check if the input is valid |
| 673 | if not images or not isinstance(images, list) or not all(isinstance(row, list) for row in images): |
| 674 | raise ValueError("Input must be a nested list of numpy arrays.") |
| 675 | |
| 676 | # Determine the number of rows and columns |
| 677 | num_rows = len(images) |
| 678 | num_cols = len(images[0]) |
| 679 | |
| 680 | # Check if all rows have the same number of columns |
| 681 | if not all(len(row) == num_cols for row in images): |
| 682 | raise ValueError("All rows must have the same number of columns.") |
| 683 | |
| 684 | # Get the dimensions of each image |
| 685 | first_image_shape = images[0][0].shape |
| 686 | img_height, img_width = first_image_shape[:2] |
| 687 | |
| 688 | # Check if all images have the same dimensions |
| 689 | for row in images: |
| 690 | for img in row: |
| 691 | if img.shape[:2] != (img_height, img_width): |
| 692 | raise ValueError("All images must have the same dimensions.") |
| 693 | |
| 694 | # Determine the number of channels |
| 695 | num_channels = first_image_shape[2] if len(first_image_shape) == 3 else 1 |
| 696 | |
| 697 | # Create an empty array for the resulting grid |
| 698 | annotation_height = 50 # Height reserved for annotations |
| 699 | grid_height = num_rows * img_height + annotation_height |
| 700 | grid_width = num_cols * img_width |
| 701 | |
| 702 | if num_channels == 1: |
| 703 | grid = np.zeros((grid_height, grid_width), dtype=images[0][0].dtype) |
| 704 | else: |
| 705 | grid = np.zeros((grid_height, grid_width, num_channels), dtype=images[0][0].dtype) |
| 706 | |
| 707 | # Add annotations at the top of each column |
| 708 | for col_idx, annotation in enumerate(annotations): |
| 709 | text_size = cv2.getTextSize(annotation, font, font_scale, thickness)[0] |
| 710 | text_x = col_idx * img_width + (img_width - text_size[0]) // 2 |
| 711 | text_y = (annotation_height + text_size[1]) // 2 |
| 712 | cv2.putText(grid, annotation, (text_x, text_y), font, font_scale, font_color, thickness) |
| 713 | |
| 714 | # Populate the grid with the images |
no outgoing calls
no test coverage detected
searching dependent graphs…