def sobel_v(image, mask=None): """Find the vertical edges of an image using the Sobel transform. Parameters ---------- image : 2-D array Image to process. mask : 2-D array, optional An optional mask to limit the application to a certain area. Note that pixels surrounding masked regions are also masked to prevent masked regions from affecting the result. Returns ------- output : 2-D array The Sobel edge map. Notes ----- We use the following kernel:: 1 0 -1 2 0 -2 1 0 -1 """ check_nD(image, 2) image = img_as_float(image) result = convolve(image, VSOBEL_WEIGHTS) return _mask_filter_result(result, mask)
def sobel(image, mask=None): """Find the edge magnitude using the Sobel transform. Parameters ---------- image : 2-D array Image to process. mask : 2-D array, optional An optional mask to limit the application to a certain area. Note that pixels surrounding masked regions are also masked to prevent masked regions from affecting the result. Returns ------- output : 2-D array The Sobel edge map. See also -------- scharr, prewitt, roberts, feature.canny Notes ----- Take the square root of the sum of the squares of the horizontal and vertical Sobels to get a magnitude that's somewhat insensitive to direction. The 3x3 convolution kernel used in the horizontal and vertical Sobels is an approximation of the gradient of the image (with some slight blurring since 9 pixels are used to compute the gradient at a given pixel). As an approximation of the gradient, the Sobel operator is not completely rotation-invariant. The Scharr operator should be used for a better rotation invariance. Note that ``scipy.ndimage.sobel`` returns a directional Sobel which has to be further processed to perform edge detection. Examples # -------- # >>> from skimage import data # >>> camera = data.camera() # >>> from skimage import filters # >>> edges = filters.sobel(camera) """ check_nD(image, 2) out = np.sqrt(sobel_h(image, mask)**2 + sobel_v(image, mask)**2) out /= np.sqrt(2) return out
def test_check_nD(): z = np.random.random(200**2).reshape((200, 200)) x = z[10:30, 30:10] with testing.raises(ValueError): check_nD(x, 2)
def better_blob_dog(image, min_sigma=1, max_sigma=50, sigma_ratio=1.6, threshold=0.03): r"""Find blobs in the given grayscale image. Blobs are found using the Difference of Gaussian (DoG) method [1]_. For each blob found, the method returns its coordinates and the standard deviation of the Gaussian kernel that detected the blob. Parameters ---------- image : ndarray Input grayscale image, blobs are assumed to be light on dark background (white on black). min_sigma : float, optional The minimum standard deviation for Gaussian Kernel. Keep this low to detect smaller blobs. max_sigma : float, optional The maximum standard deviation for Gaussian Kernel. Keep this high to detect larger blobs. sigma_ratio : float, optional The ratio between the standard deviation of Gaussian Kernels used for computing the Difference of Gaussians threshold : float, optional. The absolute lower bound for scale space maxima. Local maxima smaller than thresh are ignored. Reduce this to detect blobs with less intensities. Returns ------- A : (n, 3) ndarray A 2d array with each row representing 3 values, ``(y, x, sigma)`` where ``(y, x)`` are coordinates of the blob and ``sigma`` is the standard deviation of the Gaussian kernel which detected the blob. References ---------- .. [1] http://en.wikipedia.org/wiki/Blob_detection# The_difference_of_Gaussians_approach Notes ----- The radius of each blob is approximately :math:`\sqrt{2}sigma`. """ check_nD(image, 2) image = img_as_float(image) sigma_ratio = float(sigma_ratio) # k such that min_sigma*(sigma_ratio**k) > max_sigma k = int(log(float(max_sigma) / min_sigma, sigma_ratio)) + 1 # a geometric progression of standard deviations for gaussian kernels sigma_list = np.array([min_sigma * (sigma_ratio**i) for i in range(k + 1)]) # Use the faster fft_gaussian_filter to speed things up. gaussian_images = [fft_gaussian_filter(image, s) for s in sigma_list] # computing difference between two successive Gaussian blurred images # multiplying with standard deviation provides scale invariance dog_images = [(gaussian_images[i] - gaussian_images[i + 1]) * sigma_list[i] for i in range(k)] image_cube = np.dstack(dog_images) # peak_local_max is looking in the image_cube, so threshold should # be scaled by differences in sigma, i.e. sigma_ratio local_maxima = peak_local_max( image_cube, threshold_abs=threshold, footprint=np.ones((3, 3, 3)), threshold_rel=0.0, exclude_border=False, ) if local_maxima.size: # Convert local_maxima to float64 lm = local_maxima.astype(np.float64) # Convert the last index to its corresponding scale value lm[:, 2] = sigma_list[local_maxima[:, 2]] local_maxima = lm return local_maxima