diff --git a/README.md b/README.md index 82dc7b01..150f7809 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ Python package for automatic tree crown delineation based on Mask R-CNN. Pre-trained models can be picked in the [`model_garden`](https://github.com/PatBall1/detectree2/tree/master/model_garden). -A tutorial on how to prepare data, train models and make predictions is available [here](https://patball1.github.io/detectree2/tutorial.html). For questions, collaboration proposals and requests for example data email [James Ball](mailto:ball.jgc@gmail.com). +A tutorial on how to prepare data, train models and make predictions is available [here](https://patball1.github.io/detectree2/tutorial.html). For questions, collaboration proposals and requests for data email [James Ball](mailto:ball.jgc@gmail.com). Some example data is available for download [here](https://doi.org/10.5281/zenodo.8136161). -Detectree2是一个基于Mask R-CNN的自动树冠检测与分割的Python包。您可以在[`model_garden`](https://github.com/PatBall1/detectree2/tree/master/model_garden)中选择预训练模型。[这里](https://patball1.github.io/detectree2/tutorial.html)提供了如何准备数据、训练模型和进行预测的教程。如果有任何问题,合作提案或者需要样例数据,可以邮件联系[James Ball](mailto:ball.jgc@gmail.com)。 +Detectree2是一个基于Mask R-CNN的自动树冠检测与分割的Python包。您可以在[`model_garden`](https://github.com/PatBall1/detectree2/tree/master/model_garden)中选择预训练模型。[这里](https://patball1.github.io/detectree2/tutorial.html)提供了如何准备数据、训练模型和进行预测的教程。如果有任何问题,合作提案或者需要样例数据,可以邮件联系[James Ball](mailto:ball.jgc@gmail.com)。一些示例数据可以在[这里](https://doi.org/10.5281/zenodo.8136161)下载。 Code developed by James Ball, Seb Hickman, Thomas Koay, Oscar Jiang, Luran Wang, Panagiotis Ioannou, James Hinton and Matthew Archer in the [Forest Ecology and Conservation Group](https://coomeslab.org/) at the University of Cambridge. The Forest Ecology and Conservation Group is led by Professor David Coomes and is part of the University of Cambridge [Conservation Research Institute](https://www.conservation.cam.ac.uk/). @@ -21,9 +21,7 @@ MRes project repo available [here](https://github.com/shmh40/detectreeRGB). **Warning**\ > Due to an influx of new users we have been hitting bandwidth limits. This is primarily from the file size of the pre-trained models. If you are using these models please aim to save them locally and point to them when you need them rather than downloading them each time they are required. We will move to a more bandwidth friendly set up soon. In the meantime, if installing the package is failing please raise it as an issue or notify me directly on ball.jgc@gmail.com. -## Citation - -**Please cite**: +## Please cite Ball, J.G.C., Hickman, S.H.M., Jackson, T.D., Koay, X.J., Hirst, J., Jay, W., Archer, M., Aubry-Kientz, M., Vincent, G. and Coomes, D.A. (2023), Accurate delineation of individual tree crowns in tropical forests from aerial RGB imagery using Mask R-CNN. diff --git a/detectree2/preprocessing/tiling.py b/detectree2/preprocessing/tiling.py index 249207da..26e6acbb 100644 --- a/detectree2/preprocessing/tiling.py +++ b/detectree2/preprocessing/tiling.py @@ -17,6 +17,7 @@ import numpy as np import rasterio from fiona.crs import from_epsg # noqa: F401 +from rasterio.crs import CRS from rasterio.io import DatasetReader from rasterio.mask import mask from shapely.geometry import box @@ -70,8 +71,10 @@ def tile_data( Returns: None """ - os.makedirs(out_dir, exist_ok=True) - crs = data.crs.data["init"].split(":")[1] + out_path = Path(out_dir) + os.makedirs(out_path, exist_ok=True) + crs = CRS.from_string(data.crs.wkt) + crs = crs.to_epsg() tilename = Path(data.name).stem for minx in np.arange(data.bounds[0], data.bounds[2] - tile_width, @@ -79,8 +82,7 @@ def tile_data( for miny in np.arange(data.bounds[1], data.bounds[3] - tile_height, tile_height, int): # Naming conventions - out_path_root = out_dir + tilename + "_" + str(minx) + "_" + str( - miny) + "_" + str(tile_width) + "_" + str(buffer) + "_" + crs + out_path_root = out_path / f"{tilename}_{minx}_{miny}_{tile_width}_{buffer}_{crs}" # new tiling bbox including the buffer bbox = box( minx - buffer, @@ -135,7 +137,7 @@ def tile_data( # If tile appears blank in folder can show the image here and may # need to fix RGB data or the dtype # show(out_img) - out_tif = out_path_root + ".tif" + out_tif = out_path_root.with_suffix(out_path_root.suffix + ".tif") with rasterio.open(out_tif, "w", **out_meta) as dest: dest.write(out_img) @@ -164,7 +166,7 @@ def tile_data( # save this as jpg or png...we are going for png...again, named with the origin of the specific tile # here as a naughty method cv2.imwrite( - out_path_root + ".png", + str(out_path_root.with_suffix(out_path_root.suffix + ".png").resolve()), rgb_rescaled, ) @@ -205,7 +207,8 @@ def tile_data_train( # noqa: C901 out_path = Path(out_dir) os.makedirs(out_path, exist_ok=True) tilename = Path(data.name).stem - crs = data.crs.data["init"].split(":")[1] + crs = CRS.from_string(data.crs.wkt) + crs = crs.to_epsg() # out_img, out_transform = mask(data, shapes=crowns.buffer(buffer), crop=True) # Should start from data.bounds[0] + buffer, data.bounds[1] + buffer to avoid later complications for minx in np.arange(ceil(data.bounds[0]) + buffer, data.bounds[2] - tile_width - buffer, tile_width, int):