From f58966a8cb91f4f35a43042da3538f302cf3cdff Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Mon, 12 Jul 2021 15:14:27 -0700 Subject: [PATCH 1/4] Handle non-GeoTIFF TIFF files --- canopycover.py | 25 +++++++++++++++++++++---- requirements.txt | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/canopycover.py b/canopycover.py index 98cea7c..0758995 100755 --- a/canopycover.py +++ b/canopycover.py @@ -10,6 +10,7 @@ import subprocess import tempfile from typing import Union +import cv2 import numpy as np from agpypeline import entrypoint, algorithm, geoimage from agpypeline.checkmd import CheckMD @@ -88,6 +89,22 @@ def _add_image_mask(source_file: str) -> np.ndarray: return pixels +def _add_image_mask_non_geo(pxarray: np.ndarray) -> np.ndarray: + """Adds an alpha channel to an image that isn't geo-referenced + Arguments: + pxarray: the image array to add an alpha channel to + Return: + Returns the image with an alpha channel added + Note: no check is made to see if the image already has an alpha channel + """ + rolled_image = np.rollaxis(pxarray, 0, 3) + channel1 = rolled_image[:, :, 0] + channel2 = rolled_image[:, :, 1] + channel3 = rolled_image[:, :, 2] + alpha = np.ones(channel1.shape, dtype=channel1.dtype) * 255 + return np.rollaxis(cv2.merge((channel1, channel2, channel3, alpha)), 2, 0) + + def get_fields() -> list: """Returns the supported field names as a list """ @@ -357,9 +374,9 @@ def perform_process(self, environment: Environment, check_md: CheckMD, transform continue image_bounds = geoimage.get_image_bounds(one_file) - if not image_bounds: - logging.info("Image file does not appear to be geo-referenced '%s'", one_file) - continue + # if not image_bounds: + # logging.info("Image file does not appear to be geo-referenced '%s'", one_file) + # continue overlap_plots = [os.path.basename(os.path.dirname(one_file))] @@ -380,7 +397,7 @@ def perform_process(self, environment: Environment, check_md: CheckMD, transform image_to_use = pxarray else: logging.info('Adding missing alpha channel to loaded image from "%s"', one_file) - image_to_use = _add_image_mask(one_file) + image_to_use = _add_image_mask(one_file) if image_bounds else _add_image_mask_non_geo(pxarray) del pxarray # Potentially free up memory logging.debug("Calculating canopy cover") diff --git a/requirements.txt b/requirements.txt index f22bb9d..989ade2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ +opencv-contrib-python-headless agpypeline \ No newline at end of file From 7a10a6b969969db99c68860ad98416263e66ef75 Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Mon, 12 Jul 2021 15:34:07 -0700 Subject: [PATCH 2/4] Adding test --- .github/workflows/testing_checks.yaml | 3 +- test_data/three_channel_mask.tif | Bin 0 -> 893136 bytes tests/test_canopy_cover.py | 56 ++++++++++++++++++++++++-- 3 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 test_data/three_channel_mask.tif diff --git a/.github/workflows/testing_checks.yaml b/.github/workflows/testing_checks.yaml index dd730aa..23808d9 100644 --- a/.github/workflows/testing_checks.yaml +++ b/.github/workflows/testing_checks.yaml @@ -51,7 +51,7 @@ jobs: - name: Fetch source code uses: actions/checkout@v2 - name: Finding files to process - run: find . -type f -name "*.py" | grep -v '/tests/' > action_test_files.txt + run: find . -type f -name "*.py" > action_test_files.txt - name: Install system requirements shell: bash run: 'sudo apt-get install -y python3-gdal gdal-bin libgdal-dev gcc g++ python3.8-dev' @@ -69,6 +69,7 @@ jobs: run: 'if [ -s "requirements.txt" ]; then (python3 -m pip install --no-cache-dir -r requirements.txt) || (echo "Failed to install Python requirements" && exit 1); fi' - name: Run action pylint script shell: bash + if: ${{ matrix.app == 'pylint' }} run: 'if [ -s ".github/workflows/action_pylint.sh" ]; then (chmod +x ".github/workflows/action_pylint.sh" && ./.github/workflows/action_pylint.sh) || (echo "Error running shell script" && exit 1); fi' - name: Fetching pylint.rc file if: ${{ matrix.app == 'pylint' }} diff --git a/test_data/three_channel_mask.tif b/test_data/three_channel_mask.tif new file mode 100644 index 0000000000000000000000000000000000000000..4765bb1cb61eda333ed55077fbfbcb359f782f81 GIT binary patch literal 893136 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 literal 0 HcmV?d00001 diff --git a/tests/test_canopy_cover.py b/tests/test_canopy_cover.py index e3ef004..2d51905 100644 --- a/tests/test_canopy_cover.py +++ b/tests/test_canopy_cover.py @@ -23,6 +23,7 @@ # Path to files to use for testing META = os.path.abspath(os.path.join(TESTING_JSON_FILE_PATH, 'meta.yaml')) INPUT1 = os.path.abspath(os.path.join(TESTING_JSON_FILE_PATH, 'rgb_17_7_W.tif')) +INPUT_NO_ALPHA = os.path.abspath(os.path.join(TESTING_JSON_FILE_PATH, 'three_channel_mask.tif')) def random_string(): @@ -83,7 +84,8 @@ def test_no_metadata(): results = os.path.join(out_dir, 'result.json') assert os.path.isfile(results) - result = json.load(open(results)) + with open(results) as res_file: + result = json.load(res_file) assert 'files' in result out_files = [f['path'] for f in result['files']] @@ -92,7 +94,8 @@ def test_no_metadata(): assert os.path.isfile(canopycover) - canopy = csv.DictReader(open(canopycover)) + with open(canopycover) as cc_file: + canopy = csv.DictReader(cc_file) canopy_flds = [ 'local_datetime', 'canopy_cover', 'species', 'site', 'method' ] @@ -108,6 +111,49 @@ def test_no_metadata(): rmtree(out_dir) +def test_no_metadata_no_alpha(): + """ Run with a file that doesn't have an alpha channel, and with no metadata""" + out_dir = random_string() + + # This ought not be necessary as the program *should* + # create it; for now, we'll create the output dir. + os.makedirs(out_dir) + + try: + cmd = f'{SOURCE_PATH} --working_space {out_dir} {INPUT_NO_ALPHA}' + ret_val, _ = getstatusoutput(cmd) + assert ret_val == 0 + + results = os.path.join(out_dir, 'result.json') + assert os.path.isfile(results) + + with open(results) as res_file: + result = json.load(res_file) + assert 'files' in result + out_files = [f['path'] for f in result['files']] + + canopycover = f'{out_dir}/canopycover.csv' + assert canopycover in out_files + + assert os.path.isfile(canopycover) + + with open(canopycover) as cc_file: + canopy = csv.DictReader(cc_file) + canopy_flds = [ + 'local_datetime', 'canopy_cover', 'species', 'site', 'method' + ] + assert canopy.fieldnames == canopy_flds + + canopy_data = list(canopy) + assert len(canopy_data) == 1 + + assert canopy_data[0]['canopy_cover'] == '1.05' + + finally: + if os.path.isdir(out_dir): + rmtree(out_dir) + + def test_get_fields(): """Fetches the fields""" # pylint: disable=import-outside-toplevel @@ -199,7 +245,8 @@ def test_good_input(): results = os.path.join(out_dir, 'result.json') assert os.path.isfile(results) - result = json.load(open(results)) + with open(results) as res_file: + result = json.load(res_file) assert 'files' in result out_files = [f['path'] for f in result['files']] @@ -208,7 +255,8 @@ def test_good_input(): assert os.path.isfile(canopycover) - canopy = csv.DictReader(open(canopycover)) + with open(canopycover) as cc_file: + canopy = csv.DictReader(cc_file) canopy_flds = [ 'local_datetime', 'canopy_cover', 'species', 'site', 'method' ] From 529aeb3535147b6369ecec7d9c71bd82873af526 Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Mon, 12 Jul 2021 15:40:48 -0700 Subject: [PATCH 3/4] Silencing wrong pylint warning --- canopycover.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/canopycover.py b/canopycover.py index 0758995..5c6ed5a 100755 --- a/canopycover.py +++ b/canopycover.py @@ -102,6 +102,8 @@ def _add_image_mask_non_geo(pxarray: np.ndarray) -> np.ndarray: channel2 = rolled_image[:, :, 1] channel3 = rolled_image[:, :, 2] alpha = np.ones(channel1.shape, dtype=channel1.dtype) * 255 + # Disable this warning since 'cv2.merge' exists + # pylint: disable=no-member return np.rollaxis(cv2.merge((channel1, channel2, channel3, alpha)), 2, 0) From 09cd43cfadbc4cb4aab5563f06ec8da8c7f44557 Mon Sep 17 00:00:00 2001 From: Chris Schnaufer Date: Mon, 12 Jul 2021 15:55:13 -0700 Subject: [PATCH 4/4] Fixing up change --- tests/test_canopy_cover.py | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/tests/test_canopy_cover.py b/tests/test_canopy_cover.py index 2d51905..4320d52 100644 --- a/tests/test_canopy_cover.py +++ b/tests/test_canopy_cover.py @@ -96,15 +96,15 @@ def test_no_metadata(): with open(canopycover) as cc_file: canopy = csv.DictReader(cc_file) - canopy_flds = [ - 'local_datetime', 'canopy_cover', 'species', 'site', 'method' - ] - assert canopy.fieldnames == canopy_flds + canopy_flds = [ + 'local_datetime', 'canopy_cover', 'species', 'site', 'method' + ] + assert canopy.fieldnames == canopy_flds - canopy_data = list(canopy) - assert len(canopy_data) == 1 + canopy_data = list(canopy) + assert len(canopy_data) == 1 - assert canopy_data[0]['canopy_cover'] == '99.8' + assert canopy_data[0]['canopy_cover'] == '99.8' finally: if os.path.isdir(out_dir): @@ -139,15 +139,15 @@ def test_no_metadata_no_alpha(): with open(canopycover) as cc_file: canopy = csv.DictReader(cc_file) - canopy_flds = [ - 'local_datetime', 'canopy_cover', 'species', 'site', 'method' - ] - assert canopy.fieldnames == canopy_flds + canopy_flds = [ + 'local_datetime', 'canopy_cover', 'species', 'site', 'method' + ] + assert canopy.fieldnames == canopy_flds - canopy_data = list(canopy) - assert len(canopy_data) == 1 + canopy_data = list(canopy) + assert len(canopy_data) == 1 - assert canopy_data[0]['canopy_cover'] == '1.05' + assert canopy_data[0]['canopy_cover'] == '1.05' finally: if os.path.isdir(out_dir): @@ -257,15 +257,15 @@ def test_good_input(): with open(canopycover) as cc_file: canopy = csv.DictReader(cc_file) - canopy_flds = [ - 'local_datetime', 'canopy_cover', 'species', 'site', 'method' - ] - assert canopy.fieldnames == canopy_flds + canopy_flds = [ + 'local_datetime', 'canopy_cover', 'species', 'site', 'method' + ] + assert canopy.fieldnames == canopy_flds - canopy_data = list(canopy) - assert len(canopy_data) == 1 + canopy_data = list(canopy) + assert len(canopy_data) == 1 - assert canopy_data[0]['canopy_cover'] == '99.8' + assert canopy_data[0]['canopy_cover'] == '99.8' finally: if os.path.isdir(out_dir):