#初めに
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()
![Screen Shot 2020-05-17 at 16.02.45.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F628168%2F5e6e12b8-1b40-dfc0-6771-fcad81cac657.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=c3a4fc1b1d138cdefa9713b4dbe44db9)
##反対側のピクセルを複数(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()
![Screen Shot 2020-05-17 at 16.23.55.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F628168%2F895a3e48-a049-a0e4-9fce-fb929896133b.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=70f543746e40139daeb74d61e753a6de)
下図のように、対象の画像を繰り返し配置している事がわかります
##エッジのピクセルをコピー(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()
![Screen Shot 2020-05-17 at 16.42.32.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F628168%2F2d2513a2-de8e-b956-2324-3077e8963dc2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=8027c347c17f7eea2e07a6e6bc39e25d)
下図のように末端のピクセルを、そのまま用いている事がわかります
##反射(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()
![Screen Shot 2020-05-17 at 17.36.40.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F628168%2F070a4089-c462-7493-a347-b6fe2259b7a4.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=7ebf4fffe8a8809fc4897d243a33c9c5)
下図のように、反転して画像を配置している事がわかります
##反射(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()
![Screen Shot 2020-05-17 at 17.47.13.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F628168%2Fdf53cd68-7af0-8add-8879-57129a95cbc8.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=976f80d84ef2e33ba65319aa71b65ba3)
BORDER_REFLECTと同じ反射ですが、エッジのピクセルを繰り返しません
BORDER_REFLECT_101をBORDER_DEFAULTとした時も同じ加工となります