Свертка изображений с 4D ядром в opencv

1

Учитывая изображение, я пытаюсь применить свертку с ядром (3 x 3 x 3 x 64):

cv2.filter2D(img, -1, np.random.rand(3,3,3,64))

дает:

error: /Users/travis/build/skvark/opencv-python/opencv/modules/imgproc/src/filterengine.hpp:363: error: (-215) anchor.inside(Rect (0, 0, ksize.width, ksize.height)) в функции normalizeAnchor

Фактически в документации говорится:

ядро - сверточное ядро (или, скорее, ядро корреляции), одноканальная матрица с плавающей запятой; если вы хотите использовать разные ядра для разных каналов, разделите изображение на отдельные цветовые плоскости с помощью split() и обработайте их по отдельности.

Есть ли какая-либо другая opencv-функция, которая может свертывать> 2D-ядро? Или мне нужно сделать два для циклов с применением filter2d?

Теги:
opencv
image
filter
convolution

2 ответа

2
Лучший ответ

В OpenCV таких функций нет - ни в одном из интерфейсов, ни в основной C++ библиотеке. Если вы хотите сделать 4D-свертку, вам придется либо использовать cv2.filter2D по 2D-подматрицам вашего 4D-ядра, напишите его самостоятельно или используйте что-то еще, что его поддерживает, например, глубокий учебный пакет или SciPy.

Самое простое решение, которое я могу предложить, без необходимости писать один или взломать его самостоятельно, - это использовать SciPy scipy.signal.convolve который выполняет N-мерную свертку: https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve.html. Имейте в виду, что и изображение, и ядро должны иметь одинаковое количество измерений, поэтому ожидалось, что ваше изображение тоже 4D.

  • 0
    Большое спасибо за информацию! использование scipy.signal.convolve и np.expand_dims может быть np.expand_dims способом, оцените это.
  • 0
    @ Киран Не беспокойся. Рад, что смог помочь. Если бы вы дали больше информации о вашем фактическом изображении, я мог бы написать для вас код, который демонстрирует, как это сделать ... но, конечно, если вы захотите узнать это сами, вы определенно более чем можете это сделать. так. Удачи!
Показать ещё 2 комментария
0

Функция OpenCV cv2.filter2D(), как следует из названия, предполагает двумерное img и 2D-ядро. Более того, вам нужно использовать циклы. Например, следующие прогоны без ошибок,

import cv2
import numpy as np

# read an rgb image
img = cv2.imread('fig1.png')

# filter the first channel (blue)
out0 = cv2.filter2D( img[:,:,0], -1, np.random.rand(3,3))

См. Документацию на cv2.filter2D()

  • 0
    Да, именно так я и делаю прямо сейчас, мне было интересно, есть ли другая функция, которая выполняет 4D, но не думаю.
  • 0
    На обычном процессоре это не дало бы никакого реального преимущества. Итерация цикла происходит один раз для каждого канала, поэтому она сравнительно дешевая. И это будет иметь одинаковую стоимость независимо от того, происходит ли это внутри функции или вне функции. Но на большом параллельном процессоре, например, на графическом процессоре, может быть существенное преимущество в удобстве и скорости. Я подозреваю, что вам нужно будет развернуть внешний цикл (ы), чтобы сделать это, поэтому некоторые усилия могут быть направлены на создание чистого API для произвольного числа измерений. Может быть, этот API уже существует в некоторой библиотеке GPU.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню