def predict_image(self, image_path, return_plot=True, show=False): '''Predict tree crowns based on loaded (or trained) model Args: image_path (str): Path to image on disk show (bool): Plot the predicted image with bounding boxes. Ignored if return_plot=False return_plot: Whether to return image with annotations overlaid, or just a numpy array of boxes Returns: predictions (array): if return_plot, an image. Otherwise a numpy array of predicted bounding boxes ''' #Check for model weights if (self.weights is None): raise ValueError( "Model currently has no weights, either train a new model using deepforest.train, loading existing model, or use prebuilt model (see deepforest.use_release()" ) #convert model to prediction self.prediction_model = convert_model(self.model) if return_plot: image = predict.predict_image(self.prediction_model, image_path, return_plot=return_plot) #cv2 channel order if show: plt.imshow(image[:, :, ::-1]) plt.show() return image else: boxes = predict.predict_image(self.prediction_model, image_path, return_plot=return_plot) return boxes
def predict_image(self, image=None, path=None, return_plot=False, color=None, thickness=1): """Predict a single image with a deepforest model Args: image: a float32 numpy array of a RGB with channels last format path: optional path to read image from disk instead of passing image arg return_plot: Return image with plotted detections color: color of the bounding box as a tuple of BGR color, e.g. orange annotations is (0, 165, 255) thickness: thickness of the rectangle border line in px Returns: boxes: A pandas dataframe of predictions (Default) img: The input with predictions overlaid (Optional) """ if isinstance(image, str): raise ValueError( "Path provided instead of image. If you want to predict an image from disk, is path =" ) if path: if not isinstance(path, str): raise ValueError("Path expects a string path to image on disk") image = np.array(Image.open(path).convert("RGB")).astype("float32") #sanity checks on input images if not type(image) == np.ndarray: raise TypeError( "Input image is of type {}, expected numpy, if reading from PIL, wrap in np.array(image).astype(float32)" .format(type(image))) # Load on GPU is available if self.current_device.type == "cuda": self.model = self.model.to("cuda") self.model.eval() self.model.score_thresh = self.config["score_thresh"] # Check if GPU is available and pass image to gpu result = predict.predict_image(model=self.model, image=image, return_plot=return_plot, device=self.current_device, iou_threshold=self.config["nms_thresh"], color=color, thickness=thickness) #Set labels to character from numeric if returning boxes df if not return_plot: if not result is None: result["label"] = result.label.apply( lambda x: self.numeric_to_label_dict[x]) return result
def predict_image(self, image_path=None, numpy_image=None, return_plot=True, score_threshold=0.05, show=False, color=None): """Predict tree crowns based on loaded (or trained) model Args: image_path (str): Path to image on disk numpy_image (array): Numpy image array in BGR channel order following openCV convention color (tuple): Color of bounding boxes in BGR order (0,0,0) black default show (bool): Plot the predicted image with bounding boxes. Ignored if return_plot=False return_plot: Whether to return image with annotations overlaid, or just a numpy array of boxes Returns: predictions (array): if return_plot, an image. Otherwise a numpy array of predicted bounding boxes, with scores and labels """ #Check for model save if (self.prediction_model is None): raise ValueError( "Model currently has no prediction weights, either train a new model using deepforest.train, loading existing model, or use prebuilt model (see deepforest.use_release()" ) #Check the formatting if isinstance(image_path, np.ndarray): raise ValueError( "image_path should be a string, but is a numpy array. If predicting a loaded image (channel order BGR), use numpy_image argument." ) #Check for correct formatting #Warning if image is very large and using the release model if numpy_image is None: numpy_image = cv2.imread(image_path) #Predict prediction = predict.predict_image(self.prediction_model, image_path=image_path, raw_image=numpy_image, return_plot=return_plot, score_threshold=score_threshold, color=color, classes=self.labels) #cv2 channel order to matplotlib order if return_plot & show: plt.imshow(prediction[:, :, ::-1]) plt.show() return prediction
def predict_image(self, image=None, path=None, return_plot=False): """Predict an image with a deepforest model Args: image: a numpy array of a RGB image ranged from 0-255 path: optional path to read image from disk instead of passing image arg return_plot: Return image with plotted detections Returns: boxes: A pandas dataframe of predictions (Default) img: The input with predictions overlaid (Optional) """ if isinstance(image, str): raise ValueError( "Path provided instead of image. If you want to predict an image from disk, is path =" ) if path: if not isinstance(path, str): raise ValueError("Path expects a string path to image on disk") image = io.imread(path) # Load on GPU is available if torch.cuda.is_available: self.model.to(self.device) self.model.eval() # Check if GPU is available and pass image to gpu result = predict.predict_image(model=self.model, image=image, return_plot=return_plot, device=self.device, iou_threshold=self.config["nms_thresh"]) #Set labels to character from numeric if returning boxes df if not return_plot: if not result is None: result["label"] = result.label.apply( lambda x: self.numeric_to_label_dict[x]) return result