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 把這種線條手摳出來?