【问题标题】:Performing sobel filters on rgb color components对 rgb 颜色分量执行 sobel 过滤器
【发布时间】:2018-10-20 01:29:45
【问题描述】:

我正在尝试将图像分离为其 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))))

【问题讨论】:

  • 如果 gxx == gyy 你可以除以零
  • 是的,我已经明白了,但我认为 gxx 和 gyy 可能相等,因为 u 和 v 相等
  • 任何单个索引都是相等的...您始终可以打印内容以查看它们的外观...或使用断点检查它们numpy([1,2,3])/numpy([1,2,0])

标签: python image-processing colors scikit-image


【解决方案1】:

当除以这样的图像时,很可能某个像素的值为零,因此您会得到除以零。

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

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

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

与:

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

您计算的gxxgyygxy 三元组看起来很像结构张量。如果这是您打算计算的内容,则需要为这三个组件中的每一个添加额外的模糊。这会导致梯度信息在局部进行平均,从而产生更少的零梯度位置。

【讨论】:

  • 这似乎是正确的,我最终只是在程序的开头添加了这个 np.seterr(divide='ignore', invalid='ignore') 以忽略我除以零的时间。这样就够了吗?
  • @Jacob:我更喜欢计算正确的角度。 atan2 有什么问题?消除错误就像把灰尘推到地毯下面。你再也看不到它了,但它仍然存在,它仍然会导致健康问题。 :)
  • 这正是我使用的,这是一个有截止日期的作业。我假设我的程序只是不包括导致除以 0 错误的像素。
  • 不,它仍然被零除。只要你不做0/0,除以零就会产生无穷大。 atan(inf)==pi/2,所以你得到了正确的结果。但是如果gxygxx-gyy 都为零(这发生在图像中的均匀区域),你会得到NaN,然后​​是atan(NaN)==NaN
猜你喜欢
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-24
  • 2019-03-11
  • 2020-06-27
  • 2015-07-19
  • 2014-05-15
相关资源
最近更新 更多