Exemple #1
0
def test__is_iterable():
    test1 = [1, 2]
    test2 = (3, 4)
    test3 = torch.ones(2)
    test4 = 5

    assert _is_iterable(test1)
    assert _is_iterable(test2)
    assert not _is_iterable(test3)
    assert not _is_iterable(test4)
Exemple #2
0
    def _get_raw_predictions(self, images):
        self._model.eval()

        with torch.no_grad():
            # Convert image into a list of length 1 if not already a list
            if not _is_iterable(images):
                images = [images]

            # Convert to tensor and normalize if not already
            if not isinstance(images[0], torch.Tensor):
                # This is a temporary workaround to the bad accuracy
                # when normalizing on default weights. Will need to
                # investigate further TODO
                if self._disable_normalize:
                    defaults = transforms.Compose([transforms.ToTensor()])
                else:
                    defaults = default_transforms()
                images = [defaults(img) for img in images]

            # Send images to the specified device
            images = [img.to(self._device) for img in images]

            preds = self._model(images)
            # Send predictions to CPU if not already
            preds = [{k: v.to(torch.device('cpu')) for k, v in p.items()} for p in preds]
            return preds
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)
Exemple #4
0
def detect_ingredients(image, boxes, labels=None):
    plt.rcParams.update({'font.size': 14})
    fig, ax = plt.subplots(figsize=(20, 10))
    fig.patch.set_visible(False)
    ax.axis('off')

    # 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 utils._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=2, edgecolor='cyan', facecolor='none')
        if labels:
            ax.text(box[0], box[1] - 10, '{}'.format(labels[i]), color='black')
        ax.add_patch(rect)
    fig.savefig('detection_result.jpg', dpi=100)
Exemple #5
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()
Exemple #6
0
    def predict(self, images):
        """Takes in an image or list of images and returns predictions
        for object locations.

        :param images: An image or list of images to predict on. If the
            images have not already been transformed into torch.Tensor
            objects, the default transformations contained in
            :func:`detecto.utils.default_transforms` will be applied.
        :type images: list or numpy.ndarray or torch.Tensor
        :return: If given a single image, returns a tuple of size
            three. The first element is a list of string labels of size N,
            the number of detected objects. The second element is a
            torch.Tensor of size (N, 4), giving the ``xmin``, ``ymin``,
            ``xmax``, and ``ymax`` coordinates of the boxes around each
            object. The third element is a torch.Tensor of size N containing
            the scores of each predicted object (ranges from 0.0 to 1.0). If
            given a list of images, returns a list of the tuples described
            above, each tuple corresponding to a single image.
        :rtype: tuple or list of tuple

        **Example**::

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

            >>> model = Model.load('model_weights.pth', ['horse', 'zebra'])
            >>> image = read_image('image.jpg')
            >>> labels, boxes, scores = model.predict(image)
            >>> print(labels[0])
            >>> print(boxes[0])
            >>> print(scores[0])
            horse
            tensor([   0.0000,  428.0744, 1617.1860, 1076.3607])
            tensor(0.9397)
        """

        # Convert all to lists but keep track if a single image was given
        is_single_image = not _is_iterable(images)
        images = [images] if is_single_image else images
        preds = self._get_raw_predictions(images)

        results = []
        for pred in preds:
            # Convert predicted ints into their corresponding string labels
            result = ([self._classes[val] for val in pred['labels']],
                      pred['boxes'], pred['scores'])
            results.append(result)

        return results[0] if is_single_image else results
def show_labeled_image(image, boxes, labels=None):

    fig, ax = plt.subplots(1)

    ## result image 사이즈를 크게 조정
    plt.rcParams.update({'font.size': 22})
    fig.set_size_inches(30, 20)

    # 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 utils._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()

    # detecting 결과 이미지를 현재 작업 디렉토리에 저장
    fig.savefig('result.png', dpi=100)
    plt.close(fig)
Exemple #8
0
    def _get_raw_predictions(self, images):
        self._model.eval()

        with torch.no_grad():
            # Convert image into a list of length 1 if not already a list
            if not _is_iterable(images):
                images = [images]

            # Convert to tensor and normalize if not already
            if not isinstance(images[0], torch.Tensor):
                defaults = default_transforms()
                images = [defaults(img) for img in images]

            # Send images to the specified device
            images = [img.to(self._device) for img in images]

            preds = self._model(images)
            # Send predictions to CPU if not already
            preds = [{k: v.to(torch.device('cpu'))
                      for k, v in p.items()} for p in preds]
            return preds
Exemple #9
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)