From c9507ced2813d4cd6f1832b1adb933fa74cfdc77 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Mon, 15 Dec 2025 09:51:54 +0100 Subject: [PATCH 1/6] Fix threshold.triangle for empty mask. --- plantcv/plantcv/threshold/threshold_methods.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/plantcv/plantcv/threshold/threshold_methods.py b/plantcv/plantcv/threshold/threshold_methods.py index 62ff850ef..9f3cbb443 100644 --- a/plantcv/plantcv/threshold/threshold_methods.py +++ b/plantcv/plantcv/threshold/threshold_methods.py @@ -196,6 +196,15 @@ def triangle(gray_img, object_type="light", xstep=1): :param xstep: int :return bin_img: numpy.ndarray """ + + # If the image is empty, return empty image + if np.count_nonzero(gray_img) == 0: + params.device += 1 + bin_img = np.copy(gray_img) + _debug(visual=bin_img, filename=os.path.join(params.debug_outdir, + f"{params.device}_triangle_empty.png")) + return bin_img + # Calculate automatic threshold value based on triangle algorithm hist = cv2.calcHist([gray_img], [0], None, [256], [0, 255]) From d8acf3db91ae6f8bc732dd283c97b619b001fed0 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Mon, 15 Dec 2025 11:44:09 +0100 Subject: [PATCH 2/6] Test for empty mask triangle threshold. --- tests/plantcv/threshold/test_threshold_methods.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/plantcv/threshold/test_threshold_methods.py b/tests/plantcv/threshold/test_threshold_methods.py index ef66aa83f..d88a01c18 100644 --- a/tests/plantcv/threshold/test_threshold_methods.py +++ b/tests/plantcv/threshold/test_threshold_methods.py @@ -255,3 +255,10 @@ def test_dual_channels_bad_channel(): pts = [(0, 0), (255, 255)] with pytest.raises(RuntimeError): _ = dual_channels(img, x_channel='wrong_ch', y_channel='index', points=pts, above=True) + + +def test_empty_mask_triangle(): + """Test for PlantCV.""" + mask = np.zeros((100, 100)) + fmask = triangle(mask) + assert np.sum(fmask) == 0 \ No newline at end of file From 35f9480091e2ebf7eefe4bb90f7cf554f03302d9 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Mon, 15 Dec 2025 12:11:36 +0100 Subject: [PATCH 3/6] Space at the end of line. --- tests/plantcv/threshold/test_threshold_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plantcv/threshold/test_threshold_methods.py b/tests/plantcv/threshold/test_threshold_methods.py index d88a01c18..16ca55a24 100644 --- a/tests/plantcv/threshold/test_threshold_methods.py +++ b/tests/plantcv/threshold/test_threshold_methods.py @@ -261,4 +261,4 @@ def test_empty_mask_triangle(): """Test for PlantCV.""" mask = np.zeros((100, 100)) fmask = triangle(mask) - assert np.sum(fmask) == 0 \ No newline at end of file + assert np.sum(fmask) == 0 From 88e6a91cde3b741a1f35c25ff1faa86433ecd95e Mon Sep 17 00:00:00 2001 From: Nirkan Date: Mon, 15 Dec 2025 14:36:53 +0100 Subject: [PATCH 4/6] Some CI error fixes. --- plantcv/plantcv/threshold/threshold_methods.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plantcv/plantcv/threshold/threshold_methods.py b/plantcv/plantcv/threshold/threshold_methods.py index 9f3cbb443..38d2b824d 100644 --- a/plantcv/plantcv/threshold/threshold_methods.py +++ b/plantcv/plantcv/threshold/threshold_methods.py @@ -196,13 +196,11 @@ def triangle(gray_img, object_type="light", xstep=1): :param xstep: int :return bin_img: numpy.ndarray """ - # If the image is empty, return empty image if np.count_nonzero(gray_img) == 0: params.device += 1 bin_img = np.copy(gray_img) - _debug(visual=bin_img, filename=os.path.join(params.debug_outdir, - f"{params.device}_triangle_empty.png")) + _debug(visual=bin_img, filename=os.path.join(params.debug_outdir, f"{params.device}_triangle_empty.png")) return bin_img # Calculate automatic threshold value based on triangle algorithm From 4821fd487d498441fa4664dc1fb84dca0165f52c Mon Sep 17 00:00:00 2001 From: Nirkan Date: Mon, 15 Dec 2025 21:30:04 +0100 Subject: [PATCH 5/6] Fix FLK-W293 --- plantcv/plantcv/threshold/threshold_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plantcv/plantcv/threshold/threshold_methods.py b/plantcv/plantcv/threshold/threshold_methods.py index 38d2b824d..7d684ca6b 100644 --- a/plantcv/plantcv/threshold/threshold_methods.py +++ b/plantcv/plantcv/threshold/threshold_methods.py @@ -202,7 +202,7 @@ def triangle(gray_img, object_type="light", xstep=1): bin_img = np.copy(gray_img) _debug(visual=bin_img, filename=os.path.join(params.debug_outdir, f"{params.device}_triangle_empty.png")) return bin_img - + # Calculate automatic threshold value based on triangle algorithm hist = cv2.calcHist([gray_img], [0], None, [256], [0, 255]) From a319a55184ba9aed954ab84675d729126de8deb4 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Wed, 14 Jan 2026 21:50:57 +0100 Subject: [PATCH 6/6] Specify dtype np.uint8 in the test. --- tests/plantcv/threshold/test_threshold_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plantcv/threshold/test_threshold_methods.py b/tests/plantcv/threshold/test_threshold_methods.py index 16ca55a24..2f65dca67 100644 --- a/tests/plantcv/threshold/test_threshold_methods.py +++ b/tests/plantcv/threshold/test_threshold_methods.py @@ -259,6 +259,6 @@ def test_dual_channels_bad_channel(): def test_empty_mask_triangle(): """Test for PlantCV.""" - mask = np.zeros((100, 100)) + mask = np.zeros((100, 100), dtype=np.uint8) fmask = triangle(mask) assert np.sum(fmask) == 0