对RGB颜色分量执行Sobel滤镜

时间:2018-10-20 01:29:46

标签: python image-processing colors scikit-image

我试图将图像分为rgb颜色分量,然后尝试对每个颜色分量图像执行sobel h和v滤镜。我不太确定问题是什么,但是我得到了以下除以0的错误。我想可能是因为我的u和v变成了完全相同的数组。

错误

/Users/Sam/PycharmProjects/temp/A2.py:51: RuntimeWarning: divide by zero encountered in true_divide
  theta = 0.5 * np.arctan(2 * gxy / (gxx - gyy))
/Users/Sam/PycharmProjects/temp/A2.py:51: RuntimeWarning: invalid value encountered in true_divide
  theta = 0.5 * np.arctan(2 * gxy / (gxx - gyy))
/Users/Sam/PycharmProjects/temp/A2.py:54: RuntimeWarning: invalid value encountered in sqrt
  fTheta = np.sqrt(0.5 * ((gxx + gyy) + (gxx - gyy) * np.cos(2 * theta) + (2 * gxy * np.sin(2 * theta))))
Traceback (most recent call last):
  File "/Users/Sam/PycharmProjects/A1/venv/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 51, in _wrapfunc
    return getattr(obj, method)(*args, **kwds)

代码

import skimage.filters as filt
import numpy as np
def color_dot_product(A, B):
    return np.sum(A.conj() * B, axis=2)


mushroom = io.imread('mushroom.jpg')
I = util.img_as_float(mushroom)
  red = I[:, :, 0]  # Zero out contribution from green
  blue = I[:,:,1]
  green = I[:,:,2]

  # Compute horizontal and vertical derivatives of red, blue and green channels through applying sobel filters
  u = I.copy()
  u[:, :, 0] = filt.sobel_h(red)
  u[:, :, 1] = filt.sobel_h(green)
  u[:, :, 2] = filt.sobel_h(blue)
  v = I.copy()
  v[:, :, 0] = filt.sobel_v(red)
  v[:, :, 1] = filt.sobel_v(green)
  v[:, :, 2] = filt.sobel_v(blue)
  gxx = color_dot_product(u, u)
  gyy = color_dot_product(v, v)
  gxy = color_dot_product(u, v)

  # Calculate gradient direction (direction of the largest colour change)
  theta = 0.5 * np.arctan(2 * gxy / (gxx - gyy))

  # Calculate the magnitude of the rate of change
  fTheta = np.sqrt(0.5 * ((gxx + gyy) + (gxx - gyy) * np.cos(2 * theta) + (2 * gxy * np.sin(2 * theta))))

1 个答案:

答案 0 :(得分:2)

按这样的图像进行除法时,某些像素的值很可能为零,因此您将除以零。

通常可以通过在除法之前显式测试每个像素是否为零来避免这种情况,或者如果除数为非负数,则添加一个非常小的值。

但是在这种情况下,您根本不需要划分。函数atan2接受两个输入参数,因此atan2(y,x)等效于atan(y/x)。除了返回的角度范围为(-π,π](即,可以为您提供360度的完整角度范围)之外,我喜欢上面的Wikipedia,因为atan2是所有语言中都存在的通用函数。除了在Numpy中,它被称为arctan2(我想奇怪是要有所不同吗?)。所以替换:

theta = 0.5 * np.arctan(2 * gxy / (gxx - gyy))

具有:

theta = 0.5 * np.arctan2(2 * gxy, gxx - gyy)

您计算的gxxgyygxy三元组看起来很像结构张量。如果这是您要计算的内容,则需要为这三个组件的每一个添加额外的模糊处理。这样就可以对梯度信息进行局部平均,从而产生较少的零梯度位置。