Учитывая изображение, я пытаюсь применить свертку с ядром (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 таких функций нет - ни в одном из интерфейсов, ни в основной 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.
Функция 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()
scipy.signal.convolve
иnp.expand_dims
может бытьnp.expand_dims
способом, оцените это.