Example #1
0
    def compose_panorama(self, image_left, image_right):
        """Try to compose the given images into the final panorama.

        This happens under the assumption that the image transformations were estimated or loaded
        before.

        Args:
            image_left (ndarray): Input left image.
            image_right (ndarray): Input right image.

        Returns:
            ndarray: panorama (stitched image)
        """
        image_left = helpers.add_alpha_channel(image_left)
        image_right = helpers.add_alpha_channel(image_right)

        if self.rectify:
            image_left = self.rectificator.rectify_image(image_left)
            image_right = self.rectificator.rectify_image(image_right)

        bounds = helpers.get_boundaries(self.size_left, self.size_right,
                                        self.homo_left, self.homo_right)
        pano_size = (math.ceil(bounds.xmax - bounds.xmin),
                     math.ceil(bounds.ymax - bounds.ymin))

        image_left = cv2.warpPerspective(image_left, self.homo_left, pano_size)
        image_right = cv2.warpPerspective(image_right, self.homo_right,
                                          pano_size)

        alpha = 0.5
        cv2.addWeighted(image_left, alpha, image_right, 1 - alpha, 0,
                        image_left)

        return image_left
Example #2
0
def test_add_alpha_channel(left_img):
    color = left_img['color']
    w, h = left_img['size']

    # test color image without alpha channel
    target = helpers.add_alpha_channel(color)
    assert target.shape == (h, w, 4)

    # test black and white image
    img_bw = left_img['bw']
    target = helpers.add_alpha_channel(img_bw)
    assert target.shape == (h, w, 4)

    # test already alpha
    img_alpha = np.zeros((3000, 4000, 4), dtype=np.uint8)
    helpers.add_alpha_channel(img_alpha)
    assert img_alpha.shape == (h, w, 4)

    # provoke exception
    img_not = np.zeros((3000, 4000, 5), dtype=np.uint8)
    with pytest.raises(Exception):
        helpers.add_alpha_channel(img_not)

    # provoke exception
    img_not = np.zeros((3000, 4000, 5, 4), dtype=np.uint8)
    with pytest.raises(Exception):
        helpers.add_alpha_channel(img_not)
Example #3
0
def create_prepared_image_dict(img, angle, config):
    img_alpha = helpers.add_alpha_channel(img['img'])
    rectificator = prep.Rectificator(config)
    rect_img = rectificator.rectify_image(img_alpha)
    rect_detections = rectificator.rectify_points(img['detections'],
                                                  img['size'])
    rect_img_w_detections = rectificator.rectify_image(img['img_w_detections'])

    rot_img, rot_mat = prep.rotate_image(rect_img, angle)
    rot_detections = prep.rotate_points(rect_detections, angle, img['size'])
    rot_img_w_detections, rot_mat = prep.rotate_image(rect_img_w_detections,
                                                      angle)

    d = dict()
    d['img'] = rot_img
    d['detections'] = rot_detections
    d['img_w_detections'] = rot_img_w_detections
    return d
Example #4
0
    def _prepare_image(self, image, angle=0):
        """Prepare image for stitching.

        It rotates and rectifies the image. Ff the Stitcher is initialized with ``rectify=False``
        the image will not be rectified.

        Args:
            image (ndarray): Image to prepare.
            angle (int): angle in degree to rotate image.

        Returns:
            - **image** (ndarray) -- rotated (and rectified) image.
            - **affine** (ndarray) -- An affine *(3,3)*--matrix for rotation of image or points.
        """
        image = helpers.add_alpha_channel(image)
        if self.rectify:
            image = self.rectificator.rectify_image(image)
        image_rot, affine = prep.rotate_image(image, angle)
        return image_rot, affine
Example #5
0
    def pick(self, images, all_pts=True):
        """Initialise a GUI to pick points on multiple images.

        A matplot GUI will be initialised, where the user can pick multiple points
        on the **N** ``images``. Afterwards the :obj:`PointPicker` will return **N** ndarrays, which
        holds the coordinates of the marked points. Each ndarray holds the points for one image.

        Args:
            images (list(ndarray)): List of images (ndarray)
            all_pts (bool): If ``True`` all points will be returned and else just 'selected' \
            points will be returned.

        Returns:
            list(ndarray): Returns a List of length **N**, where each cell contains a ndarray \
            *(M,2)*, which holds the coordinates of the *M* marked points per image.
        """
        imgs_a = []
        for img in images:
            imgs_a.append(helpers.add_alpha_channel(img))
        count_images = len(imgs_a)
        # creating one list per image, which will hold the draggable marks
        # e.g. for 2 images:
        # dms_per_image = [[<dragableMarks first image>],[<dragableMarks second image>]]

        dms_per_image = []
        for __ in range(count_images):
            dms_per_image.append(draggs.DraggableMarkList())

        def _on_click(event):
            # double click left mouse button
            if event.button == 1 and event.dblclick:
                for i, ax in enumerate(axes):
                    if event.inaxes == ax:
                        marker, = ax.plot(event.xdata,
                                          event.ydata,
                                          'xr',
                                          markersize=10,
                                          markeredgewidth=2)
                        dm = draggs.DraggableMark(marker, imgs_a[i])
                        dm.connect()
                        dms_per_image[i].append(dm)
                        fig.canvas.draw()

        fig, axes = plt.subplots(nrows=1,
                                 ncols=count_images,
                                 tight_layout=False)
        fig.canvas.mpl_connect('button_press_event', _on_click)
        fig.canvas.set_window_title(
            'Point Picker | r-refine point | s-select point | z-zoom | '
            'p-pan | q-quit/finish')

        # if the nrows == 1 and ncols == 1 the function of plt.subplots returns a single
        # class 'matplotlib.axes._subplots.AxesSubplot' but we want always an array
        if count_images == 1:
            axes = np.array([axes])

        for i, image in enumerate(imgs_a):
            # don't draw y-axis on every image, just on first image
            if i > 0:
                plt.setp(axes[i].get_yticklabels(), visible=False)
            axes[i].imshow(image)

        plt.show()
        points = []
        for i, dms in enumerate(dms_per_image):
            points_per_image = dms.get_points(all_pts=all_pts)
            points.append(points_per_image)
        return points