Python 这个用于Sobel边缘检测的Matlab代码的OpenCv等价物是什么?

Python 这个用于Sobel边缘检测的Matlab代码的OpenCv等价物是什么?,python,matlab,opencv,Python,Matlab,Opencv,这是我想在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)

这是我想在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也没有帮助

这是我需要的输出:


有人能告诉我我做错了什么,我应该做什么才能得到相同的结果图像吗?

sobel边缘检测的MATLAB实现是不可见的,因此我们只能准确地猜测发生了什么。我们从
edge
上的文档中得到的唯一提示是,当使用
'sobel'
选项时

在图像I的渐变点处查找边 最大值,使用索贝尔近似导数

没有说明,但是取梯度的最大值比简单地取图像中的局部最大值更复杂。相反,我们想要找到关于梯度方向的局部最大值。不幸的是,MATLAB用于此操作的实际代码是隐藏的

查看
edge
中可用的代码,它们似乎在细化操作中使用了4*平均值(幅值)作为阈值,因此我将其与您的模糊因子结合使用。
oriented_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)
导入cv2
将numpy作为np导入
导入scipy.ndimage.filters
gray\u image=cv2.imread('cell.png',cv2.imread\u GRAYSCALE).astype(dtype=np.float32)
def定向非最大值抑制(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]])
法师=非最大抑制(法师,葡萄酒)
magSE=非最大抑制(mag、winSE)
magS=非最大抑制(mag,winS)
magSW=非最大抑制(mag、winSW)
mag[ang_quant==0]=magE[ang_quant==0]
mag[ang_quant==1]=magSE[ang_quant==1]
mag[ang_quant==2]=mag[ang_quant==2]
mag[ang_quant==3]=magSW[ang_quant==3]
回传杂志
def非最大值抑制(数据,win):
data\u max=scipy.ndimage.filters.max\u filter(数据,footprint=win,mode='constant')
数据最大值[数据!=数据最大值]=0
返回数据_max
#计算索贝尔响应
sobelx=cv2.Sobel(灰度图像,cv2.CV\u32f,1,0,ksize=3)
sobely=cv2.Sobel(灰度图像,cv2.CV\u32f,0,1,ksize=3)
mag=np.hypot(sobelx,sobely)
ang=np.arctan2(sobely,sobelx)
#门槛
fudgefactor=0.5
阈值=4*模糊因子*np.平均值(mag)
mag[mag<阈值]=0
#非最大抑制
mag=定向非最大抑制(mag,ang)
但不考虑梯度方向
#mag=撇渣.形态.薄(mag.astype(np.bool)).astype(np.float32)
#创建遮罩
mag[mag>0]=255
mag=mag.astype(np.uint8)
关于细胞的结果 Python

MATLAB


MATLAB的peppers.png(内置)上的结果 Python

MATLAB


MATLAB实现必须使用一些不同的东西,但看起来这非常接近