U X gb°>ã@sdZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddlZddlmZddlmZdd„ZGdd„deƒZej ed ¡d d fd d „Zej ed ¡dd fdd„Zdd„Zd#dd„Zdd„Zdd„Zdd„Zd$dd„Zdd„Zd d„Zd!d"„ZdS)%zUtilities modeléN)Útqdm)Ú_ROOTc Csbz*t|dƒ�}tj|tjd�}W5QRXWn2tk r\}ztd ||¡ƒ‚W5d}~XYnX|S)zRead config yaml fileÚr)ÚLoaderz#There is no config at {}, yields {}N)ÚopenÚyamlÚloadÚ FullLoaderÚ ExceptionÚFileNotFoundErrorÚformat)Ú config_pathÚfÚconfigÚe©rúj/home/ec2-user/SageMaker/vegetation-management-remars2022/remars2022-workshop/libs/deepforest/utilities.pyÚ read_configs ÿrc@seZdZdZddd„ZdS)ÚDownloadProgressBarzDownload progress bar class.éNcCs&|dk r||_| |||j¡dS)z Update class attributes Args: b: bsize: tsize: Returns: N)ÚtotalÚupdateÚn)ÚselfÚbZbsizeÚtsizerrrÚ update_to#s zDownloadProgressBar.update_to)rrN)Ú__name__Ú __module__Ú __qualname__Ú__doc__rrrrrr srzdata/ZbirdTc CsŠtj ||d¡}|�r@t tj tjjdddid�¡  ¡¡}|dd}|d}zt   |d ¡}Wn$t k rˆt   d d gi¡}YnX|jd|d k�s"td  |d|d ¡ƒtddd| d¡dd��}tjj|||jd�W5QRXtd |¡ƒt   d |d gi¡}| |d ¡ntd |d ¡ƒ|d |fSzt   |d¡}Wn$t k �rvtd |¡ƒ‚YnX|jd|fSd S)a˜ Check the existence of, or download the latest model release from github Args: save_dir: Directory to save filepath, default to "data" in deepforest repo prebuilt_model: Currently only accepts "NEON", but could be expanded to include other prebuilt models. The local model will be called prebuilt_model.h5 on disk. check_release (logical): whether to check github for a model recent release. In cases where you are hitting the github API rate limit, set to False and any local model will be downloaded. If no model has been downloaded an error will raise. Returns: release_tag, output_path (str): path to downloaded model ú.ptzChttps://api.github.com/repos/Weecology/BirdDetector/releases/latestÚAcceptúapplication/vnd.github.v3+json©ÚheadersÚassetsrÚbrowser_download_urlzcurrent_bird_release.csvÚcurrent_bird_releaseNÚhtml_urlzBDownloading model from BirdDetector release {}, see {} for detailsÚtag_nameÚBTrú/éÿÿÿÿ©ÚunitÚ unit_scaleÚminitersÚdesc©ÚfilenameÚ reporthookú$Model was downloaded and saved to {}zXModel from BirdDetector Repo release {} was already downloaded. Loading model from file.úcurrent_release.csvúKCheck release argument is {}, but no release has been previously downloaded)ÚosÚpathÚjoinÚjsonÚloadsÚurllibÚrequestÚurlopenÚRequestÚreadÚpdÚread_csvÚ BaseExceptionÚ DataFramer(Úprintr rÚsplitÚ urlretrieverÚto_csvÚ ValueErrorÚcurrent_release© Úsave_dirZprebuilt_modelÚ check_releaseÚ output_pathÚ_jsonÚassetÚurlZ release_txtÚtrrrÚuse_bird_release2sP þÿÿ ÿ ýÿ rUÚNEONc CsŠtj ||d¡}|�r@t tj tjjdddid�¡  ¡¡}|dd}|d}zt   |d ¡}Wn$t k rˆt   d d gi¡}YnX|jd|d k�s"td  |d|d ¡ƒtddd| d¡dd��}tjj|||jd�W5QRXtd |¡ƒt   d |d gi¡}| |d ¡ntd |d ¡ƒ|d |fSzt   |d ¡}Wn$t k �rvtd |¡ƒ‚YnX|jd|fSd S)a¡ Check the existence of, or download the latest model release from github Args: save_dir: Directory to save filepath, default to "data" in deepforest repo prebuilt_model: Currently only accepts "NEON", but could be expanded to include other prebuilt models. The local model will be called prebuilt_model.h5 on disk. check_release (logical): whether to check github for a model recent release. In cases where you are hitting the github API rate limit, set to False and any local model will be downloaded. If no model has been downloaded an error will raise. Returns: release_tag, output_path (str): path to downloaded model r!zAhttps://api.github.com/repos/Weecology/DeepForest/releases/latestr"r#r$r&rr'r7rLNr)z@Downloading model from DeepForest release {}, see {} for detailsr*r+Trr,r-r.r3r6zQModel from DeepForest release {} was already downloaded. Loading model from file.r8)r9r:r;r<r=r>r?r@rArBrCrDrErFrLrGr rrHrIrrJrKrMrrrÚ use_releaseosP þÿÿ ÿ ýÿ rWc Csªt|ƒ�}t | ¡¡}W5QRXz|dd}Wn8tk rj}ztd |||d¡ƒ‚W5d}~XYnXg}g}g}g}g} t|tƒrì|D]Z} | | dd¡| | dd¡| | dd¡| | dd ¡|  | d ¡qŽnV| |dd¡| |dd¡| |dd¡| |dd ¡|  |d ¡t j   |dd ¡} d d „|Dƒ}dd „|Dƒ}dd „|Dƒ}dd „|Dƒ}t   | ||||| dœ¡} | S)aK Load annotations from xml format (e.g. RectLabel editor) and convert them into retinanet annotations format. Args: xml_path (str): Path to the annotations xml, formatted by RectLabel Returns: Annotations (pandas dataframe): in the format -> path-to-image.png,x1,y1,x2,y2,class_name Ú annotationÚobjectz*error {} for path {} with doc annotation{}NZbndboxÚxminÚxmaxÚyminÚymaxÚnamer4cSsg|] }t|ƒ‘qSr©Úround_with_floats©Ú.0ÚxrrrÚ Úsz&xml_to_annotations..cSsg|] }t|ƒ‘qSrr_rarrrrdÛscSsg|] }t|ƒ‘qSrr_rarrrrdÜscSsg|] }t|ƒ‘qSrr_rarrrrdÝs)Ú image_pathrZr\r[r]Úlabel)rÚ xmltodictÚparserBr r Ú isinstanceÚlistÚappendr9r:ÚbasenamerCrF) Zxml_pathÚfdÚdocZtile_xmlrrZr[r\r]rfÚtreeZrgb_nameÚ annotationsrrrÚxml_to_annotations­sR ÿ úrqÚ.c CsRt |¡}|jj}t |¡�}|j\}}}} |jd} W5QRX|j|| |d<|d t ¡|d<|j || |d<|d t ¡|d<| |j | |d<|d t ¡|d<| |j | |d<|d t ¡|d<d|j krè|d|d<nd|d<tj |¡|d<|ddddddg} | jd d d d d œd�} | | j| jk} | | j| jk} | S)aˆ Convert a shapefile of annotations into annotations csv file for DeepForest training and evaluation Args: shapefile: Path to a shapefile on disk. If a label column is present, it will be used, else all labels are assumed to be "Tree" rgb: Path to the RGB image on disk savedir: Directory to save csv files Returns: results: a pandas dataframe rÚ tile_xminÚ tile_xmaxÚ tile_ymaxÚ tile_yminrfÚTreererZr\r[r])rsrvrtru©Úcolumns)ÚgpdÚ read_fileÚgeometryÚboundsÚrasteriorÚresÚminxÚastypeÚintÚmaxxÚminyÚmaxyryr9r:rlÚrenamerZr[r\r]) Z shapefileÚrgbÚsavedirÚgdfÚdfÚsrcÚleftÚbottomÚrightÚtopÚ resolutionÚresultrrrÚshapefile_to_annotationsêsD   ÿü r’cCsBz t|ƒ}Wn0tk r<t d¡tt t|ƒ¡ƒ}YnX|S)zACheck if string x is float or int, return int, rounded if needed.aAnnotations file contained non-integer coordinates. These coordinates were rounded to nearest int. All coordinates must correspond to pixels in the image coordinate system. If you are attempting to use projected data, first convert it into image coordinates see FAQ for suggestions.)r‚rEÚwarningsÚwarnÚnpÚroundÚfloat)rcr‘rrrr`)s ÿr`cs"t‡fdd„dDƒƒstdƒ‚ˆS)z:Check a file format for correct column names and structurec3s|]}|ˆjkVqdS©Nrxra©rŠrrÚ =sÿzcheck_file..)rerZr[r\r]rfzyInput file has incorrect column names, the following columns must exist 'image_path','xmin','ymin','xmax','ymax','label'.)ÚallÚIOErrorr™rr™rÚ check_file:s ÿÿr�cCs"|jddkstd |j¡ƒ‚dS)z“Check an image is three channel, channel last format Args: image: numpy array Returns: None, throws error on assert éézUimage is expected have three channels, channel last format, found image with shape {}N)ÚshaperKr )ÚimagerrrÚ check_imageFsr¢c Cs|j ¡}t|ƒdkr&td |¡ƒ‚n|d}d ||¡}t |¡�}|j}|j\}} |j } W5QRX|rÚ|d  t ¡||j |d<|d  t ¡||j |d<|j |d  t ¡| |d<|j |d  t ¡| |d<|jd d „dd �|d <tj|d d �}| |_ |S)av Convert from image coordinates to geographic coordinates Note that this assumes df is just a single plot being passed to this function df: a pandas type dataframe with columns: name, xmin, ymin, xmax, ymax. Name is the relative path to the root_dir arg. root_dir: directory of images transform: If true, convert from image to geographic coordinates rúQThis function projects a single plots worth of data. Multiple plot names found {}rú{}/{}rZr[r\r]cSstj |j|j|j|j¡Sr˜)Úshapelyr|ÚboxrZr\r[r]©rcrrrÚoózproject_boxes..)Úaxisr|©r|)reÚuniqueÚlenrKr r~rr}rÚcrsr�r—rŒr�ÚapplyrzÚ GeoDataFrame) rŠÚroot_dirÚ transformÚ plot_namesÚ plot_nameÚrgb_pathÚdatasetr}Z pixelSizeXZ pixelSizeYr®rrrÚ project_boxesOs2  ÿÿ   ÿ r·c Csltjj||j|jdd�\}}tjj||j|jdd�\}}t||||ƒ}dd„|Dƒ}tj ||d�} || _ | S)aˆ Convert output from predict_image and predict_tile to a geopandas data.frame Args: df: prediction data.frame with columns ['xmin','ymin','xmax','ymax','label','score'] transform: A rasterio affine transform object crs: A rasterio crs object Returns: results: a geopandas dataframe where every entry is the bounding box for a detected tree. Úcenter)r²ÚrowsÚcolsÚoffsetcSs&g|]\}}}}tj ||||¡‘qSr)r¥r|r¦)rbrZr\r[r]rrrrd’s z,annotations_to_shapefile..r«) r~r²Úxyr\rZr]r[Úziprzr°r®) rŠr²r®Z xmin_coordsZ ymin_coordsZ xmax_coordsZ ymax_coordsZ box_coordsZ box_geomsÚgeodfrrrÚannotations_to_shapefilevs" ü ü r¿c Csv|j ¡}t|ƒdkr&td |¡ƒ‚n|d}d ||¡}t |¡�}|j}|j}W5QRXt |||d�}||d<|S)a¡ Convert output from predict_file into a geopandas data.frame Note that this assumes df is just a single plot being passed to this function Args: df: a pandas type dataframe with columns: image_path, xmin, ymin, xmax, ymax. image_path is the relative within the root_dir arg. root_dir: directory of images Returns: geodf: a geodataframe with transformed boxes as geometry rr£rr¤)rŠr²r®re) rer¬r­rKr r~rr²r®r¿) rŠr±r³r´rµr¶r²r®r¾rrrr·™s  ÿÿ  cCsttdd„|ƒƒ}tt|ŽƒS)NcSs|dk Sr˜rr§rrrr¨µr©zcollate_fn..)rjÚfilterÚtupler½)ÚbatchrrrÚ collate_fn´srÃ)rr)T) r r<r9r>r“Ú geopandasrzÚnumpyr•ÚpandasrCr~r¥rgrrÚlibs.deepforestrrrr:r;rUrWrqr’r`r�r¢r·r¿rÃrrrrÚs4   =>= ?  '#