Прочтите второй абзац вашей документации страницы:
Другая общая особенность функций и классов, описанных в этом разделе, заключается в том, что, в отличие от простых арифметических функций, им необходимо экстраполировать значения некоторых несуществующих пикселей. Например, если вы хотите сгладить изображение с использованием фильтра Гаусса 3x3, то при обработке крайних левых пикселей в каждой строке вам понадобятся пиксели слева от них, то есть за пределами изображения. Вы можете сделать так, чтобы эти пиксели были такими же, как крайние левые пиксели изображения (метод экстраполяции с «реплицированной границей»), или предположить, что все несуществующие пиксели являются нулями (метод экстраполяции с «постоянной границей»), и так далее. OpenCV позволяет вам указать метод экстраполяции. Подробнее см. Функцию borderInterpolate()
и обсуждение параметра borderType
в разделе и различные функции ниже.
Сделайте так, как вы ожидали
Чтобы он работал так, как вы ожидали, он должен был явно указать, что вы хотите интерполировать вашу границу с нулевыми значениями. Как это:
import cv2
import numpy as np
img = np.array([[0,1,0],[1,0,1],[0,1,0]]).astype(float)
border = cv2.borderInterpolate(0, 1, cv2.BORDER_CONSTANT)
sobelx64f = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3, borderType=border)
print 'img'
print img
print 'sobelx64f'
print sobelx64f
Выход:
img
[[ 0. 1. 0.]
[ 1. 0. 1.]
[ 0. 1. 0.]]
sobelx64f
[[ 2. 0. -2.]
[ 2. 0. -2.]
[ 2. 0. -2.]]
Тип границы по умолчанию
Значение по умолчанию borderType
равно BORDER_DEFAULT
, что на моей машине такое же, как BORDER_REFLECT_101
. Вы можете запустить этот скрипт, чтобы подтвердить его на своем компьютере:
import cv2
for var in dir(cv2):
if not var.startswith('BORDER_'): continue
if cv2.__dict__[var] == cv2.BORDER_DEFAULT:
print 'BORDER_DEFAULT ==', var
Выход:
BORDER_DEFAULT == BORDER_DEFAULT
BORDER_DEFAULT == BORDER_REFLECT101
BORDER_DEFAULT == BORDER_REFLECT_101
И BORDER_REFLECT_101
работает именно так, как это соответствует вашим результатам. Вот объяснение различных типов границ:
BORDER_REPLICATE: aaaaaa|abcdefgh|hhhhhhh
BORDER_REFLECT: fedcba|abcdefgh|hgfedcb
BORDER_REFLECT_101: gfedcb|abcdefgh|gfedcba
BORDER_WRAP: cdefgh|abcdefgh|abcdefg
BORDER_CONSTANT: iiiiii|abcdefgh|iiiiiii with some specified 'i'
Объяснение того, что вы получаете
Таким образом, тип интерполяции границ по умолчанию (равный BORDER_REFLECT_101
) делает ваш массив таким, каким он был до вычисления:
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
1 0 1 0 1
0 1 0 1 0
С помощью простой арифметики вы можете подтвердить, что правильные значения после применения ядра Собеля к внутренним пикселям 3x3 - все нули - это то, что вы получили, запустив свой скрипт.