U h gb7 @sddlZddlZddlmZddlZddlZddlmZddl Z ddl Z ddl Z ddl mZddlmZddlmZddlmZdd d Zdd dZdddZdddZd ddZdS)!N)Image)tqdm)nms) preprocess) visualize)dataset皙?c Cs|jdkr(td|jd|d}tj||d}t||}W5QRXt|dddkrjdSt |d}t ||d}|r|j d ks| }t|d}t|dd }|ddddddd fd }|d }t j||||d}|S|SdS)aPredict 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'))devicerboxesN iou_thresholdcpuuint8color thickness)dtypewarningswarnastyperZpreprocess_imagetorchno_gradlenr format_boxesacross_class_nmstypernparraysqueezerollaxisplot_predictions) modelimage return_plotr rrr predictiondfr+h/home/ec2-user/SageMaker/vegetation-management-remars2022/remars2022-workshop/libs/deepforest/predict.py predict_images(       r-rrc Csv|t|}|j} tj||ddd} g} t4| D](} | |} |t | d} | | q@W5QRXdd| D} g}t | D]\}} t | } t| jdkrt| |d} |rLttd || |ddddddd f}t || }||j| |k}t j||||d }td |tj| |d|| || d <| | qtj|dd}|S)aCreate 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_fileroot_dir transformstrainrcSsg|]}|D]}|q qSr+r+).0sublistitemr+r+r, csz predict_file..r r z{}/{}rrz {}/{}.png image_pathT) ignore_index)evalpdread_csvr8uniquer TreeDatasetrrto unsqueezeappend enumeraterrrlabelrr!r"ropenformatr%cv2imwriteospathsplitextconcat)r&r0r1savedirr rrrr*pathsdsZprediction_listir)resultsindexr' 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|dkrtddS|rNt|}|dkr|}nt|jddtj|d d d d gjtjd }tj|jjtjd }|jj}| s~t|||d}nt||| | d}|}|| tj!||||}}}tj"|tj#|ddtj#|ddgdd} tj$| d d d d ddgd}t|jdd|rH|dddddddf}t%j&||| | d}|S|Snt't(||SdS)aFor 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 Nrr F)r&r'r(r z#No predictions made, returning Nonez@ predictions in overlapping windows, applying non-max supressionxminyminxmaxymaxrr scoresr)r r`sigmathreshr axisrCscorecolumnsz+ predictions kept after non-max suppressionrr))riorDreadr!moveaxisrZcompute_windowsrBrindicesrr-ZgetRectrZr\r[r]rArprintr;rKshapertensorvaluesr rerCrsoft_nmsnumpyr int concatenate expand_dims DataFramerr%listzip)!r&r raster_pathr' patch_size patch_overlaprr(mosaic use_soft_nmsrarbrrwindowspredicted_boxescropsrQwindowcropr rZr[r\r]Z mosaic_dfr`labels bbox_left_idx new_boxes new_labels new_scoresimage_detectionsr+r+r, predict_tiles*            rcCs|jd}tjd|tjd|d}tj||fdd}|dddf}|dddf}|dddf}|dddf} ||d| |d} t|D]} || } | d} | |dkrtj|| ddd\}}| |kr|| | d|| || <|| | d<|| | d|| || <|| | d<| || d| | | | <| || d<t || df || ddf }t || df || ddf }t || df || ddf }t || df || ddf }t d||d}t d||d}t||}t|| | | | d|}t|| |}||| d|| d<q|ddd 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)rmrarangefloatviewcatrangeclonemaxr6r!maximumrqminimumrndivexprr)r r`rarbNindexesx1y1x2y2areasrOZtscoreposZmaxscoremaxposZxx1Zyy1Zxx2Zyy2whinterovrweightZ idxs_keepr+r+r,rpsb        (((( rpc Cstj|ddddgjtjd}tj|jjtjd}|jj}t|||d}|}||tj ||||}}}t j |t j |ddt j |ddgdd} t j| ddddd d gd } | S) zperform 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`rrrrrrZnew_dfr+r+r,rCs2   r)rNr )rr.r ) NNrTrUrVFTFrWrXNr )rWrX)rV)rFpandasr;PILrrqr!rHrrrrasteriorhZtorchvision.opsrlibs.deepforestrrrr-rSrrprr+r+r+r,s<       0 @  @