blur
也稱為 box filter、均值濾波器澡为,就是簡單地將每個像素的值替換成鄰域平均值。
cv::blur(image, result, cv::Size(3,3));
如果用 kernel (也稱為 mask) 表示顶别,就是
如果采用積分圖的方法拒啰,可以更快的計算這種 box filter 的結(jié)果。
在積分圖中谋旦,只需要三次加法運算,一次乘法運算即可册着,即通過積分圖,算出 kernel 內(nèi)部區(qū)域的像素和演熟,然后取平均。
積分圖
積分圖中每一點 ? 的值是原圖中對應(yīng)位置左上角區(qū)域所有值的和:
積分圖的計算可以很高效:
每次計算只需要新增一個像素值芒粹,其他值都是之前已經(jīng)計算出來的。
積分圖一旦計算出來化漆,對任意矩形區(qū)域內(nèi)像素和的計算都可以在常數(shù)時間(即計算時間固定,與區(qū)域的大小無關(guān))內(nèi)完成获三,例如:
GaussianBlur
在高斯濾波器中疙教,當(dāng)前像素值取鄰域的加權(quán)平均棺聊,離當(dāng)前像素越近贞谓,權(quán)重越大,權(quán)重服從高斯分布祟同。
在實際應(yīng)用中理疙,幾乎總是首選高斯濾波器晕城,很少直接用 box filter.
cv::GaussianBlur(image, result, cv::Size(5,5), 1.5); //最后的參數(shù)表示高斯分布的方差 sigma
上述命令中窖贤,最后兩個參數(shù) kernel size 和 ? 如果只設(shè)置一個,則另一個可以通過以下公式推出:
第二個式子很好理解滤蝠,就是借助高斯函數(shù)的性質(zhì)(距離均值 3 個標(biāo)準(zhǔn)差范圍內(nèi)的取值占總數(shù)的 99.7%)授嘀,因此窗口大小就是 3 倍的 ? *2 (兩邊)然后再加上 1 (自身)。
第一個式子與第二個非常近似蹄皱,但是又做了一些微調(diào)。
上述高斯濾波器內(nèi)部實際上是先調(diào)用如下函數(shù)巷折,產(chǎn)生服從高斯分布的一系列權(quán)重:
cv::getGaussianKernel(9, sigma, CV_32F); // 產(chǎn)生 9 個權(quán)重,與中心像素的距離依次為 -4晴弃,-3, ...3, 4
上述 9 個權(quán)重是經(jīng)過歸一化的,即和為 1上鞠,其公式為
其中 ? 滿足歸一化的要求,ksize 必須是奇數(shù)世曾。如果要生成二維的高斯矩陣權(quán)重,則是先產(chǎn)生一個權(quán)重列向量轮听,然后令該列向量與自身的轉(zhuǎn)置相乘岭佳,得到高斯矩陣權(quán)重,最后再統(tǒng)一進(jìn)行歸一化珊随,保證矩陣所有元素和為 1。
另外叶洞,還可以分別產(chǎn)生兩個不同的高斯權(quán)重向量,對應(yīng)行和列方向上的高斯模糊權(quán)重螟炫,然后把它們相乘得到高斯矩陣艺晴。由于滿足這種分離的性質(zhì)昼钻,高斯濾波器被稱為可分離的濾波器财饥。
非線性濾波器:中值濾波器
前邊在進(jìn)行濾波操作時折晦,都只包含線性操作(算數(shù)平均、加權(quán)平均)满着。
另外還可以采用非線性操作,對應(yīng)非線性濾波器宁改。非線性濾波器不能表示成 kernel 矩陣卷積操作的形式魂莫。
中值濾波器是一種非線性濾波器还蹲。它把當(dāng)前像素和鄰域像素組成一個集合,排序之后潭兽,選擇中間值(即排序中間位置的數(shù)值)替換當(dāng)前像素值斗遏。
椒鹽噪聲:像素隨機替換成白色或者黑點。在通訊時诵次,如果部分像素值丟失,就會產(chǎn)生這種噪聲逾一。
中值濾波器可以有效的消除椒鹽噪聲,因為這些噪聲點在排序時很難成為中間值归敬,因此全都被剔除了鄙早。
Sobel 邊緣檢測濾波器
Sobel 也是線性濾波器汪茧,只不過采用了特殊的 kernel 矩陣:
分別針對水平方向和垂直方向的操作舱污。
用上述 kernel 進(jìn)行操作,就是計算水平或者垂直方向像素值的差分扩灯,近似反映了像素值水平和垂直變化的速度霜瘪,合在一起就是圖像梯度的近似。
// 橫向的
cv::Sobel(image, // 輸入
sobelX, // 輸出
CV_8U, // 輸出數(shù)據(jù)類型
1, 0, // 采用第一個 kernel颖对,即計算 x 軸方向(橫向)像素變化率
3, // kernel 的大小
0.4, 128); // 縮放因子和偏移量
// 縱向的
cv::Sobel(image,
sobelY,
CV_8U,
0, 1, // 采用第二個 kernel悔橄,即計算 y 軸方向(縱向)像素變化率
3,
0.4, 128);
在默認(rèn)情況下自娩,差分運算的結(jié)果很可能超過 [0,255] 這個范圍,而且有正有負(fù)江解,應(yīng)該用 CV_16S 數(shù)據(jù)類型表示徙歼。經(jīng)過上述縮放和偏移之后犁河,才勉強適合用 CV_8U 表示,但還是需要飽和截斷操作耕魄。
cv::Sobel(image, sobelX, CV_16S, 1, 0);
在分別得到橫向彭谁、縱向變化率之后吸奴,可以整合起來計算梯度的大小
cv::Mat sobel;
sobel = abs(sobelX) + abs(sobelY); // 這里采用了 L1 范數(shù)
一般如果要顯示最后的 sobel 邊緣檢測的結(jié)果缠局,還需要把上述模值轉(zhuǎn)化到 [0,255] 范圍內(nèi)。
高斯導(dǎo)數(shù)
sobel 實際上包含了平滑和求導(dǎo)兩個操作读处,其中鄰域像素累加相當(dāng)于高斯平滑唱矛,距離越近的像素權(quán)重越高罚舱。
sobel 的 kernel size 可以選擇 1, 3, 5 和 7绎谦,其中 1 代表 1×3 或者 3×1,此時是沒有高斯平滑的包个。
對于大的 size,這種平滑更明顯碧囊。此時纤怒,sobel 不是高通濾波器,而是帶通濾波器泊窘,既消除了部分高頻,又消除了部分低頻州既。
其他梯度算子
與 Sobel 算子類似的還有其他幾個計算梯度的算子萝映,只是采用不同的 kernel.
- Prewitt
cv::Prewitt(image, prewittX, CV_16S, 1, 0);
- Roberts
cv::Roberts(image, robertsX, CV_16S, 1, 0);
- Scharr
cv::Scharr(image, robertsX, CV_16S, 1, 0);
上述所有的濾波器都是近似計算圖像函數(shù)的一階導(dǎo)數(shù)序臂,像素變化大的區(qū)域計算得到的值較大实束,平坦的區(qū)域計算值較小逊彭。
Laplacian 算子
sobel 算子通過對圖片函數(shù)求導(dǎo)咸灿,那些數(shù)值絕對值較高的點對應(yīng)了邊界區(qū)域:
如果繼續(xù)求二階導(dǎo)避矢,則導(dǎo)數(shù)較大的點對應(yīng)了過零點:
因此卸勺,也可以通過搜索二階導(dǎo)的過零點來檢測邊界點悟狱。
Laplacian 算子的定義:
對照 Hessian 矩陣:
Laplacian 算子實際上就是 Hessian 矩陣的 Trace富稻。
具體到圖像操作中,二階導(dǎo)有如下表達(dá)式:
所以最終 Laplacian 算子表達(dá)式為:
在具體實現(xiàn)中,可以用以下 kernel 進(jìn)行卷積操作:
Laplacian 算子具有旋轉(zhuǎn) 90 度不變性硼身,即一幅圖旋轉(zhuǎn) 90 度及其倍數(shù)营袜,對應(yīng)的 Laplacian 算子操作結(jié)果相同啸驯。
為了得到更好的旋轉(zhuǎn)不變性针姿,可以將 Laplacian 算子 kernel 擴展為如下形式:
這樣就具有了旋轉(zhuǎn) 45 度及其倍數(shù)的不變性。
cv::Laplacian(input,
output,
int ddepth, // 元素類型筒饰,由于輸入的是CV_8U,為了避免數(shù)據(jù)溢出,一般設(shè)定為 CV_16S
int ksize=1, // 求導(dǎo)數(shù)的 Sobel 算子的窗口大小帮孔,一般 ksize >1 奇數(shù)燎孟,如果取 ksize=1爆侣,則直接用上述 [1, -4, ...] kernel.
double scale=1, // 是否對計算得到的值進(jìn)行放縮
double delta, // 在存儲到 output 之前忍法,是否添加 bias
int borderType); // 邊界像素插值方式,具體選項可以官網(wǎng)查看 https://docs.opencv.org/3.4/d2/de8/group__core__array.html#ga209f2f4869e304c82d07739337eae7c5
LoG (Laplacian of Gaussian)
Laplacian 算子對噪聲比較敏感羹蚣,因此一般在進(jìn)行 Laplacian 之前先進(jìn)行高斯平滑濾波。
兩個步驟合并稱為 LoG (Laplacian of Gaussian)咽弦。
在具體實現(xiàn)中,我們并不需要先高斯再拉普拉斯离唬,而是兩步并作一步:將拉普拉斯算子作用在高斯 kernel 上划鸽,得到新的 kernel输莺,再與 image 做卷積:
最后作用在 ? 位置上的卷積權(quán)重為
同樣也是通過 ? 設(shè)定濾波范圍嫂用。
對高斯函數(shù)取拉普拉斯算子操作是什么樣子的?
- 一維形式
- 二維形式
二維情況下得到的曲面很像“墨西哥草帽”嘱函。
? 的大小決定了檢測的粗粒度:
DoG ( LoG 的近似)
Difference of Gaussians
為了減少 LoG 計算量埂蕊,用兩個不同 ? 的高斯做差疏唾,來近似 LoG
上圖中兩個 ? 的取值好像反了函似。。撇寞。