File size: 3,033 Bytes
8cf4ead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import matplotlib.pyplot as plt
import numpy as np


class ImageViewer:
    def __init__(self, title="Image Viewer", figsize=(8, 6), num_images=1, image_titles=None):
        self.title = title
        self.figsize = figsize
        self.num_images = num_images
        self.image_titles = image_titles or [f"Camera {i+1}" for i in range(num_images)]

        # Enable interactive mode before creating subplots
        plt.ion()

        if num_images == 1:
            self._fig, self._ax = plt.subplots(figsize=self.figsize)
            self._ax.set_title(self.title)
            self._im = self._ax.imshow(np.zeros((100, 100)))
            self._ax.axis("off")
            self._axes = [self._ax]
            self._images = [self._im]
        else:
            # Calculate grid dimensions
            cols = min(num_images, 3)  # Max 3 columns
            rows = (num_images + cols - 1) // cols

            # Adjust figure size based on number of images
            fig_width = self.figsize[0] * min(cols, 2)
            fig_height = self.figsize[1] * rows / 2

            self._fig, axes = plt.subplots(rows, cols, figsize=(fig_width, fig_height))
            self._fig.suptitle(self.title)

            # Flatten axes array for easier access
            if num_images == 2:
                axes = [axes[0], axes[1]]
            elif rows == 1:
                axes = axes if cols > 1 else [axes]
            else:
                axes = axes.flatten()

            self._axes = []
            self._images = []

            for i in range(num_images):
                ax = axes[i]
                ax.set_title(self.image_titles[i])
                im = ax.imshow(np.zeros((100, 100)))
                ax.axis("off")
                self._axes.append(ax)
                self._images.append(im)

            # Hide unused subplots
            for i in range(num_images, len(axes)):
                axes[i].set_visible(False)

        # Show the figure initially to make window appear
        self._fig.show()

    def show(self, image_array):
        """Show a single image (backward compatibility)"""
        if self.num_images == 1:
            self._images[0].set_data(image_array)
        else:
            # If multiple viewers but single image provided, show in first viewer
            self._images[0].set_data(image_array)

        # non-blocking update
        self._fig.canvas.draw_idle()
        self._fig.canvas.flush_events()

    def show_multiple(self, images):
        """Show multiple images"""
        for i, img in enumerate(images):
            if i < len(self._images) and img is not None:
                self._images[i].set_data(img)
                # Auto-adjust aspect ratio
                self._axes[i].set_aspect("auto")

        # non-blocking update
        self._fig.canvas.draw_idle()
        self._fig.canvas.flush_events()

    def close(self):
        plt.close(self._fig)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()