def image_recognition(image_path,save_path):
    image = utils.read_image(image_path)
    model = core.Model()

    labels, boxes, scores = model.predict_top(image)

    fig, ax = plt.subplots(1)
    # If the image is already a tensor, convert it back to a PILImage
    # and reverse normalize it
    if isinstance(image, torch.Tensor):
        image = reverse_normalize(image)
        image = transforms.ToPILImage()(image)
    ax.imshow(image)

    # Show a single box or multiple if provided
    if boxes.ndim == 1:
        boxes = boxes.view(1, 4)

    if labels is not None and not _is_iterable(labels):
        labels = [labels]

    # Plot each box
    for i in range(boxes.shape[0]):
        box = boxes[i]
        width, height = (box[2] - box[0]).item(), (box[3] - box[1]).item()
        initial_pos = (box[0].item(), box[1].item())
        rect = patches.Rectangle(initial_pos, width, height, linewidth=1,
                                 edgecolor='r', facecolor='none')
        if labels:
            ax.text(box[0] + 5, box[1] - 5, '{}'.format(labels[i]), color='red')

        ax.add_patch(rect)

    plt.savefig(save_path)
예제 #2
0
def show_labeled_image(image, boxes, labels=None):
    """Show the image along with the specified boxes around detected objects.
    Also displays each box's label if a list of labels is provided.

    :param image: The image to plot. If the image is a normalized
        torch.Tensor object, it will automatically be reverse-normalized
        and converted to a PIL image for plotting.
    :type image: numpy.ndarray or torch.Tensor
    :param boxes: A torch tensor of size (N, 4) where N is the number
        of boxes to plot, or simply size 4 if N is 1.
    :type boxes: torch.Tensor
    :param labels: (Optional) A list of size N giving the labels of
            each box (labels[i] corresponds to boxes[i]). Defaults to None.
    :type labels: torch.Tensor or None

    **Example**::

        >>> from detecto.core import Model
        >>> from detecto.utils import read_image
        >>> from detecto.visualize import show_labeled_image

        >>> model = Model.load('model_weights.pth', ['tick', 'gate'])
        >>> image = read_image('image.jpg')
        >>> labels, boxes, scores = model.predict(image)
        >>> show_labeled_image(image, boxes, labels)
    """

    fig, ax = plt.subplots(1)
    # If the image is already a tensor, convert it back to a PILImage
    # and reverse normalize it
    if isinstance(image, torch.Tensor):
        image = reverse_normalize(image)
        image = transforms.ToPILImage()(image)
    ax.imshow(image)

    if len(boxes) == 0 or boxes is None: # can't do "if not boxes"
        plt.show()
        return

    # Show a single box or multiple if provided
    if boxes.ndim == 1:
        boxes = boxes.view(1, 4)

    if labels is not None and not _is_iterable(labels):
        labels = [labels]

    # Plot each box
    for i in range(boxes.shape[0]):
        box = boxes[i]
        width, height = (box[2] - box[0]).item(), (box[3] - box[1]).item()
        initial_pos = (box[0].item(), box[1].item())
        rect = patches.Rectangle(initial_pos,  width, height, linewidth=1,
                                 edgecolor='r', facecolor='none')
        if labels:
            ax.text(box[0] + 5, box[1] - 5, '{}'.format(labels[i]), color='red')

        ax.add_patch(rect)

    plt.show()
예제 #3
0
def show_labeled_image(image, boxes):
    """Show the image along with the specified boxes around detected objects.

    :param image: The image to plot. If the image is a normalized
        torch.Tensor object, it will automatically be reverse-normalized
        and converted to a PIL image for plotting.
    :type image: numpy.ndarray or torch.Tensor
    :param boxes: A torch tensor of size (N, 4) where N is the number
        of boxes to plot, or simply size 4 if N is 1.
    :type boxes: torch.Tensor

    **Example**::

        >>> from detecto.core import Model
        >>> from detecto.utils import read_image
        >>> from detecto.visualize import show_labeled_image

        >>> model = Model.load('model_weights.pth', ['tick', 'gate'])
        >>> image = read_image('image.jpg')
        >>> labels, boxes, scores = model.predict(image)
        >>> show_labeled_image(image, boxes)
    """

    fig, ax = plt.subplots(1)
    # If the image is already a tensor, convert it back to a PILImage
    # and reverse normalize it
    if isinstance(image, torch.Tensor):
        image = reverse_normalize(image)
        image = transforms.ToPILImage()(image)
    ax.imshow(image)

    # Show a single box or multiple if provided
    if boxes.ndim == 1:
        boxes = boxes.view(1, 4)

    # Plot each box
    for box in boxes:
        width, height = (box[2] - box[0]).item(), (box[3] - box[1]).item()
        initial_pos = (box[0].item(), box[1].item())
        rect = patches.Rectangle(initial_pos,
                                 width,
                                 height,
                                 linewidth=1,
                                 edgecolor='r',
                                 facecolor='none')

        ax.add_patch(rect)

    plt.show()
