Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Sobel滤波器的结果很差_Python_Opencv_Computer Vision_Sobel - Fatal编程技术网

Python Sobel滤波器的结果很差

Python Sobel滤波器的结果很差,python,opencv,computer-vision,sobel,Python,Opencv,Computer Vision,Sobel,我试图用python实现sobel过滤器,但是输出很差,充满了噪声。 我得到的输出图像是: 我给出的输入是(模糊后): sobel过滤器的代码如下: def sobel_filters(img): Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]) Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]]) Ix = ndimage.filters.convolve(img, Kx)

我试图用python实现sobel过滤器,但是输出很差,充满了噪声。 我得到的输出图像是:

我给出的输入是(模糊后):

sobel过滤器的代码如下:

def sobel_filters(img):
  Kx = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
  Ky = np.array([[1, 2, 1], [0, 0, 0], [-1, -2, -1]])

  Ix = ndimage.filters.convolve(img, Kx)
  Iy = ndimage.filters.convolve(img, Ky)

  G = np.sqrt(np.square(Ix) + np.square(Iy))
  G *= 255.0 / G.max()
  

  return G
我用sigma=1.3模糊了结果。输入图像大小为512 x 512。
我希望输出与这里显示的类似:

这里有一种在Python/OpenCV中实现这一点的方法。你的问题是你的衍生品没有正确的标准化,应该作为浮动进行处理。您的规范化也不考虑负值。在这个答案中,我使用了OpenCV内置的Sobel和其他方法。因此,没有必要引入scipy.ndimage

输入:


Sobel X(标准化):

Sobel Y(标准化):

索贝尔震级:


以下是使用浮点图像和Python/OpenCV中的适当规范化来实现这一点的方法。如果没有浮动数据,则只能得到单边导数(不包括正结果和负结果)

正如Cris Luengo所指出的,您答案中的导数相对于OpenCV中的标准导数是错误的。参考文献中的导数用于适当的卷积。但Scipy同时具有卷积和相关性。事实上,大多数“卷积”都是相关性。(OpenCV cv2.filter2D就是这样。该函数实际上计算相关性,而不是卷积)。因此,我修正了内核,使其与OpenCV Sobel中的内容或cv2.filter2D()使用的内容一致。卷积和相关性通过转置进行关联。看

输入:


Sobel X(标准化):

Sobel Y(标准化):

索贝尔震级:


谢谢克里斯。我没有注意到这一问题的迹象。他从他试图复制的链接中得到了这些值。在其中一个例子中,我回答他为什么他的代码不起作用。在另一个例子中,我向他展示了我是如何使用OpenCVCris完成的对不起,当我试图更改规范化时,我重写了错误的答案,然后决定将其放回原处。我不想修理他的索贝尔果仁,因为他是从他列出的参考资料中得到的。但你的观点被很好地理解了,很高兴你指出了这一点。希望他能理解。然而,由于震级考虑了绝对值之和,我认为震级不重要。当然,X和Y导数图像的边缘极性会发生变化。克里斯,我已经编辑了我的答案,以显示正确的内核和图像。并对卷积和相关性给出更好的解释。您发布的链接没有使用正确的Sobel内核。关注维基百科页面,这是正确的:非常感谢!它起作用了!我实际上是在使用我自己的高斯模糊实现,并将结果存储在int8中。转换后,它工作!另外,请注意,您的实现中存在一些错误:在sobely_norm变量中,您使用了相同的参数Ix而不是Iy
import cv2
import numpy as np
import skimage.exposure as exposure

# read the image
img = cv2.imread('gray_lena.png')

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# blur
blur = cv2.GaussianBlur(gray, (0,0), 1.3, 1.3)

# apply sobel derivatives
sobelx = cv2.Sobel(blur,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(blur,cv2.CV_64F,0,1,ksize=3)

# optionally normalize to range 0 to 255 for proper display
sobelx_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
sobely_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)

# square 
sobelx2 = cv2.multiply(sobelx,sobelx)
sobely2 = cv2.multiply(sobely,sobely)

# add together and take square root
sobel_magnitude = cv2.sqrt(sobelx2 + sobely2)

# normalize to range 0 to 255 and clip negatives
sobel_magnitude = exposure.rescale_intensity(sobel_magnitude, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)

# save results
cv2.imwrite('gray_lena_sobelx_norm.jpg', sobelx_norm)
cv2.imwrite('gray_lena_sobely_norm.jpg', sobely_norm)
cv2.imwrite('gray_lena_sobel_magnitude.jpg', sobel_magnitude)

# show results
cv2.imshow('sobelx_norm', sobelx_norm)  
cv2.imshow('sobely_norm', sobely_norm)  
cv2.imshow('sobel_magnitude', sobel_magnitude)  
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
import scipy.ndimage as ndimage
import skimage.exposure as exposure

# read the image and convert to float
img = cv2.imread('gray_lena.png').astype(np.float32)

# convert to gray
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# blur
blur = cv2.GaussianBlur(gray, (0,0), 1.3, 1.3)

# define Sobel X and Y (correlation) kernels
Kx = np.array([[-1, 0, 1], 
               [-2, 0, 2], 
               [-1, 0, 1]])

Ky = np.array([[-1, -2, -1], 
               [ 0,  0,  0], 
               [ 1,  2,  1]])

# apply correlations and normalize by sum of absolute values of elements
sobelx = ndimage.filters.correlate(blur, Kx)
sobely = ndimage.filters.correlate(blur, Ky)

#OpenCV alternate:
#sobelx = cv2.filter2D(blur, cv2.CV_32F, Kx)
#sobely = cv2.filter2D(blur, cv2.CV_32F, Ky)

# optionally normalize to range 0 to 255 for proper display and saving as 8-bit data.
sobelx_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)
sobely_norm= exposure.rescale_intensity(sobelx, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)

# add and take square root
sobel_magnitude = np.sqrt(np.square(sobelx) + np.square(sobely))

# normalize to range 0 to 255 and clip negatives
sobel_magnitude = exposure.rescale_intensity(sobel_magnitude, in_range='image', out_range=(0,255)).clip(0,255).astype(np.uint8)

# save results
cv2.imwrite('gray_lena_sobelx_norm2.jpg', sobelx_norm)
cv2.imwrite('gray_lena_sobely_norm2.jpg', sobely_norm)
cv2.imwrite('gray_lena_sobel_magnitude2.jpg', sobel_magnitude)

# show results
cv2.imshow('sobelx_norm', sobelx_norm)  
cv2.imshow('sobely_norm', sobely_norm)  
cv2.imshow('sobel_magnitude', sobel_magnitude)  
cv2.waitKey(0)
cv2.destroyAllWindows()