# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# # Forest: Tree crown detection
#
# ## Context
# ### Purpose
# Detect tree crown using state-of-art models
#
# ### Modelling approach
# A prebuilt Deep Learning model, named _DeepForest_, is used to predict individual tree crowns from an airborne RGB image.
#
# ### Highlights
# * _DeepForest_ was trained on data from the National Ecological Observatory Network.
#
# ### Authors
# <NAME>, The Alan Turing Institute, [@acocac](https://github.com/acocac)
#
# :::{note}
# The author acknowledges [DeepForest](https://deepforest.readthedocs.io/en/latest/) contributors. Some code snippets were extracted from DeepForest [GitHub public repository](https://github.com/weecology/DeepForest).
# :::

# ## Install and load libraries

# + pycharm={"name": "#%%\n"}
# !pip -q install git+https://github.com/ESM-VFC/intake_zenodo_fetcher.git ##Intake Zenodo Fetcher
# !pip -q install DeepForest

# + pycharm={"name": "#%%\n"}
import glob
import os
import urllib

import intake
from intake_zenodo_fetcher import download_zenodo_files_for_entry
import matplotlib.pyplot as plt
import xmltodict
import cv2

import tempfile

# %matplotlib inline
# -

# ## Fetch a RGB image from Zenodo

# + pycharm={"name": "#%%\n"}
# create a temp dir
path = tempfile.mkdtemp()

catalog_file = os.path.join(path, 'catalog.yaml')

with open(catalog_file, 'w') as f:
    f.write('''
sources:
  NEONTREE_rgb:
    driver: xarray_image
    description: 'NeonTreeEvaluation RGB images (collection)'
    metadata:
      zenodo_doi: "10.5281/zenodo.3459803"
    args:
      urlpath: "{{ CATALOG_DIR }}/NEONsample_RGB/2018_MLBS_3_541000_4140000_image_crop.tif"
      ''')

# + pycharm={"name": "#%%\n"}
cat_tc = intake.open_catalog('tc.yaml')

# + pycharm={"name": "#%%\n"}
for catalog_entry in list(cat_tc):
    download_zenodo_files_for_entry(
        cat_tc[catalog_entry],
        force_download=False
    )

# + pycharm={"name": "#%%\n"}
tc_rgb = cat_tc["NEONTREE_rgb"].to_dask()

# + pycharm={"name": "#%%\n"}
tc_rgb

# + [markdown] pycharm={"name": "#%% md\n"}
# ## Load and prepare labels

# + pycharm={"name": "#%%\n"}
filenames = glob.glob('./NEONsample_RGB/*.tif')
filesn = [os.path.basename(i) for i in filenames]


# + pycharm={"name": "#%%\n"}
##Create ordered dictionary of .xml annotation files
def loadxml(imagename):
  imagename = imagename.replace('.tif','')
  fullurl = "https://raw.githubusercontent.com/weecology/NeonTreeEvaluation/master/annotations/" + imagename + ".xml"
  file = urllib.request.urlopen(fullurl)
  data = file.read()
  file.close()
  data = xmltodict.parse(data)
  return data

allxml = [loadxml(i) for i in filesn]


# + pycharm={"name": "#%%\n"}
# function to extract bounding boxes
def extractbb(i):
  bb = [f['bndbox'] for f in allxml[i]['annotation']['object']]
  return bb

bball = [extractbb(i) for i in range(0,len(allxml))]
print(len(bball))


# -

# ## Visualise image and labels

# + pycharm={"name": "#%%\n"}
# function to plot images
def cv2_imshow(a, **kwargs):
    a = a.clip(0, 255).astype('uint8')
    # cv2 stores colors as BGR; convert to RGB
    if a.ndim == 3:
        if a.shape[2] == 4:
            a = cv2.cvtColor(a, cv2.COLOR_BGRA2RGBA)
        else:
            a = cv2.cvtColor(a, cv2.COLOR_BGR2RGB)

    return plt.imshow(a, **kwargs)


# + pycharm={"name": "#%%\n"}
image = tc_rgb

# + pycharm={"name": "#%%\n"}
# plot predicted bbox
image2 = image.values.copy()
target_bbox = bball[0]

for row in target_bbox:
    cv2.rectangle(image2, (int(row["xmin"]), int(row["ymin"])), (int(row["xmax"]), int(row["ymax"])), (0, 0, 0), thickness=10, lineType=cv2.LINE_AA)

plt.figure(figsize=(15,15))
cv2_imshow(image2)
plt.show()
# -

# ## Load *DeepForest* pretrained model

# + pycharm={"name": "#%%\n"}
from deepforest import main

# + pycharm={"name": "#%%\n"}
# load deep forest model
model = main.deepforest()
model.use_release()

# + pycharm={"name": "#%%\n"}
#boxes = model.predict_image(image=image.values)
#print(boxes)

StarcoderdataJupyterScriptsDedupFiltered