圖像濾波是一種十分常見的圖像處理手段蜘犁。通常扔字,你可以認為相鄰位置像素是緊密聯系的,它們共同來顯示對某個物體格嘁,圖像濾波則通過運算來排除圖像中和周圍相差大的像素笛求。當然,這并不是絕對的糕簿,有時候你為了評估圖像的質量探入,也會將這些“特立獨行”的像素作為選取的目標。無論你采用什么方法懂诗,記住你要的目標就行蜂嗽,有時候你的目標可能是別人的背景。
濾波常常會使得圖像變得模糊(非絕對)殃恒,那么植旧,為什么你需要將一幅清晰的圖像變得模糊呢?下面的例子應該可以解釋离唐。
相關博客:使用OpenCV進行實時車道檢測:http://www.reibang.com/p/c6b7a8a601f2
1.高斯濾波
高斯濾波采用滿足正態(tài)分布的核模板啊送,其參數的主要參數是標準差σ,代表核的離散程度欣孤,σ值越小馋没,模板中心系數與邊緣系數差越大,平滑的程度越小降传。
高斯濾波對圖像采集過程中由于不良照明/高溫引起的傳感器噪聲信號有較好的效果篷朵,消除了圖像中的高頻信號。
cv2,GaussianBlur(img, ksize, sigma_x, sigma_y,border_type)
只給定sigma_x時婆排,sigma_y會取相同的值声旺,如果兩個都是0,會依據核函數的大小計算段只。
cv2.getGaussianKernel(kszie, sigma, ktype)
ksize為核大小(奇數)腮猖,得到一個一維的垂向kernel
由于得到的是一維的Gaussian Kernel,你可以采用下面的方式轉為二維的
import cv2
import numpy as np
kernel_x = cv2.getGaussianKernel(5, 2, cv2.CV_32F)
kernel_y = cv2.getGaussianKernel(5, 2, cv2.CV_32F)
# 轉為2維的kernel
kernel_gaussian = np.multiply(kernel_x, np.transpose(kernel_y))
print(kernel_gaussian)
參考博客:二維高斯核函數https://blog.csdn.net/qq_16013649/article/details/78784791
對于kernel保留不同的小數位數對計算會產生一定的差距赞枕,請留意
為了便于直觀感受高斯濾波的效果,使用Canny算子來提取輪廓對比炕婶,你可以試試在特征提取前加高斯濾波對比姐赡。
# 高斯濾波
import cv2
import numpy as np
img=cv2.imread('scraths.jpg')
gray_img=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 高斯平滑,為了消除圖像中的噪聲
gaussian_img = cv2.GaussianBlur(gray_img,(5, 5),0)
# Canny算子
gaussian_canny_edges_img = cv2.Canny(gaussian_img, 100, 200, 5)
canny_edges_img = cv2.Canny(gray_img, 100, 200, 5)
cv2.imshow('canny_img',canny_edges_img)
cv2.imshow('gaussian_canny_img',gaussian_canny_edges_img)
cv2.imshow('gray_img', gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.均值濾波
均值濾波,中心點的像素為kernel區(qū)域像素的均值柠掂,使得像素間的差距變小项滑,達到平滑的效果,對脈沖型(椒鹽等)噪聲的效果不理想涯贞,不過在你需要提取輪廓特征時枪狂,讓圖像平滑些會更有利。blur_img_3 = cv2.blur(gray_img, (3, 3))
cv2.blur(img, ksize, anchor, bordertype)
anchor通常取-1肩狂,將錨點(被平滑的點)設置為kernel的中心
補充說明:對于均值濾波摘完,你也可以使用cv2.boxFilter(src, ddepth, ksize[, dst[, anchor[, normalize[, borderType]]]])來實現,需要將normalize設置為True,當設置normalize為False時傻谁,實現的是將kernel內像素相加,官方文檔做出的描述為:
Unnormalized box filter is useful for computing various integral characteristics over each pixel neighborhood, such as covariance matrices of image derivatives (used in dense optical flow algorithms, and so on). If you need to compute pixel sums over variable-size windows.) 鏈接:https://docs.opencv.org/3.0-beta/modules/imgproc/doc/filtering.html?highlight=cv2.bilateralfilter#boxfilter
在后期的光流處理算法中可能會涉及到
3.中值濾波
中值濾波對圖像中的脈沖型(椒鹽等)噪聲信號處理效果好列粪,當你的應用場景存在這種顆粒感的噪聲信號時审磁,中值濾波會是一種很好的選擇谈飒。它,選取kernel區(qū)域內像素點集的中值最為錨點的像素值态蒂,對類似投票機制中的最高分(高灰階點)和最低分(過低灰階點)影響有很好的抑制作用杭措。
cv2.medianBlur(img, ksize)
ksize須為奇數
4.雙邊濾波
如果你的應用涉及到圖像美化,雙邊濾波可以初步達到你的期望钾恢,關于雙邊濾波手素,這里不做展開,由你來探索瘩蚪,其函數參數信息如下泉懦。
cv2.bilateralFilter(img, d, sigma_color, sigma_space, bordertype)
d:表示在過濾過程中每個像素鄰域的直徑范圍。如果這個值是非正數疹瘦,則函數會從參數sigmaSpace計算該值崩哩。
sigmaColor: 顏色空間過濾器的sigma值,這個參數的值月大言沐,表明該像素鄰域內有月寬廣的顏色會被混合到一起邓嘹,產生較大的半相等顏色區(qū)域。
sigmaSpace: 坐標空間中濾波器的sigma值险胰,如果該值較大汹押,則意味著顏色相近的較遠的像素將相互影響,從而使更大的區(qū)域中足夠相似的顏色獲取相同的顏色起便。當d>0時鲸阻,d指定了鄰域大小且與sigmaSpace無關,否則d正比于sigmaSpace
參考博客:opencv學習(二十二)之雙邊濾波bilateralFilter:https://blog.csdn.net/keith_bb/java/article/details/54427779
5.filter2D自定義的kernel進行卷積
cv2.filter2D(src, ddepth, kernel[, anchor[, delta[, borderType]]])
ddepth:圖像的深度
kernel:自定義的核
anchor:錨點缨睡,默認(-1,-1)即核中心
delta:將像素存于dst之前會加上delta鸟悴,類似偏置
參考博客:Python-OpenCV中的filter2D()函數https://www.cnblogs.com/lfri/p/10599420.html
自定義kernel的方式如下:
# 根據自己kernel數據來選擇類型:https://www.runoob.com/numpy/numpy-dtype.html
kernel = np.array((
[0.0625, 0.125, 0.0625],
[0.125, 0.25, 0.125],
[0.0625, 0.125, 0.0625]), dtype = np.float32)
對于opencv-python的圖像濾波部分有問題歡迎留言, Have Fun With OpenCV-Python, 下期見奖年。