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