1. 程式人生 > >【拜小白opencv】28-平滑處理1線性濾波之——盒式濾波(方框濾波)

【拜小白opencv】28-平滑處理1線性濾波之——盒式濾波(方框濾波)

常言道“溫故而知新”,寫此文章就是對自己目前學習內容的小小的總結與記錄。

本文力求用最簡潔的語言,詳細的程式碼將此部分內容講解清楚,但由於博主同樣是剛剛接觸OpenCV,或許表達上有些瑕疵,還望讀者能夠指教探討,大家共同進步。

博主機器配置為:VS2013+opencv2.4.13+Win-64bit。

若本文能給讀者帶來一點點啟示與幫助,我就很開心了。

===========================分割線========================

1-盒式濾波(方框濾波)

  • 盒式濾波(方框濾波)是一種線性濾波技術,它的實現借鑑了積分影象的原理思想,在快速積分影象求解中,將計算某個矩陣畫素間的和值運算,轉化為求矩陣對應邊角點的求和差值運算。
  • 盒式濾波的實現最關鍵的步驟就是初始化陣列S,陣列S的每個值是存放畫素鄰域內的畫素和值,在求解某矩形塊中的畫素和時,只需要索引對應區域的位置存放的和值就可以完成計算。

原理:

先給出核心,用核心各點的值與對應的影象畫素值相乘:



可以才看出通過盒式濾波後,圖片的邊緣資訊會丟失。

=======================分割線=========================

2-boxFilter()函式——盒式濾波

OpenCV將盒式濾波封裝在boxFilter()函式中,作用是輸入一副影象對其進行盒式濾波。感興趣的同學可以看看其原始碼。下面來看下boxFilter()函式的定義:
void boxFilter( InputArray src, OutputArray dst, int ddepth,
                             Size ksize, Point anchor=Point(-1,-1),
                             bool normalize=true,
                             int borderType=BORDER_DEFAULT );
引數說明
  • 引數1:輸入要處理的影象。
  • 引數2:得到處理後的的輸出影象。
  • 引數3:影象的深度。-1代表使用原圖深度,即src.depth()。
  • 引數4:核心的大小。一般用Size(w,h)來表示核心大小,其中w為畫素寬度,h為畫素高度,正奇數或0。例:Size(3,3)就代表3×3的核大小。
  • 引數5:表示錨點,即被平滑的那個點。如果這個點座標是負值的話,就表示取核的中心點為錨點,所以預設值Point(-1,-1)表示這個錨點在核的中心。
  • 引數6:預設值為true,一個識別符號,表示核心是否被其區域歸一化了,具體見下面介紹。
  • 引數7:用於推斷影象外部畫素的某種邊界模式,有預設值BORDER_DEFAULT,我們一般不用管它。
boxFilter()函式盒式濾波所用的核表示如下:
對引數6具體解釋:
  • 當normalize = true 時,盒式濾波就變成了均值濾波。也就是說,均值濾波是盒式濾波歸一化(normalized)後的特殊情況。其中,歸一化就是把要處理的量都縮放到一個範圍內,比如(0,1),以便統一處理和直觀量化。
  • 當normalize = false時,為非歸一化的盒式濾波,用於計算每個畫素鄰域內的積分特性,比如密集光流演算法(dense optical flow algorithms)中用到的影象倒數的協方差矩陣(covariance matrices of image derivatives)。
=========================分割線====================

3-程式碼演示

/*
	盒式濾波(方框濾波)
*/

#include <opencv2/core/core.hpp>                
#include <opencv2/highgui/highgui.hpp>    
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>   
using namespace std;
using namespace cv;

int main()
{
	//------------【1】讀取源影象並檢查影象是否讀取成功------------   
	Mat srcImage = imread("D:\\OutPutResult\\ImageTest\\boat1.jpg");
	if (!srcImage.data)
	{
		cout << "讀取圖片錯誤,請重新輸入正確路徑!\n";
		system("pause");
		return -1;
	}
	imshow("【源影象】", srcImage);
	//------------【2】對影象進行盒式濾波(方框濾波)處理------------   
	Mat dstImage;
	boxFilter(srcImage, dstImage, -1, Size(5, 5), Point(-1, -1), false); //false為非歸一化情況
	imshow("【盒式濾波/方框濾波】", dstImage);
	waitKey(0);
}

=======================分割線=====================

4-顯示結果

非歸一化情況如下
歸一化情況如下
=======================分割線================

5-程式說明

可以發現,非歸一化的時候,得到影象就是一片白色,對源影象毀壞太大,根本無法使用。

而歸一化的時候,得到影象是一種模糊的效果,此時與均值濾波一樣。

下一節我們將瞭解均值濾波的時候方法。

=====================END==============