From 46a3ca362aa135909493893b01798d0d756fa341 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Sat, 13 Dec 2025 23:08:56 +0100 Subject: [PATCH 1/3] Empty mask handling within pcv.threshold.otsu --- plantcv/plantcv/threshold/threshold_methods.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/plantcv/plantcv/threshold/threshold_methods.py b/plantcv/plantcv/threshold/threshold_methods.py index 62ff850ef..54ba78072 100644 --- a/plantcv/plantcv/threshold/threshold_methods.py +++ b/plantcv/plantcv/threshold/threshold_methods.py @@ -170,6 +170,11 @@ def otsu(gray_img, object_type="light"): params.device += 1 + # If the grayscale image is all zeros, return copy of input image. + if np.count_nonzero(gray_img) == 0: + out = np.copy(gray_img) + return out + # Threshold the image bin_img = _call_threshold(gray_img, 0, threshold_method, "_otsu_threshold_") From a27c76cdad3d0eee76427d4f202c93188bbb05e1 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Sun, 14 Dec 2025 13:16:01 +0100 Subject: [PATCH 2/3] Test for empty mask otsu. --- 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..59ec4d634 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_otsu_empty_mask(): + """Test for PlantCV.""" + mask = np.zeros((100, 100)) + fmask = otsu(mask) + assert np.sum(fmask) == 0 + From 48829cd83eaba13b9c3628aa5c775a6a613e11b5 Mon Sep 17 00:00:00 2001 From: Nirkan Date: Sun, 14 Dec 2025 14:56:05 +0100 Subject: [PATCH 3/3] Adding debug --- plantcv/plantcv/threshold/threshold_methods.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/plantcv/plantcv/threshold/threshold_methods.py b/plantcv/plantcv/threshold/threshold_methods.py index 54ba78072..78d0057b8 100644 --- a/plantcv/plantcv/threshold/threshold_methods.py +++ b/plantcv/plantcv/threshold/threshold_methods.py @@ -172,8 +172,9 @@ def otsu(gray_img, object_type="light"): # If the grayscale image is all zeros, return copy of input image. if np.count_nonzero(gray_img) == 0: - out = np.copy(gray_img) - return out + bin_img = np.copy(gray_img) + _debug(visual=bin_img, filename=os.path.join(params.debug_outdir, f"{params.device}_otsu_empty.png")) + return bin_img # Threshold the image bin_img = _call_threshold(gray_img, 0, threshold_method, "_otsu_threshold_")