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)
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()
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()
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()
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)