这是我想在OpenCv中复制的Matlab代码
e[~, threshold] = edge(I, 'sobel');
fudgeFactor = .5;
BWs = edge(I,'sobel', threshold * fudgeFactor);
figure, imshow(BWs), title('binary gradient mask');
这是我的测试图片:
我尝试过像
这样的事情blurred_gray = cv2.GaussianBlur(gray_image,(3,3),0)
sobelx = cv2.Sobel(blurred_gray,cv2.CV_8U,1,0,ksize=3)
sobely = cv2.Sobel(blurred_gray,cv2.CV_8U,0,1,ksize=3)[2]
我得到的输出是:
我尝试添加sobelx和sobely,因为我读到它们是偏导数,但结果图像看起来与上面相同,并且改变ksize没有帮助。
这是我需要的输出:
有人可以告诉我我做错了什么以及我应该做些什么来获得相同的结果图像?
答案 0 :(得分:3)
sobel边缘检测的MATLAB实现是不可见的,所以我们只能猜测到底发生了什么。我们得到的唯一提示是edge
上的文档说明当使用'sobel'
选项时
在图像I的渐变点处找到边缘 最大,使用Sobel逼近导数。
没有说明,但是采用最大梯度比仅仅采用图像中的局部最大值更复杂。相反,我们希望找到相对于梯度方向的局部最大值。不幸的是,MATLAB用于此操作的实际代码是隐藏的。
查看edge
中可用的代码,看起来他们在细化操作中使用4 * mean(幅度)作为阈值,因此我将此与您的软糖因子结合使用。 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 强>
<强>的Python 强>
<强> MATLAB 强>
MATLAB实现必须使用一些不同的东西,但看起来这非常接近。