卷積邊界處理(copyMakeBorder)

進行卷積處理影像時,在影像的邊界,核心沒有足夠元素納入計算,OpenCV裡用copyMakeBorder()函式將原圖稍微放大,再開始進行卷積,OpenCV在空間濾波的相關函式內部已包含copyMakeBorder()了,所以實際上使用空間濾波時,不需要呼叫copyMakeBorder()。

在OpenCV裡進行卷積時,處理邊界問題通常分以下3個步驟:

  1. 先將原始影像的資料,複製到一個稍大的影像裡。
  2. 將邊界進行外推,有幾種BORDER型態決定外推值,以下列出較常見的幾個:

    BORDER_CONSTANT:外推的值為常數,常在仿射變換、透視變換中使用。

    BORDER_REPLICATE:外推的值和邊緣值相同,OpenCV的medianBlur默認的處理方式。

    BORDER_REFLECT_101:外推像素和影像邊界成鏡像映射,OpenCV的 filter2D、blur、GaussianBlur、bilateralFilter默認的處理方式。

  3. 處理完後將外推的部分切掉,使得輸出圖和輸入圖大小相同。


copyMakeBorder()為上述的第一、二步驟,就是輸入來源圖,得到一個稍大的有外推的輸出圖。

OpenCV邊緣複製:void copyMakeBorder(InputArray src, OutputArray dst, int top, int bottom, int left, int right, int borderType, const Scalar&value=Scalar())

  • src:輸入圖。
  • dst:輸出圖,深度和輸入圖相同,尺寸會依輸入參數而變得稍大,Size(src.cols+left+right, src.rows+top+bottom)。。
  • top、bottom、left、right:上下左右分別外推多少像素。
  • borderType:邊緣型態。
  • value:當borderType為BORDER_CONSTANT,此為外推的值。

以下示範如何用copyMakeBorder()讓影像邊界擴充,分別使用BORDER_CONSTANT和BORDER_REPLICATE來指定邊界的值:

#include <cstdio>
#include <opencv2/opencv.hpp>
using namespace cv;

int main(){
    Mat src = imread("cat.jpg");
    Mat dst1;
    Mat dst2;
    copyMakeBorder(src, dst1, 5, 5, 5, 5, BORDER_CONSTANT, Scalar(255,0,0));
    copyMakeBorder(src, dst2, 5, 5, 5, 5, BORDER_REPLICATE);
    imshow("origin", src);
    imshow("border1", dst1);
    imshow("border2", dst2);
    waitKey(0);

    return 0;
}

copyMakeBorder

copyMakeBorder

copyMakeBorder

回到首頁

回到OpenCV教學


參考資料:

OpenCV 教程