mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-11 04:10:24 +08:00
Added quantile_threshold option to canny edge detection
This allows you to specify the high and low thresholds as quantiles of the edge magnitude image, rather than as absolute edge magnitude values
This commit is contained in:
@@ -50,7 +50,8 @@ def smooth_with_function_and_mask(image, function, mask):
|
||||
return output_image
|
||||
|
||||
|
||||
def canny(image, sigma=1., low_threshold=None, high_threshold=None, mask=None):
|
||||
def canny(image, sigma=1., low_threshold=None, high_threshold=None, mask=None,
|
||||
quantile_threshold=False):
|
||||
"""Edge filter an image using the Canny algorithm.
|
||||
|
||||
Parameters
|
||||
@@ -67,6 +68,9 @@ def canny(image, sigma=1., low_threshold=None, high_threshold=None, mask=None):
|
||||
If None, high_threshold is set to 20% of dtype's max.
|
||||
mask : array, dtype=bool, optional
|
||||
Mask to limit the application of Canny to a certain area.
|
||||
quantile_threshold : bool, optional
|
||||
If True then treat low_threshold and high_threshold as quantiles of the
|
||||
edge magnitude image, rather than absolute edge magnitude values.
|
||||
|
||||
Returns
|
||||
-------
|
||||
@@ -246,6 +250,14 @@ def canny(image, sigma=1., low_threshold=None, high_threshold=None, mask=None):
|
||||
c2 = magnitude[1:, :-1][pts[:-1, 1:]]
|
||||
c_minus = c2 * w + c1 * (1 - w) <= m
|
||||
local_maxima[pts] = c_plus & c_minus
|
||||
|
||||
#
|
||||
#---- If quantile_threshold is set then calculate the thresholds to use
|
||||
#
|
||||
if quantile_threshold:
|
||||
high_threshold = np.percentile(magnitude, 100.0 * high_threshold)
|
||||
low_threshold = np.percentile(magnitude, 100.0 * low_threshold)
|
||||
|
||||
#
|
||||
#---- Create two masks at the two thresholds.
|
||||
#
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import unittest
|
||||
import numpy as np
|
||||
from numpy.testing import assert_equal
|
||||
from scipy.ndimage import binary_dilation, binary_erosion
|
||||
import skimage.feature as F
|
||||
from skimage import filters, data
|
||||
from skimage import img_as_float
|
||||
|
||||
|
||||
class TestCanny(unittest.TestCase):
|
||||
@@ -66,3 +69,27 @@ class TestCanny(unittest.TestCase):
|
||||
result1 = F.canny(np.zeros((20, 20)), 4, 0, 0, np.ones((20, 20), bool))
|
||||
result2 = F.canny(np.zeros((20, 20)), 4, 0, 0)
|
||||
self.assertTrue(np.all(result1 == result2))
|
||||
|
||||
|
||||
def test_quantile_threshold():
|
||||
image = img_as_float(data.camera()[::50,::50])
|
||||
|
||||
# Correct output produced manually with quantiles
|
||||
# of 0.8 and 0.6 for high and low respectively
|
||||
correct_output = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
|
||||
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0],
|
||||
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=bool)
|
||||
|
||||
result = F.canny(image, low_threshold=0.6, high_threshold=0.8, quantile_threshold=True)
|
||||
|
||||
assert_equal(result, correct_output)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user