Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modified boxes_to_shapefile function #597

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions deepforest/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,13 @@ def check_image(image):
"found image with shape {}".format(image.shape))


def boxes_to_shapefile(df, root_dir, projected=True, flip_y_axis=False):
def boxes_to_shapefile(df, rgb, projected=True, flip_y_axis=False):
"""
Convert from image coordinates to geographic coordinates
Note that this assumes df is just a single plot being passed to this function
Args:
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 to lookup image_path column
rgb: path for the image file
projected: If True, convert from image to geographic coordinates, if False, keep in image coordinate system
flip_y_axis: If True, reflect predictions over y axis to align with raster data in QGIS, which uses a negative y origin compared to numpy. See https://gis.stackexchange.com/questions/306684/why-does-qgis-use-negative-y-spacing-in-the-default-raster-geotransform
Returns:
Expand All @@ -401,15 +401,7 @@ def boxes_to_shapefile(df, root_dir, projected=True, flip_y_axis=False):
.format(flip_y_axis, projected), UserWarning)
projected = False

plot_names = df.image_path.unique()
if len(plot_names) > 1:
raise ValueError("This function projects a single plots worth of data. "
"Multiple plot names found {}".format(plot_names))
else:
plot_name = plot_names[0]

rgb_path = "{}/{}".format(root_dir, plot_name)
with rasterio.open(rgb_path) as dataset:
with rasterio.open(rgb) as dataset:
bounds = dataset.bounds
pixelSizeX, pixelSizeY = dataset.res
crs = dataset.crs
Expand Down
2 changes: 1 addition & 1 deletion docs/annotation.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ for path in files:
plt.imshow(fig)

#Create a shapefile, in this case img data was unprojected
shp = boxes_to_shapefile(boxes, root_dir=PATH_TO_DIR, projected=False)
shp = boxes_to_shapefile(boxes, rgb=path, projected=False)

#Get name of image and save a .shp in the same folder
basename = os.path.splitext(os.path.basename(path))[0]
Expand Down
10 changes: 5 additions & 5 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,28 +88,28 @@ def test_boxes_to_shapefile_projected(m):
img = get_data("OSBS_029.tif")
r = rio.open(img)
df = m.predict_image(path=img)
gdf = utilities.boxes_to_shapefile(df, root_dir=os.path.dirname(img), projected=True)
gdf = utilities.boxes_to_shapefile(df, rgb=img, projected=True)

#Confirm that each boxes within image bounds
geom = geometry.box(*r.bounds)
assert all(gdf.geometry.apply(lambda x: geom.intersects(geom)).values)

#Edge case, only one row in predictions
gdf = utilities.boxes_to_shapefile(df.iloc[:1,], root_dir=os.path.dirname(img), projected=True)
gdf = utilities.boxes_to_shapefile(df.iloc[:1,], rgb=img, projected=True)
assert gdf.shape[0] == 1

def test_boxes_to_shapefile_projected_from_predict_tile(m):
img = get_data("OSBS_029.tif")
r = rio.open(img)
df = m.predict_tile(raster_path=img)
gdf = utilities.boxes_to_shapefile(df, root_dir=os.path.dirname(img), projected=True)
gdf = utilities.boxes_to_shapefile(df, rgb=img, projected=True)

#Confirm that each boxes within image bounds
geom = geometry.box(*r.bounds)
assert all(gdf.geometry.apply(lambda x: geom.intersects(geom)).values)

#Edge case, only one row in predictions
gdf = utilities.boxes_to_shapefile(df.iloc[:1,], root_dir=os.path.dirname(img), projected=True)
gdf = utilities.boxes_to_shapefile(df.iloc[:1,], rgb=img, projected=True)
assert gdf.shape[0] == 1

# Test unprojected data, including warning if flip_y_axis is set to True, but projected is False
Expand All @@ -123,7 +123,7 @@ def test_boxes_to_shapefile_unprojected(m, flip_y_axis, projected):
with pytest.warns(UserWarning):
gdf = utilities.boxes_to_shapefile(
df,
root_dir=os.path.dirname(img),
rgb=img,
projected=projected,
flip_y_axis=flip_y_axis)

Expand Down
Loading