Выполнение фильтров sobel для цветовых компонентов RGB - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь разделить изображение на его цветовые компоненты 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 голосов
/ 20 октября 2018

При делении на изображение, подобное этому, весьма вероятно, что некоторый пиксель имеет значение ноль, и, таким образом, вы получаете деление на ноль.

Этого обычно избегают, явно проверяя каждый пиксель на нольперед делением, или если делитель неотрицательный, добавьте очень маленькое значение.

Но в этом случае вам вообще не нужно делить.Функция 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)

gxx,gyy, gxy триплет, который вы вычисляете, очень похож на тензор структуры. Если это то, что вы намереваетесь вычислить, вам нужно добавить дополнительное размытие для каждого из этих трех компонентов. Это приводит к локальному усреднению информации о градиенте, получая меньше мест с нулевым градиентом.

...