예제 #4
0
def plot_prediction_grid(model,
                         images,
                         dim=None,
                         figsize=None,
                         score_filter=0.6):
    """Plots a grid of images with boxes drawn around predicted objects.

    :param model: The trained model with which to run object detection.
    :type model: detecto.core.Model
    :param images: An iterable of images to plot. If the images are
        normalized torch.Tensor images, they will automatically be
        reverse-normalized and converted to PIL images for plotting.
    :type images: iterable
    :param dim: (Optional) The dimensions of the grid in the format
        ``(rows, cols)``. If no value is given, the grid is of the shape
        ``(len(images), 1)``. ``rows * cols`` must match the number of
        given images, or a ValueError is raised. Defaults to None.
    :type dim: tuple or None
    :param figsize: (Optional) The size of the entire grid in the format
        ``(width, height)``. Defaults to None.
    :type figsize: tuple or None
    :param score_filter: (Optional) Minimum score required to show a
        prediction. Defaults to 0.6.
    :type score_filter: float

    **Example**::

        >>> from detecto.core import Model
        >>> from detecto.utils import read_image
        >>> from detecto.visualize import plot_prediction_grid

        >>> model = Model.load('model_weights.pth', ['tick', 'gate'])
        >>> images = []
        >>> for i in range(4):
        >>>     image = read_image('image{}.jpg'.format(i))
        >>>     images.append(image)
        >>> plot_prediction_grid(model, images, dim=(2, 2), figsize=(8, 8))
    """

    # If not specified, show all in one column
    if dim is None:
        dim = (len(images), 1)

    if dim[0] * dim[1] != len(images):
        raise ValueError('Grid dimensions do not match size of list of images')

    fig, axes = plt.subplots(dim[0], dim[1], figsize=figsize)

    # Loop through each image and position in the grid
    index = 0
    for i in range(dim[0]):
        for j in range(dim[1]):
            image = images[index]
            preds = model.predict(image)

            # If already a tensor, reverse normalize it and turn it back
            if isinstance(image, torch.Tensor):
                image = transforms.ToPILImage()(reverse_normalize(image))
            index += 1

            # Get the correct axis
            if dim[0] <= 1 and dim[1] <= 1:
                ax = axes
            elif dim[0] <= 1:
                ax = axes[j]
            elif dim[1] <= 1:
                ax = axes[i]
            else:
                ax = axes[i, j]

            ax.imshow(image)

            # Plot boxes and labels
            for label, box, score in zip(*preds):
                if score >= score_filter:
                    width, height = box[2] - box[0], box[3] - box[1]
                    initial_pos = (box[0], box[1])
                    rect = patches.Rectangle(initial_pos,
                                             width,
                                             height,
                                             linewidth=1,
                                             edgecolor='r',
                                             facecolor='none')
                    ax.add_patch(rect)

                    ax.text(box[0] + 5,
                            box[1] - 10,
                            '{}: {}'.format(label, round(score.item(), 2)),
                            color='red')
                ax.set_title('Image {}'.format(index))

    plt.show()
예제 #5
0
    def classifyMountingConfiguration(self,
                                      image_file_path,
                                      acc_cutoff=.65,
                                      file_name_save=None,
                                      use_nms=True):
        """
        This function is used to detect and classify the mounting configuration
        of solar installations in satellite imagery. It leverages the Detecto
        package's functionality
        (https://detecto.readthedocs.io/en/latest/api/index.html),
        to perform object detection on a satellite image.

        Parameters
        -----------
        image_file_path: string
            File path of the image. PNG file.
        acc_cutoff: float
            Default set to 0.65. Confidence cutoff for whether or not to
            count a object detection classification as real. All returned
            classications greater than or equal to the accuracy cutoff are
            counted, and all classifications less than the accuracy cutoff
            are thrown out.
        Returns
        -----------
        Returns
            tuple
            Tuple consisting of (scores, labels, boxes), where 'scores' is
            the list of object detection confidence scores, 'labels' is a
            list of all corresponding labels, and 'boxes' is a tensor object
            containing the associated boxes for the associated labels and
            confidence scores.
        """
        image = read_image(image_file_path)
        labels, boxes, scores = self.mounting_classifier.predict(image)
        if use_nms:
            # Perform non-maximum suppression (NMS) on the detections
            nms_idx = nms(boxes=boxes, scores=scores, iou_threshold=0.25)
            scores = scores[nms_idx]
            boxes = boxes[nms_idx]
            labels = [labels[nms] for nms in nms_idx]
        mask = [float(x) > acc_cutoff for x in scores]
        scores = list(np.array(scores)[mask])
        labels = list(np.array(labels)[mask])
        boxes = torch.tensor(np.array(boxes)[mask])
        # This code is adapted from the Detecto package's show_labeled_image()
        # function. See the following link as reference:
        # https://github.com/alankbi/detecto/blob/master/detecto/visualize.py
        # Generate the image associated with the classifications
        fig, ax = plt.subplots(1)
        # If the image is already a tensor, convert it back to a PILImage
        # and reverse normalize it
        if isinstance(image, torch.Tensor):
            image = reverse_normalize(image)
            image = transforms.ToPILImage()(image)
        ax.imshow(image)
        # Show a single box or multiple if provided
        if boxes.ndim == 1:
            boxes = boxes.view(1, 4)
        if labels is not None and not _is_iterable(labels):
            labels = [labels]
        # Plot each box
        for i in range(boxes.shape[0]):
            box = boxes[i]
            width, height = (box[2] - box[0]).item(), (box[3] - box[1]).item()
            initial_pos = (box[0].item(), box[1].item())
            rect = patches.Rectangle(initial_pos,
                                     width,
                                     height,
                                     linewidth=1,
                                     edgecolor='r',
                                     facecolor='none')
            if labels:
                ax.text(box[0] + 5,
                        box[1] - 5,
                        '{}'.format(labels[i]),
                        color='red')
            ax.add_patch(rect)
        if file_name_save is not None:
            plt.savefig(file_name_save)
        return (scores, labels, boxes)