1. 程式人生 > >【OpenCV3】平滑處理詳解

【OpenCV3】平滑處理詳解

“平滑”通常又稱“模糊”,是一種簡單常用的影象處理操作。進行平滑處理的原因有很多,但通常是用來去除噪聲和相機失真,平滑在按照一定的原理來降低影象解析度中也有重要應用。

OpenCV2和OpenCV3中提供了5種不同的平滑處理方法,每一種都有自己相關的庫函式,每一個庫函式實現的平滑都略有不同。在所有的平滑操作函式中,src和dst兩個引數都分別代表源影象和目標影象。除此之外,每一種平滑操作都具有特定的相關操作引數。其中,唯一的共同引數是最後的borderType,這個引數表示平滑操作的過程中如何處理影象的邊緣的畫素。

下面將分別對這5中平滑操作函式進行介紹。

1、cv::blur()

void cv::blur(
	cv::InputArray src, // 輸入影象
	cv::OutputArray dst, // 輸出影象
	cv::Size ksize, // 核大小
	cv::Point anchor = cv::Point(-1,-1), // 錨點位置
	int borderType = cv::BORDER_DEFAULT // 邊界處理方法
);

cv::blur()又被稱作“簡單平滑”操作,輸出影象中的每個畫素值,為視窗中(如核)所有畫素的簡單平均值,視窗的大小通過ksize引數指定。引數anchor可以用來指定核心是如何與被計算的畫素對齊的。預設情況下,anchor的取值為cv::Point(-1,-1),這意味著,核相對於濾波器居中。在多通道影象中,每個通道需要分別計算。

cv::blur()實際上是下面要介紹的cv::boxFilter()的一個特例,實際平滑效果如下。


2、cv::boxFilter()

void cv::boxFilter(
	cv::InputArray src, // 輸入影象
	cv::OutputArray dst, // 輸出影象
	int ddepth, // 位深(如 CV_8U)
	cv::Size ksize, // 核大小
	cv::Point anchor = cv::Point(-1,-1), // 錨點位置
	bool normalize = true, // 如果是 true, 用box area進行劃分
	int borderType = cv::BORDER_DEFAULT // 邊界處理方法
);

cv::boxFilter()相對於cv::blur()來說更為通用,後者是前者的一種特殊形式。所謂"盒形濾波器"即為,任意一個矩形形狀濾波器,其中所有的均相等,通常情況下 = 1,或者 = 1/A,其中A為濾波器的面積,如下圖所示。


二者間的主要區別在於,cv::boxFilter()可以在非歸一化模式(normalize = false)下執行,且輸出影象的位深可以控制(在cv::blur中,dst的位深始終和src保持一致)。如果ddepth的值設為-1,則輸出影象和輸入影象的位深一致;否則,你可以選擇常用的任何位深(如CV_32F)。平滑效果如下:


3、cv::medianBlur()

void cv::medianBlur(
	cv::InputArray src, // 輸入影象
	cv::OutputArray dst, // 輸出影象
	cv::Size ksize // 核大小
);

cv::medianBlur()即通常所說的均值濾波,其主要思想是,用中心畫素矩形鄰域內的中值來替代中心畫素。平滑效果如下:


4、cv::GaussianBlur()

void cv::GaussianBlur(
	cv::InputArray src, // 輸入影象
	cv::OutputArray dst, // 輸出影象
	cv::Size ksize, // 核大小
	double sigmaX, // x方向高斯半寬
	double sigmaY = 0.0, // y方向高斯半寬
	int borderType = cv::BORDER_DEFAULT // 邊界處理方法
);

cv::GaussianBlur()即高斯濾波,是最常用的一種濾波方式。其主要思想是,使用高斯核與輸入影象中的每個點作卷積運算,然後對卷積結果進行求和,從而得到輸出影象。

對於cv::GaussianBlur()而言,引數ksize用於指定濾波視窗的寬和高;sigmaX為高斯核在x方向上的sigma值;sigmaY為高斯核在y方向上的sigma值;如果你只指定x的值,而將y的值設為0,則y的值將被認為和x相同。如果二者均被指定為0,則高斯引數則自動使用下式進行計算:


下圖是ksize = (5,3), sigmaX = 1, and sigmaY = 0.5的高斯核示例:


平滑效果如下:


5、cv::bilateralFilter()

void cv::bilateralFilter(
	cv::InputArray src, // 輸入影象
	cv::OutputArray dst, // 輸出影象
	int d, // 畫素臨接大小(最大距離)
	double sigmaColor, // 顏色權重函式寬度引數
	double sigmaSpace, // 空間權重函式寬度引數
	int borderType = cv::BORDER_DEFAULT // 邊界處理方法
);

cv::bilateralFilter(),即雙邊濾波,是一種可以保持影象邊緣的平滑方法。和高斯濾波類似,雙邊濾波也是通過計算中畫素和鄰域畫素的加權平均所實現的,只是其權值由兩部分組成。其中,第一部分和高斯平滑的權值相同;第二部分也是高斯權值,但是該權值並不是基於中心畫素的空間距離,而是基於和中心畫素點的灰度值的差異。

雙邊濾波函式有3個主要引數(不包括輸入和輸出):第一個引數d是濾波過程中的畫素鄰域直徑;第二個引數是用於顏色域高斯核的引數,稱作sigmaColor,和高斯濾波中的sigma引數類似;第三個引數是空間域中的高斯核寬度,稱作sigmaSpace。平滑效果如下:


2017.03.29