Сглаживание изображений (краевые случаи)

Кто-нибудь знает, как выполняется обработка краевых случаев в cv2.blur()? Ни в документации, ни на разных сайтах этой информации нет. Я хочу написать сам функцию сглаживания, но не понимаю, откуда берутся краевые значения в cv2.blur(). Может, есть какие-нибудь идеи? (ядро 3*3) Вход:

img = np.array([[0,255,1,4,78,5,20,150],
                [0,170,9,40,58,45,200,180],
                [190,45,110,46,198,56,0,190],
                [80,25,10,40,7,15,200,130],
                [30,240,111,43,68,52,203,153],
                [5,2,0,44,10,53,200,250],
                [10,25,31,34,0,25,10,15],
                [0,255,0,1,90,25,2,200]])

После cv2.blur()

[[132  68  78  33  41  79 114 150]
 [126  87  76  60  59  73  94 107]
 [ 83  71  55  58  56  87 113 144]
 [102  93  74  70  58  89 111 142]
 [ 72  56  57  37  37  90 140 193]
 [ 64  50  59  38  37  69 107 138]
 [ 64  36  44  23  31  46  87  99]
 [ 70  43  48  25  26  21  36  30]]

Мой результат:

[[  1   1   1   1   1   1   1   1]
 [  1  87  76  60  59  73  94   1]
 [  1  71  55  58  56  87 113   1]
 [  1  93  74  70  58  89 111   1]
 [  1  56  57  37  37  90 140   1]
 [  1  50  59  38  37  69 107   1]
 [  1  36  44  23  31  46  87   1]
 [  1   1   1   1   1   1   1   1]]

Понятия не имею, откуда берутся такие края, помогите, пожалуйста(((


Ответы (2 шт):

Автор решения: passant

Как раз непонятно откуда у вас берутся ваши краевые единички. А в классической задаче сглаживания, если новое значение это усреднение окружающих его значений, то краевые точки считаются точно также, только делятся не на 9, а на 6. (так как такие точки имеют пять окружающих точек плюс они сами) А для угловых точек -на 4.

→ Ссылка
Автор решения: strawdog

В документации, вообще-то, все написано. Помимо указанного вами кернела, cv2.blur использует еще такую вещь, как BorderType. Так вот, параметр BorderType по умолчанию равен BORDER_DEFAULT, то есть BORDER_REFLECT_101. Судя по документации, отражение считается так:

gfedcb|abcdefgh|gfedcba

Если взять для примера левый верхний угол вашей исходной матрицы:

 0 255 
 0 170 

то, на основании правила BORDER_REFLECT_101, мы получим матрицу, расширенную за пределы исходной такого типа:

(170) (0) (170)
(255)  0   255
(170)  0   170

Далее применяется обычный метод усредненного боксфильтра: (170+0+170+255+0+255+170+0+170)/9 (при кернеле 3х3). То есть, 1190/9 или 132.(2) то есть, 132. Именно это число и уходит в левый верхний угол результирующего изображения вместо 0.

Здесь ссылка на нужный кусок документации.

→ Ссылка