#初めに
OpenCVでのフィルタリング処理(Blur, Filter)は、特定の領域を定義して、その総和をとる事により画像を加工(ぼかし・ノイズ除去)しています
この時、画像の縁部分に対しては領域を拡張して計算するわけですが、その拡張方法について調べてみました。
#動作環境
Python3,OpenCV
##定数値で拡大(BORDER_CONSTANT)
黒色(0, 0, 0)で拡張します
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
black = [0x00, 0x00, 0x00]
dimgray = [0x69, 0x69, 0x69]
gray = [0x80, 0x80, 0x80]
darkgray = [0xa9, 0xa9, 0xa9]
silver = [0xc0, 0xc0, 0xc0]
lighgray = [0xd3, 0xd3, 0xd3]
gainsboro = [0xdc, 0xdc, 0xdc]
whiteSmoke = [0xf5, 0xf5, 0xf5]
white = [0xFF, 0xFF, 0xFF]
img = np.array([
[black, white, black, white, black]
,[white, dimgray, white, dimgray, white]
,[gray, white, gray, white, gray]
,[white, darkgray, white, darkgray, white]
,[silver, white, silver, white, silver]
,[white, lighgray, white, lighgray, white]
,[gainsboro, white, gainsboro, white, gainsboro]
,[white, whiteSmoke, white, whiteSmoke, white]
])
# 拡張ピクセル数
exPixelNum = 8
plt.subplot(121),plt.imshow(img),plt.imshow(img),plt.title('Original')
conBdImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_CONSTANT)
plt.subplot(122),plt.imshow(conBdImg),plt.title('BORDER_CONSTANT')
plt.show()

##反対側のピクセルを複数(BORDER_WRAP)
# オリジナル画像(比較のために黒色で拡張しています)
orgImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_CONSTANT)
plt.subplot(121),plt.imshow(orgImg),plt.title('Original')
plt.xticks([]), plt.yticks([])
# Wrap画像
wrpBdImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_WRAP)
plt.subplot(122),plt.imshow(wrpBdImg),plt.title('BORDER_WRAP')
plt.xticks([]), plt.yticks([])
plt.show()

下図のように、対象の画像を繰り返し配置している事がわかります
##エッジのピクセルをコピー(BORDER_REPLICATE)
# Replicate画像
repBdImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_REPLICATE)
plt.subplot(122),plt.imshow(repBdImg),plt.title('BORDER_REPLICATE')
plt.xticks([]), plt.yticks([])
plt.show()

下図のように末端のピクセルを、そのまま用いている事がわかります
##反射(BORDER_REFLECT)
# Replicate画像
# Reflect画像
refBdImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_REFLECT)
plt.subplot(122),plt.imshow(refBdImg),plt.title('BORDER_REFLECT')
plt.xticks([]), plt.yticks([])
plt.show()

下図のように、反転して画像を配置している事がわかります
##反射(BORDER_REFLECT_101)
# Reflect画像(エッジのピクセルを繰り返さない)
# BORDER_DEFAULTとした時も同じ加工を行う
ref101BdImg = cv.copyMakeBorder(img, exPixelNum, exPixelNum, exPixelNum, exPixelNum, cv.BORDER_REFLECT_101)
plt.subplot(122),plt.imshow(ref101BdImg),plt.title('BORDER_REFLECT_101')
plt.xticks([]), plt.yticks([])
plt.show()

BORDER_REFLECTと同じ反射ですが、エッジのピクセルを繰り返しません
BORDER_REFLECT_101をBORDER_DEFAULTとした時も同じ加工となります