U h gbÌ7ã @s¶ddlZddlZddlmZddlZddlZddlmZddl Z ddl Z ddl Z ddl mZddlmZddlmZddlmZdd d „Zdd d„Zddd„Zddd„Zd dd„ZdS)!éN)ÚImage)Útqdm)Únms)Ú preprocess)Ú visualize)Údatasetçš™™™™™¹?éc Cs|jdkr(t d|j›d�¡| d¡}tj||d�}t ¡�||ƒ}W5QRXt|ddƒdkrjdSt   |d¡}t ||d�}|rø|j d ksš|  ¡}t | d¡¡}t |dd ¡}|dd…dd…ddd …fd }| d ¡}t j||||d�}|S|SdS)a†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 device: pytorch device of 'cuda' or 'cpu' for gpu prediction. Set internally. 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) Úfloat32zImage type is z¥, transforming to float32. This assumes that the range of pixel values is 0-255, as opposed to 0-1.To suppress this warning, transform image (image.astype('float32'))ÚdevicerÚboxesN©Ú iou_thresholdÚcpuééÿÿÿÿéÿÚuint8©ÚcolorÚ thickness)ÚdtypeÚwarningsÚwarnÚastyperZpreprocess_imageÚtorchÚno_gradÚlenrÚ format_boxesÚacross_class_nmsÚtyperÚnpÚarrayÚsqueezeÚrollaxisÚplot_predictions) ÚmodelÚimageÚ return_plotr rrrÚ predictionÚdf©r+úh/home/ec2-user/SageMaker/vegetation-management-remars2022/remars2022-workshop/libs/deepforest/predict.pyÚ predict_images(       r-©ré¥rc Csv| ¡t |¡}|j ¡} tj||ddd�} g} t ¡�4| D](} |   |¡} |t  | d¡ƒ} |   | ¡q@W5QRXdd„| Dƒ} g}t | ƒD]Ô\}} t  | ¡} t| j ¡ƒdkr¾t| |d�} |�rLt t d  || |¡¡¡dd…dd…ddd …f}t  || ¡}||j| |k}t j||||d �}t d  |tj | |¡d¡|¡| || d <|  | ¡qŽtj|dd�}|S)aáCreate a dataset and predict entire annotation file Csv file format is .csv file with the columns "image_path", "xmin","ymin","xmax","ymax" for the image name and bounding box position. Image_path is the relative filename, not absolute path, which is in the root_dir directory. One bounding box per line. If "label" column is present, these are assumed to be annotations and will be plotted in a different color than predictions Args: csv_file: path to csv file root_dir: directory of images. If none, uses "image_dir" in config savedir: Optional. Directory to save image plots. device: pytorch device of 'cuda' or 'cpu' for gpu prediction. Set internally. 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: df: pandas dataframe with bounding boxes, label and scores for each image in the csv file NF)Úcsv_fileÚroot_dirÚ transformsÚtrainrcSsg|]}|D]}|‘q qSr+r+)Ú.0ÚsublistÚitemr+r+r,Ú csz predict_file..r r z{}/{}rrz {}/{}.pngÚ image_pathT)Ú ignore_index)ÚevalÚpdÚread_csvr8ÚuniquerÚ TreeDatasetrrÚtoÚ unsqueezeÚappendÚ enumeraterrrÚlabelrr!r"rÚopenÚformatr%Úcv2ÚimwriteÚosÚpathÚsplitextÚconcat)r&r0r1Úsavedirr rrrr*ÚpathsÚdsZprediction_listÚir)ÚresultsÚindexr'Ú annotationsr+r+r,Ú predict_fileBs<  ý    4 $  rSé�çš™™™™™©?ç333333Ã?FTçà?çü©ñÒMbP?c!Cs`|dk r nt |¡ ¡}t |dd¡}t |||¡}g}g}tt|ƒƒD]˜\}}|||  ¡}|  d¡}t ||d|d�}|dk rH|rÌ||  ¡\}}}}|j ||_ |j||_|j||_|j||_n | |¡| |¡qHt|ƒdkrútdƒdS|�rNt |¡}|dk�r|}nöt|jd›d�ƒtj|d d d d gjtjd �}tj|jjtjd �}|jj}| �s~t|||d�}nt||| | d�}| ¡}||  tj!¡||||}}}tj"|tj#|dd�tj#|dd�gdd�} tj$| d d d d ddgd�}t|jd›d�ƒ|�rH|dd…dd…ddd…f}t%j&||| | d�}|S|Snt't(||ƒƒSdS)aôFor images too large to input into the model, predict_tile cuts the image into overlapping windows, predicts trees on each window and reassambles into a single array. Args: model: pytorch model device: pytorch device of 'cuda' or 'cpu' for gpu prediction. Set internally. numeric_to_label_dict: dictionary in which keys are numeric integers and values are character labels raster_path: Path to image on disk image (array): Numpy image array in BGR channel order following openCV convention patch_size: patch size default400, patch_overlap: patch overlap default 0.15, iou_threshold: Minimum iou overlap among predictions between windows to be suppressed. Defaults to 0.14. Lower values suppress more boxes at edges. return_plot: Should the image be returned with the predictions drawn? mosaic: If true, return a single annotations dataframe. If false, return a list of windows and predictions use_soft_nms: whether to perform Gaussian Soft NMS or not, if false, default perform NMS. sigma: variance of Gaussian function used in Gaussian Soft NMS thresh: the score thresh used to filter bboxes after soft-nms performed Returns: boxes (array): if return_plot, an image. windows (list): if mosaic = False, a two item tuple for each window of patch_size with predictions Otherwise a numpy array of predicted bounding boxes, scores and labels Nrér F)r&r'r(r z#No predictions made, returning Nonez@ predictions in overlapping windows, applying non-max supressionÚxminÚyminÚxmaxÚymax©r©r Úscoresr)r r`ÚsigmaÚthreshr ©ÚaxisrCÚscore©Úcolumnsz+ predictions kept after non-max suppressionrr))ÚriorDÚreadr!ÚmoveaxisrZcompute_windowsrBrÚindicesrr-ZgetRectrZr\r[r]rArÚprintr;rKÚshaperÚtensorÚvaluesr rerCrÚsoft_nmsÚnumpyr ÚintÚ concatenateÚ expand_dimsÚ DataFramerr%ÚlistÚzip)!r&r Ú raster_pathr'Ú patch_sizeÚ patch_overlaprr(ÚmosaicÚ use_soft_nmsrarbrrÚwindowsÚpredicted_boxesÚcropsrQÚwindowÚcropr rZr[r\r]Z mosaic_dfr`ÚlabelsÚ bbox_left_idxÚ new_boxesÚ new_labelsÚ new_scoresÚimage_detectionsr+r+r,Ú predict_tile€s†*         ÿÿýÿÿ   ýûÿrˆcCsÌ|jd}tjd|tjd� |d¡}tj||fdd�}|dd…df}|dd…df}|dd…df}|dd…df} ||d| |d} t|ƒD�]} ||  ¡} | d} | |dk�rˆtj|| d…dd�\}}| |k�rˆ||  ¡| d ¡||  ¡|| <||  ¡| d<||  ¡| d ¡||  ¡|| <||  ¡| d<| || d ¡| |  ¡| | <| || d<t   || df  ¡|| d…df  ¡¡}t   || df  ¡|| d…df  ¡¡}t   || df  ¡|| d…df  ¡¡}t   || df  ¡|| d…df  ¡¡}t   d||d¡}t   d||d¡}t ||¡}t || | | | d…|¡}t || |¡}||| d…|| d…<q–|dd…d f||k ¡}|S) a  Perform python soft_nms to reduce the confidances of the proposals proportional to IoU value Paper: Improving Object Detection With One Line of Code Code : https://github.com/DocF/Soft-NMS/blob/master/softnms_pytorch.py Args: boxes: predicitons bounding boxes tensor format [x1,y1,x2,y2] scores: the score corresponding to each box tensors sigma: variance of Gaussian function thresh: score thresh Return: idxs_keep: the index list of the selected boxes rr^r )ÚdimNrYrgé)rmrÚarangeÚfloatÚviewÚcatÚrangeÚcloneÚmaxr6r!ÚmaximumrqÚminimumrnÚdivÚexprr)r r`rarbÚNÚindexesÚx1Úy1Úx2Úy2ÚareasrOZtscoreÚposZmaxscoreÚmaxposZxx1Zyy1Zxx2Zyy2ÚwÚhÚinterÚovrÚweightZ idxs_keepr+r+r,rpsb    ÿ ÿÿÿ ÿ ÿÿÿÿÿ ÿ(((( rpc Csºtj|ddddgjtjd�}tj|jjtjd�}|jj}t|||d�}| ¡}|| tj ¡||||}}}t j |t j |dd�t j |dd�gdd�} t j| ddddd d gd �} | S) z‹perform non-max suppression for a dataframe of results (see visualize.format_boxes) to remove boxes that overlap by iou_thresholdold of IoUrZr[r\r]r^r_r rcrCrerf)rrnror rerCrrqr rrr!rsrtr;ru) r~rr r`r‚rƒr„r…r†r‡Znew_dfr+r+r,rCs2ÿÿÿ   ýûÿr)rNr )rr.r ) NNrTrUrVFTFrWrXNr )rWrX)rV)rFÚpandasr;ÚPILrrqr!rHrrrÚrasteriorhZtorchvision.opsrÚlibs.deepforestrrrr-rSrˆrprr+r+r+r,Ús<       0 @ó  @