diff --git a/docs/io_open_url.md b/docs/io_open_url.md new file mode 100644 index 000000000..5c0b803d0 --- /dev/null +++ b/docs/io_open_url.md @@ -0,0 +1,31 @@ +## Open an image from a URL + +Opens an image file stored at a URL. + +**plantcv.io.open_url**(*url*) + +**returns** img + +- **Parameters:** + - url - URL of the image file to be opened +- **Context:** + - Used to open an image file stored at a URL +- **Example use:** + +```python +from plantcv import plantcv as pcv + +# Set global debug behavior to None (default), "print" (to file), +# or "plot" (Jupyter Notebooks or X11) +pcv.params.debug = "plot" + +# Open image from URL +img = pcv.io.open_url(url="https://plantcv.org/s/plantcv-hyperspectral.png") + +``` + +**Image** + +PlantCV logo + +**Source Code:** [Here](https://github.com/danforthcenter/plantcv/blob/main/plantcv/plantcv/io/open_url.py) diff --git a/docs/updating.md b/docs/updating.md index 986b77665..333957694 100644 --- a/docs/updating.md +++ b/docs/updating.md @@ -565,6 +565,11 @@ pages for more details on the input and output variable types. * pre v3.0dev2: device, img_inv = **plantcv.invert**(*img, device, debug=None*) * post v3.0dev2: img_inv = **plantcv.invert**(*gray_img*) +#### plantcv.io.open_url + +* pre v4.2.1: NA +* post v4.2.1: img = **plantcv.io.open_url**(*url*) + #### plantcv.io.random_subset * pre v3.14.0: NA diff --git a/mkdocs.yml b/mkdocs.yml index 680661061..386607b56 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -88,6 +88,7 @@ nav: - 'Image Fusion': image_fusion.md - 'Invert': invert.md - 'I/O Functions': + - 'Open Image from URL': io_open_url.md - 'Random Subset': io_random_subset.md - 'Read Dataset': io_read_dataset.md - 'Kmeans Clustering Classifier': kmeans_classifier.md diff --git a/plantcv/plantcv/io/__init__.py b/plantcv/plantcv/io/__init__.py index bea4ee878..54b74e7df 100644 --- a/plantcv/plantcv/io/__init__.py +++ b/plantcv/plantcv/io/__init__.py @@ -1,5 +1,6 @@ from plantcv.plantcv.io.read_dataset import read_dataset from plantcv.plantcv.io.random_subset import random_subset +from plantcv.plantcv.io.open_url import open_url # add new functions to end of lists -__all__ = ["read_dataset", "random_subset"] +__all__ = ["read_dataset", "random_subset", "open_url"] diff --git a/plantcv/plantcv/io/open_url.py b/plantcv/plantcv/io/open_url.py new file mode 100644 index 000000000..e6d4e2d37 --- /dev/null +++ b/plantcv/plantcv/io/open_url.py @@ -0,0 +1,35 @@ +"""Open an image from a URL.""" +import imageio.v3 as iio +import cv2 +from plantcv.plantcv import fatal_error +from plantcv.plantcv._debug import _debug + + +def open_url(url): + """Open an image from a URL and return it as a numpy array. + + Parameters + ---------- + url : str + URL of the image to be opened. + + Returns + ------- + numpy.ndarray + Image data as a numpy array. + """ + # Read the image from the URL using imageio + image = iio.imread(url) + + # Check if the image is grayscale or RGB + if len(image.shape) not in [2, 3]: + fatal_error("Image is not RGB or grayscale.") + + if image.shape[-1] == 3: + # Convert the image to RGB format + image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR) + + # Debugging visualization + _debug(visual=image, filename="url_image.png") + + return image diff --git a/tests/plantcv/io/test_open_url.py b/tests/plantcv/io/test_open_url.py new file mode 100644 index 000000000..d63e6317c --- /dev/null +++ b/tests/plantcv/io/test_open_url.py @@ -0,0 +1,18 @@ +"""Tests for the open_url function.""" +import pytest +from plantcv.plantcv.io import open_url + + +def test_open_url(): + """PlantCV Test""" + url = ("https://github.com/danforthcenter/plantcv-tutorial-simple-rgb-workflow/blob/" + + "af312af00e21c84efe942132a1910359faadd49a/img/1_B73_sand_C_2023-04-14_10_19_07.jpg?raw=true") + rgb_img = open_url(url=url) + assert rgb_img.shape == (3456, 4608, 3) + + +def test_open_url_unsupported(): + """PlantCV Test""" + url = "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif" + with pytest.raises(RuntimeError): + _ = open_url(url=url)