1.16【OpenCV圖像處理】卷積邊界處理

邊界默認、常數、複製、包裝、copyMakeBorder()

1.16.1 卷積邊界問題

圖像邊界卷積時的問題:圖像卷積的時候邊界像素,不能被卷積操作,原因在於邊界像素沒有完全跟kernel重疊,所以當3x3濾波時候有1個像素的邊緣沒有被處理,5x5濾波的時候有2個像素的邊緣沒有被處理(如下圖)。

邊界處理方法:在卷積開始之前增加邊緣像素,填充的像素值為0或者RGB黑色,比如3x3在四周各填充1個像素的邊緣,這樣就確保圖像的邊緣被處理,在卷積處理之後再去掉這些邊緣。

1.16.2 邊界填充方法

(1)BORDER_DEFAULT - (邊界默認)openCV中默認的處理方法,自動填充圖像邊界(效果像是映像一樣)。

(2)BORDER_CONSTANT – (邊界常數)填充邊緣用指定像素值,使用常數填充邊界。

(3)BORDER_REPLICATE – (邊界複製)填充邊緣像素用已知的邊緣像素值,複製原圖中最臨近的行或者列。

(4)BORDER_WRAP – (邊界包裝)用另外一邊的像素來補償填充。

1.16.3 添加邊界的API

copyMakeBorder(

- Mat src, // 輸入圖像

- Mat dst, // 添加邊緣的圖像

- int top, // 邊緣長度,一般上下左右都取相同值

- int bottom,

- int left,

- int right,

- int borderType // 邊緣類型,選擇上面的填充方法,不寫默認選BORDER_DEFAULT

- Scalar value //邊框顏色值,如果邊框類型是BUALE_CONTER時才有用

/*添加圖像邊界*/nint top = (int)(0.05*src.rows); //頂部長度,設定為圖像src大小的5%nint bottom = (int)(0.05*src.rows); //底部長度nint left = (int)(0.05*src.cols); //左邊長度nint right = (int)(0.05*src.cols); //右邊長度nRNG rng(123456); //定義一個隨機數,產生隨機邊界色彩nint c = 0;nint borderType = BORDER_DEFAULT; //邊界默認,自動填充圖像邊界nwhile (true) {n c = waitKey(500);nif ((char)c == 27) { //ESC鍵nbreak;n }nif ((char)c == r) {n borderType = BORDER_REPLICATE; //按R鍵 (複製邊界)n }nelse if ((char)c == v) {n borderType = BORDER_WRAP; //按V鍵 (包裝邊界,用另外一邊的像素來補償填充)n }nelse if ((char)c == c) {n borderType = BORDER_CONSTANT; //按C鍵 (常數邊界)n }n Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //邊框顏色值ncopyMakeBorder(src, dst, top, bottom, left, right, borderType, color); //添加邊界n imshow("border image", dst);n}n

1.16.4 邊界處理的應用

做卷積時邊界處理的應用, 無需在寫填充邊界的函數,直接在卷積函數里定義,borderType不寫則默認選BORDER_DEFAULT(前面筆記沒有寫),以下函數都做了卷積

卷積濾波:(掩膜運算元、Robert運算元、Sobel運算元、Laplacian運算元、自定義模糊卷積核)

filter2D(InputArray src, OutputArray dst, int ddepth, InputArray kernel, Point anchor=Point(-1,-1), double delta=0, int borderType=BORDER_DEFAULT );

均值模糊濾波:(權重都為1)(中值濾波medianBlur沒用卷積)

blur(InputArray src, OutputArray dst, Size ksize, Point anchor=Point(-1,-1), int borderType=BORDER_DEFAULT );

高斯模糊濾波:(空間位置有權重)

GaussianBlur(InputArray src, OutputArray dst, Size ksize, double sigmaX, double sigmaY=0,int borderType=BORDER_DEFAULT );

雙邊模糊濾波:(空域核和值域核)

bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT );

膨脹:(取核下最大值)

dilate(InputArray src, OutputArray dst, InputArray element, Point anchor=Point(-1,-1),int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );

腐蝕:(取核下最小值)

erode(InputArray src, OutputArray dst, InputArray element, Point anchor=Point(-1,-1),int iterations=1, int borderType=BORDER_CONSTANT, const Scalar& borderValue=morphologyDefaultBorderValue() );

形態學操作:(開、閉、形態學梯度、頂帽、黑帽 )

morphologyEx(InputArray src, OutputArray dst, int op, InputArray element, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT,const Scalar& borderValue=morphologyDefaultBorderValue() );

GaussianBlur(src, dst2, Size(5, 5), 0, 0, BORDER_DEFAULT); //高斯濾波n


完整程序:

/*1.16 邊界處理*/n#include <opencv2/opencv.hpp>n#include <iostream> n#include <math.h>nusing namespace cv; //使用cv命名空間nnint main(int argc, char** argv) { //argc 表示命令行輸入參數的個數(以空白符分隔),argv中存儲了所有的命令行參數nMat src, dst, dst2;n src = imread("E:/OpenCV/testimage/test5.jpg");nif (src.empty()) {n printf("could not load image...n");nreturn -1;n }n namedWindow("input image", CV_WINDOW_AUTOSIZE);n imshow("input image", src);nn/*添加圖像邊界*/nint top = (int)(0.05*src.rows); //頂部長度,設定為圖像src大小的5%nint bottom = (int)(0.05*src.rows); //底部長度nint left = (int)(0.05*src.cols); //左邊長度nint right = (int)(0.05*src.cols); //右邊長度nRNG rng(123456); //定義一個隨機數,產生隨機邊界色彩nint c = 0;nint borderType = BORDER_DEFAULT; //邊界默認,自動填充圖像邊界nwhile (true) {n c = waitKey(500);nif ((char)c == 27) { //ESC鍵nbreak;n }nif ((char)c == r) {n borderType = BORDER_REPLICATE; //按R鍵 (複製邊界)n }nelse if ((char)c == v) {n borderType = BORDER_WRAP; //按V鍵 (包裝邊界,用另外一邊的像素來補償填充)n }nelse if ((char)c == c) {n borderType = BORDER_CONSTANT; //按C鍵 (常數邊界)n }nScalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); //邊框顏色值n copyMakeBorder(src, dst, top, bottom, left, right, borderType, color); //添加邊界n imshow("border image", dst);n }nn/*解決邊界問題應用*/n GaussianBlur(src, dst2, Size(5, 5), 0, 0, BORDER_DEFAULT); //高斯濾波n imshow("output image", dst2);nn waitKey(0);nreturn 0;n}n

運行結果:


推薦閱讀:

1.17【OpenCV圖像處理】Sobel運算元
如何用ps實現這張圖片中的致幻效果?
1.30【OpenCV圖像處理】圖像矩
[171111] Python OpenCV 中 SIFT 特徵點檢測和匹配
如何用 PS 把這種線條手摳出來?

TAG:OpenCV | 图像处理 | 计算机视觉 |