Repository: scikit-image/scikit-image

Issue:
Array a containing one zero element and a.any() in function hough_line_peaks in file skimage/transform/hough_transform.py
## Description

The function hough_line_peaks in the file skimage/transform/hough_transform.py contains the following logic in line 64f

if a.any():
        return (h, angles[a], dists[d])
else:
        return (h, np.array([]), np.array([]))


In the edge case of a being an array with just one element, and that element being equal to 0, according to the logic given above, an empty array is returned because of the use of a.any(), instead of angles[0]. 

## Version information

3.6.3 (default, May 31 2019, 13:05:43) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Linux-3.10.0-957.27.2.el7.x86_64-x86_64-with-centos-7.6.1810-Core
scikit-image version: 0.15.0
numpy version: 1.17.1




Discussion:
It seems like your reproducing example is almost complete.

Could you please provide all the code start to finish? that will be half way to adding the test we need to the library to ensure this bug doesn't happen again!
Also, if you would like to help address this issue, we will gladly review your PR! Contributions are welcome!
a concrete example of this issue was more recently given in https://github.com/scikit-image/scikit-image/issues/6187#issue-1103991877

Resolving patch:
diff --git a/skimage/transform/hough_transform.py b/skimage/transform/hough_transform.py
--- a/skimage/transform/hough_transform.py
+++ b/skimage/transform/hough_transform.py
@@ -1,9 +1,8 @@
 import numpy as np
 from scipy.spatial import cKDTree
-from ._hough_transform import (_hough_circle,
-                               _hough_ellipse,
-                               _hough_line,
-                               _probabilistic_hough_line as _prob_hough_line)
+
+from ._hough_transform import _hough_circle, _hough_ellipse, _hough_line
+from ._hough_transform import _probabilistic_hough_line as _prob_hough_line
 
 
 def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10,
@@ -63,7 +62,7 @@ def hough_line_peaks(hspace, angles, dists, min_distance=9, min_angle=10,
                                min_ydistance=min_distance,
                                threshold=threshold,
                                num_peaks=num_peaks)
-    if a.any():
+    if a.size > 0:
         return (h, angles[a], dists[d])
     else:
         return (h, np.array([]), np.array([]))
@@ -267,8 +266,9 @@ def probabilistic_hough_line(image, threshold=10, line_length=50, line_gap=10,
     if theta is None:
         theta = np.linspace(-np.pi / 2, np.pi / 2, 180, endpoint=False)
 
-    return _prob_hough_line(image, threshold=threshold, line_length=line_length,
-                            line_gap=line_gap, theta=theta, seed=seed)
+    return _prob_hough_line(image, threshold=threshold,
+                            line_length=line_length, line_gap=line_gap,
+                            theta=theta, seed=seed)
 
 
 def hough_circle_peaks(hspaces, radii, min_xdistance=1, min_ydistance=1,


Test patch:
diff --git a/skimage/transform/tests/test_hough_transform.py b/skimage/transform/tests/test_hough_transform.py
--- a/skimage/transform/tests/test_hough_transform.py
+++ b/skimage/transform/tests/test_hough_transform.py
@@ -2,10 +2,10 @@
 import pytest
 from numpy.testing import assert_almost_equal, assert_equal
 
+from skimage import data, transform
 from skimage._shared.testing import test_parallel
-from skimage import data
-from skimage import transform
-from skimage.draw import line, circle_perimeter, ellipse_perimeter
+from skimage.draw import circle_perimeter, ellipse_perimeter, line
+
 
 @test_parallel()
 def test_hough_line():
@@ -56,10 +56,10 @@ def test_probabilistic_hough():
         img, threshold=10, line_length=10, line_gap=1, theta=theta)
     # sort the lines according to the x-axis
     sorted_lines = []
-    for line in lines:
-        line = list(line)
-        line.sort(key=lambda x: x[0])
-        sorted_lines.append(line)
+    for ln in lines:
+        ln = list(ln)
+        ln.sort(key=lambda x: x[0])
+        sorted_lines.append(ln)
 
     assert([(25, 75), (74, 26)] in sorted_lines)
     assert([(25, 25), (74, 74)] in sorted_lines)
@@ -117,6 +117,27 @@ def test_hough_line_peaks_ordered():
     assert hspace[0] > hspace[1]
 
 
+def test_hough_line_peaks_single_line():
+    # Regression test for gh-6187, gh-4129
+
+    # create an empty test image
+    img = np.zeros((100, 100), dtype=bool)
+    # draw a horizontal line into our test image
+    img[30, :] = 1
+
+    hough_space, angles, dist = transform.hough_line(img)
+
+    best_h_space, best_angles, best_dist = transform.hough_line_peaks(
+        hough_space, angles, dist
+    )
+    assert len(best_angles) == 1
+    assert len(best_dist) == 1
+    expected_angle = -np.pi / 2
+    expected_dist = -30
+    assert abs(best_angles[0] - expected_angle) < 0.01
+    assert abs(best_dist[0] - expected_dist) < 0.01
+
+
 def test_hough_line_peaks_dist():
     img = np.zeros((100, 100), dtype=bool)
     img[:, 30] = True