diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f4db1ac --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at ethan@weecology.org. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version] + +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/4/ diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..7ca55b6 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,34 @@ +Package: deepforestr +Title: R Interface to the Deepforest package +Description: Provides an R interface to the Deepforest + via the Deepforest's + command line interface. The Deepforest is a python package for training and predicting individual tree crowns from airborne RGB imagery. +Version: 0.0.1 +Authors@R: c(person("Ben", "G", "Weinstein", role = "aut", + email = "benweinstein2010@gmail.com", + comment = c(ORCID = "0000-0002-2176-7935")), + person("Henry", "Senyondo", role = c("aut", "cre"), + email = "henrykironde@gmail.com", + comment = c(ORCID = "0000-0001-7105-5808")), + person("Ethan", "White", role = "aut", + email = "ethan@weecology.org", + comment = c(ORCID = "0000-0001-6728-7745"))) +BugReports: https://github.com/weecology/DeepForest/issues +URL: https://github.com/weecology/DeepForest/ (website), + https://github.com/weecology/DeepForest/ +Depends: + R (>= 3.4.0) +Imports: + reticulate (>= 1.16), + semver +Suggests: + testthat (>= 1.0.0), + devtools, + knitr, + rmarkdown +VignetteBuilder: knitr +SystemRequirements: Python (>= 3.0) (version must be listed to patch to allow parsing) +License: MIT + file LICENSE +LazyData: true +RoxygenNote: 7.1.1 +Encoding: UTF-8 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ff10aa7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +FROM rocker/tidyverse:latest + +MAINTAINER Weecology "https://github.com/weecology/deepforestr" + +# Write enviromental options to config files +RUN echo "options(repos='https://cloud.r-project.org/')" >> ~/.Rprofile +RUN echo "options(repos='https://cloud.r-project.org/')" >> ~/.Renviron +RUN echo "R_LIBS=\"/usr/lib/R/library\"">> ~/.Rprofile +RUN echo "R_LIBS=\"/usr/lib/R/library\"">> ~/.Renviron +RUN echo "R_LIBS_USER=\"/usr/lib/R/library\"">> ~/.Renviron + +RUN apt-get update && apt-get install -y --no-install-recommends apt-utils +RUN apt-get install -y --force-yes build-essential wget git locales locales-all > /dev/null + +# Set encoding +ENV LC_ALL en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US.UTF-8 + +# Remove python2 and install python3 +RUN apt-get remove -y python && apt-get install -y python3 python3-pip curl +RUN rm -f /usr/bin/python && ln -s /usr/bin/python3 /usr/bin/python +RUN rm -f /usr/bin/pip && ln -s /usr/bin/pip3 /usr/bin/pip + +RUN echo "export PATH="/usr/bin/python:$PATH"" >> ~/.profile +RUN echo "export PYTHONPATH="/usr/bin/python:$PYTHONPATH"" >> ~/.profile + + +# Add permissions to config files +RUN chmod 0644 ~/.Renviron +RUN chmod 0644 ~/.Rprofile +RUN chmod 0644 ~/.profile + +# Install deepforest python package +RUN pip install pillow +# h5py, pillow, kaggle fail to install from the requirement file. +RUN pip install git+https://git@github.com/weecology/DeepForest.git +RUN R_RETICULATE_PYTHON="/usr/bin/python" | echo $R_RETICULATE_PYTHON >> ~/.Renviron + +COPY . ./deepforestr + +WORKDIR ./deepforestr + + +CMD ["bash", "-c", "deepforestr -v"] diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..7d0993a --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,5 @@ +# Generated by roxygen2: do not edit by hand + +export(get_data) +importFrom(reticulate,import) +importFrom(reticulate,r_to_py) diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..86e92b7 --- /dev/null +++ b/NEWS.md @@ -0,0 +1,3 @@ + +deepforestr 1.0.0 +================= diff --git a/R/deepforestr.R b/R/deepforestr.R new file mode 100644 index 0000000..aff1102 --- /dev/null +++ b/R/deepforestr.R @@ -0,0 +1,26 @@ +#' Check for updates +#' +#' @param repo path to the repository +#' +#' @examples +#' \donttest{ +#' deepforest::get_data() +#' } +#' @importFrom reticulate import r_to_py +#' @export +get_data <- function(repo = "") { + writeLines(strwrap("Please wait while the retriever updates its scripts, ...")) + deepforest$get_data(repo) +} + +# global reference to python modules (will be initialized in .onLoad) +deepforest <- NULL + +.onLoad <- function(libname, pkgname) { + ## assignment in parent environment! + try({ + deepforest <<- reticulate::import("deepforest", delay_load = TRUE) + # Disable due to failure to test on win cran dev platform + # check_deepforest_availability() + }, silent = TRUE) +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c50cae5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3' + +services: + + rdata: + container_name: deepforestr_container + image: deepforestr_image + command: bash -c "python --version" + environment: + # If IN_DOCKER is set, + # Otherwise use local + "IN_DOCKER" : "true" + "NOT_CRAN" : "true" + build: . diff --git a/load_and_test.R b/load_and_test.R new file mode 100644 index 0000000..762857a --- /dev/null +++ b/load_and_test.R @@ -0,0 +1,17 @@ +# Used for continous testing platform +# Install analysis packages using pacman +# Pacman will load the packages and install +# the packaes not available + +if (Sys.getenv("IN_DOCKER") == "true") { + # Install pacman if it isn't already installed + if ("pacman" %in% rownames(installed.packages()) == FALSE) install.packages("pacman") + suppressMessages( + pacman::p_load(devtools, readr, rmarkdown, + testthat, tidyverse, reticulate, semver) + ) + + devtools::install_local(".", force = TRUE) + # Test package + test_dir("tests/testthat", reporter = c("check", "progress")) +} diff --git a/man/get_data.Rd b/man/get_data.Rd new file mode 100644 index 0000000..b275ca8 --- /dev/null +++ b/man/get_data.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/deepforestr.R +\name{get_data} +\alias{get_data} +\title{Check for updates} +\usage{ +get_data(repo = "") +} +\arguments{ +\item{repo}{path to the repository} +} +\description{ +Check for updates +} +\examples{ +\donttest{ +deepforest::get_data() +} +} diff --git a/paper/paper.bib b/paper/paper.bib new file mode 100644 index 0000000..55f321a --- /dev/null +++ b/paper/paper.bib @@ -0,0 +1,26 @@ +@Article{rs11111309, +AUTHOR = {Weinstein, Ben G. and Marconi, Sergio and Bohlman, Stephanie and Zare, Alina and White, Ethan}, +TITLE = {Individual Tree-Crown Detection in RGB Imagery Using Semi-Supervised Deep Learning Neural Networks}, +JOURNAL = {Remote Sensing}, +VOLUME = {11}, +YEAR = {2019}, +NUMBER = {11}, +ARTICLE-NUMBER = {1309}, +URL = {https://www.mdpi.com/2072-4292/11/11/1309}, +ISSN = {2072-4292}, +ABSTRACT = {Remote sensing can transform the speed, scale, and cost of biodiversity and forestry surveys. Data acquisition currently outpaces the ability to identify individual organisms in high resolution imagery. We outline an approach for identifying tree-crowns in RGB imagery while using a semi-supervised deep learning detection network. Individual crown delineation has been a long-standing challenge in remote sensing and available algorithms produce mixed results. We show that deep learning models can leverage existing Light Detection and Ranging (LIDAR)-based unsupervised delineation to generate trees that are used for training an initial RGB crown detection model. Despite limitations in the original unsupervised detection approach, this noisy training data may contain information from which the neural network can learn initial tree features. We then refine the initial model using a small number of higher-quality hand-annotated RGB images. We validate our proposed approach while using an open-canopy site in the National Ecological Observation Network. Our results show that a model using 434,551 self-generated trees with the addition of 2848 hand-annotated trees yields accurate predictions in natural landscapes. Using an intersection-over-union threshold of 0.5, the full model had an average tree crown recall of 0.69, with a precision of 0.61 for the visually-annotated data. The model had an average tree detection rate of 0.82 for the field collected stems. The addition of a small number of hand-annotated trees improved the performance over the initial self-supervised model. This semi-supervised deep learning approach demonstrates that remote sensing can overcome a lack of labeled training data by generating noisy data for initial training using unsupervised methods and retraining the resulting models with high quality labeled data.}, +DOI = {10.3390/rs11111309} +} + +@article {Weinstein790071, + author = {Weinstein, Ben. G. and Marconi, Sergio and Bohlman, Stephanie A. and Zare, Alina and White, Ethan P.}, + title = {Geographic Generalization in Airborne RGB Deep Learning Tree Detection}, + elocation-id = {790071}, + year = {2019}, + doi = {10.1101/790071}, + publisher = {Cold Spring Harbor Laboratory}, + abstract = {Tree detection is a fundamental task in remote sensing for forestry and ecosystem ecology applications. While many individual tree segmentation algorithms have been proposed, the development and testing of these algorithms is typically site specific, with few methods evaluated against data from multiple forest types simultaneously. This makes it difficult to determine the generalization of proposed approaches, and limits tree detection at broad scales. Using data from the National Ecological Observatory Network we extend a recently developed semi-supervised deep learning algorithm to include data from a range of forest types, determine whether information from one forest can be used for tree detection in other forests, and explore the potential for building a universal tree detection algorithm. We find that the deep learning approach works well for overstory tree detection across forest conditions, outperforming conventional LIDAR-only methods in all forest types. Performance was best in open oak woodlands and worst in alpine forests. When models were fit to one forest type and used to predict another, performance generally decreased, with better performance when forests were more similar in structure. However, when models were pretrained on data from other sites and then fine-tuned using a small amount of hand-labeled data from the evaluation site, they performed similarly to local site models. Most importantly, a universal model fit to data from all sites simultaneously performed as well or better than individual models trained for each local site. This result suggests that RGB tree detection models that can be applied to a wide array of forest types at broad scales should be possible.}, + URL = {https://www.biorxiv.org/content/early/2019/10/02/790071}, + eprint = {https://www.biorxiv.org/content/early/2019/10/02/790071.full.pdf}, + journal = {bioRxiv} +} diff --git a/paper/paper.md b/paper/paper.md new file mode 100644 index 0000000..1b4c790 --- /dev/null +++ b/paper/paper.md @@ -0,0 +1,51 @@ +--- +title: 'DeepForestR: R Interface to the Data DeepForest' +tags: + - data retrieval, data processing, R, data, data science, datasets +authors: + - name: Henry Senyondo + orcid: 0000-0001-7105-5808 + affiliation: 1, 3 + - name: Ben G Weinstein + orcid: 0000-0002-2176-7935 + affiliation: 1,3 + - name: Ethan White + affiliation: 1, 2, 3 + orcid: 0000-0001-6728-7745 + + +affiliations: + - name: Department of Wildlife Ecology and Conservation, University of Florida + index: 1 + - name: Informatics Institute, University of Florida + index: 2 + - name: The University of Florida + index: 3 + + +date: 16 June 2021 +bibliography: paper.bib +--- + +# DeepForestR: An R package for training and predicting individual tree crowns from airborne RGB imagery. + +## Summary + +The DeepForestR ... + +## Statement of Need + +A pytorch implementation of the DeepForest model for individual tree crown detection in RGB images. DeepForest is a python package for training and predicting individual tree crowns from airborne RGB imagery. DeepForest comes with a prebuilt model trained on data from the National Ecological Observatory Network. Users can extend this model by annotating and training custom models starting from the prebuilt model. + +## Implementation + +The main .... + +## Acknowledgements + +Development of this software was funded by +[the Gordon and Betty Moore Foundation's Data-Driven Discovery Initiative](http://www.moore.org/programs/science/data-driven-discovery) through +[Grant GBMF4563](http://www.moore.org/grants/list/GBMF4563) to Ethan P. White. + +## References + diff --git a/tests/testthat.R b/tests/testthat.R new file mode 100644 index 0000000..7b7ce07 --- /dev/null +++ b/tests/testthat.R @@ -0,0 +1,5 @@ +library("testthat") +library("devtools") + +test_check("deepforestr") +