/remseno

Remote Sensing

Primary LanguageJupyter NotebookGNU General Public License v3.0GPL-3.0

remseno

A package for predicting tree species using remote sensing data (either drone orthomosaic or satellite data).

install

pip install dist/remseno-0.0.1.tar.gz

You will also need to install the planet scope API, we recommend going to https://github.com/planetlabs/planet-client-python and following the steps, otherwise you can use the prebuilt version we downloaded to run this:

pip install other_software/planet-client-python-2.0.3.tar.gz

quick start

You need: a coordinate file (which has the tree ID, tree label (i.e. class), X, and Y coordinates, and you should know the coordinate reference system).

example with RBG data from drone footage

load in coordinate file

from remseno import *
coordinate_file_path = f'../data/dryad_trees/QGIS/Annotations.csv' 
c = Coords(coordinate_file_path, x_col='Y', y_col='X', label_col='class',
                   id_col='id', sep=',', class1='RedCedar', class2='Pine', crs="EPSG:21781")

load in ortho or satellite image data

from remseno import *
drone_ortho = '../data/dryad_trees/Stitch_Image/20190518_pasture_100ft_RGB_GCPs_Forest.tif'
o = Image()
o.load_image(image_path=drone_ortho)

Once the image has been loaded it will print out the coordinate reference system, if that differs to the one used in the image you'll need to change coordinates

optionally: update coordinate system

c.transform_coords(tree_coords="EPSG:4326", image_coords="EPSG:32614", plot=True)

run through the pipeline

  1. Plot your coords on the image as points
c.plot_on_image(image=o, band=1)
  1. Plot bounding boxes (in metres) around your coordinates (ToDo)
  2. Plot multiple bands downsample = reduce quality of image this makes it faster!
o.plot_multi_bands(bands=[1, 2, 3], downsample=10, show_plot=True)
  1. Plot each class as a subset individually (ToDo)
  2. Perform classification First you need to pick a classifier, this depends on your problem and interests, anything from sklearn can be passed: e.g. https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state=0)

Then you just pass that to the classifier function and you get back a dataframe with your predictions based on the pixels: The max_pixel_padding tells you how many pixels will be included as training (this is the circle around each central location).

ml = ML()
ml_df = ml.train_ml(clf, image=o, bands=[1, 2, 3], coords=c, normalise=True, max_pixel_padding=1)
ml_df

example with hyperspectral satellite data

This is basically the same as above, except we can create indicies and masks.

load in coordinate file

from remseno import *
coordinate_file_path = '../data/tallo/planetscope/planetscope_test.csv'
c = Coords(coordinate_file_path, x_col='latitude', y_col='longitude', label_col='tree_id',
           id_col='tree_id', sep=',', class1='T_498824', class2='T_498824', crs="EPSG:4326")

load in ortho or satellite image data

from remseno import *
sat = '../data/tallo/planetscope/sat_data/dab9fa59-4a98-4319-ad5f-acea23bc6feb/PSScene/20230113_230924_81_241e_3B_AnalyticMS_SR_8b_clip.tif'
o = Image()
o.load_image(image_path=sat)

Once the image has been loaded it will print out the coordinate reference system, if that differs to the one used in the image you'll need to change coordinates

optionally: update coordinate system

c.transform_coords(tree_coords="EPSG:4326", image_coords="EPSG:32755", plot=True)

run through the pipeline

  1. Plot your coords on the image as points
c.plot_on_image(image=o, band=1)
  1. Plot bounding boxes (in metres) around your coordinates (ToDo)
  2. Plot multiple bands downsample = reduce quality of image this makes it faster!
o.plot_multi_bands(bands=[1, 2, 3], downsample=10, show_plot=True)
  1. Plot indicies
from remseno.indices import *

ndvi = get_ndvi(image=o.image, red_band=6, nir_band=8)
o.plot_idx(ndvi)
plt.show()
  1. Make a mask on an index
ax = o.plot_rbg()
ndvi = get_ndvi(image=o.image, red_band=6, nir_band=8)
mask = o.mask_on_index(ndvi, index_cutoff=0.75)  # This is the filter for what to mask so anything < 0.75 will be masked
plt.imshow(mask*ndvi)
plt.show()
  1. Save as rbg for visualisation in other programs
o.write_as_rbg('rbg_version.tif')
  1. Perform classification First you need to pick a classifier, this depends on your problem and interests, anything from sklearn can be passed: e.g. https://scikit-learn.org/stable/modules/generated/sklearn.tree.DecisionTreeClassifier.html
from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier(random_state=0)

Then you just pass that to the classifier function and you get back a dataframe with your predictions based on the pixels: The max_pixel_padding tells you how many pixels will be included as training (this is the circle around each central location).

ml = ML()
ml_df = ml.train_ml(clf, image=o, bands=[1, 2, 3], coords=c, normalise=True, max_pixel_padding=1)
ml_df