sobel边缘检测的MATLAB实现是不可见的,所以我们只能猜测到底发生了什么。我们得到的唯一提示来自于edge的文档,其中指出当使用'sobel'选项时Finds edges at those points where the gradient of the image I is
maximum, using the Sobel approximation to the derivative.
虽然没有说明,但是获取最大梯度比简单地获取图像中的局部最大值要复杂得多。相反,我们想找到关于梯度方向的局部极大值。不幸的是,MATLAB用于此操作的实际代码是隐藏的。在
看看edge中可用的代码,他们在细化操作中使用了4*mean(magnity)作为阈值,所以我将它与您的fudge因子结合使用。orientated_non_max_suppression函数远不是最佳函数,但我编写它是为了可读性而不是性能。在import cv2
import numpy as np
import scipy.ndimage.filters
gray_image = cv2.imread('cell.png', cv2.IMREAD_GRAYSCALE).astype(dtype=np.float32)
def orientated_non_max_suppression(mag, ang):
ang_quant = np.round(ang / (np.pi/4)) % 4
winE = np.array([[0, 0, 0],
[1, 1, 1],
[0, 0, 0]])
winSE = np.array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]])
winS = np.array([[0, 1, 0],
[0, 1, 0],
[0, 1, 0]])
winSW = np.array([[0, 0, 1],
[0, 1, 0],
[1, 0, 0]])
magE = non_max_suppression(mag, winE)
magSE = non_max_suppression(mag, winSE)
magS = non_max_suppression(mag, winS)
magSW = non_max_suppression(mag, winSW)
mag[ang_quant == 0] = magE[ang_quant == 0]
mag[ang_quant == 1] = magSE[ang_quant == 1]
mag[ang_quant == 2] = magS[ang_quant == 2]
mag[ang_quant == 3] = magSW[ang_quant == 3]
return mag
def non_max_suppression(data, win):
data_max = scipy.ndimage.filters.maximum_filter(data, footprint=win, mode='constant')
data_max[data != data_max] = 0
return data_max
# compute sobel response
sobelx = cv2.Sobel(gray_image, cv2.CV_32F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray_image, cv2.CV_32F, 0, 1, ksize=3)
mag = np.hypot(sobelx, sobely)
ang = np.arctan2(sobely, sobelx)
# threshold
fudgefactor = 0.5
threshold = 4 * fudgefactor * np.mean(mag)
mag[mag < threshold] = 0
# non-maximal suppression
mag = orientated_non_max_suppression(mag, ang)
# alternative but doesn't consider gradient direction
# mag = skimage.morphology.thin(mag.astype(np.bool)).astype(np.float32)
# create mask
mag[mag > 0] = 255
mag = mag.astype(np.uint8)
细胞的结果
Python
MATLAB
MATLAB的结果辣椒.png(内置)
Python
MATLAB
MATLAB的实现必须使用一些不同的东西,但是看起来这很接近。在