介紹
課程的最後乙個實驗是處理雀斑,網上查詢了很多方法,最後我選擇了快速雙邊濾波。但是實驗又不能直接呼叫 opencv 的庫,因此,我參照了 這個部落格,將用 c 寫的快速雙邊濾波改用 python 重新寫了一遍。
快速雙邊濾波是啥呢,官方滴說,它是一種非線性的濾波方法。它最大的特點就是既使用了顏色的相似度,又利用了空間的距離相似度。也就是說,它在進行濾波的過程中,不光要考慮周圍畫素值與中點畫素值的大小之差,還需要考慮空間上的距離,進而確定該點對中間點的影響因子。
至於為啥要用快速雙邊濾波呢,,因為不優化的話,實在是太慢了。。。有興趣可以試一下。
優化**
主要的優化思路如下,提前計算好高斯模板,提前計算好各灰度值的濾波模板
**實現
完整的**如下:
# -*- coding: utf-8 -*-
import numpy as np
import cv2
import math
def bilateralfilter(img, radius, sigmacolor, sigmaspace) :
b, g, r = cv2.split(img)
b_tran, g_tran, r_tran = cv2.split(img)
img_height = len(b)
img_width = len(b[0])
# 計算灰度值模板係數表
color_coeff = -0.5 / (sigmacolor * sigmacolor)
weight_color = # 存放顏色差值的平方
for i in range(256) :
# 計算空間模板
space_coeff = -0.5 / (sigmaspace * sigmaspace)
weight_space = # 存放模板係數
weight_space_row = # 存放模板 x軸 位置
weight_space_col = # 存放模板 y軸 位置
maxk = 0
for i in range(-radius, radius+1) :
for j in range(-radius, radius+1) :
r_square = i*i + j*j
r = np.sqrt(r_square)
maxk = maxk + 1
# 進行濾波
for row in range(img_height) :
for col in range(img_width) :
value = 0
weight = 0
for i in range(maxk) :
m = row + weight_space_row[i]
n = col + weight_space_col[i]
if m < 0 or n < 0 or m >= img_height or n >= img_width :
val = 0
else :
val = b[m][n]
w = np.float32(weight_space[i]) * np.float32(weight_color[np.abs(val - b[row][col])])
value = value + val * w
weight = weight + w
b_tran[row][col] = np.uint8(value / weight)
# 綠色通道
for row in range(img_height) :
for col in range(img_width) :
value = 0
weight = 0
for i in range(maxk) :
m = row + weight_space_row[i]
n = col + weight_space_col[i]
if m < 0 or n < 0 or m >= img_height or n >= img_width :
val = 0
else :
val = g[m][n]
w = np.float32(weight_space[i]) * np.float32(weight_color[np.abs(val - g[row][col])])
value = value + val * w
weight = weight + w
g_tran[row][col] = np.uint8(value / weight)
# 紅色通道
for row in range(img_height) :
for col in range(img_width) :
value = 0
weight = 0
for i in range(maxk) :
m = row + weight_space_row[i]
n = col + weight_space_col[i]
if m < 0 or n < 0 or m >= img_height or n >= img_width :
val = 0
else :
val = r[m][n]
w = np.float32(weight_space[i]) * np.float32(weight_color[np.abs(val - r[row][col])])
value = value + val * w
weight = weight + w
r_tran[row][col] = np.uint8(value / weight)
cv2.imshow("beauty_after", cv2.merge([b_tran, g_tran, r_tran]))
cv2.imwrite("beauty_after.png", cv2.merge([b_tran, g_tran, r_tran]))
img = cv2.imread("beauty1.png")
cv2.imshow("original image", img)
# bilateralfilter(img, 5, 45, 100)
bilateralfilter(img, 3, 30, 80)
img = cv2.imread("beauty_after.png")
bilateralfilter(img, 3, 30, 80)
cv2.waitkey(0)
總結
三個維度的濾波不應該像我這樣寫,應該一起處理,我分成了三個通道進行處理,**就顯得有點長,但這樣十分方便,如果有時間的話,還是不要像我這樣寫。
需要注意的一點是,這段**在處理的效果上不是很好,相比於 opencv 的庫,效果差了很多,尤其是處理大的時候,使用時需要注意。
OpenCV實現雙邊濾波演算法
雙邊濾波是一種綜合考慮濾波器內影象空域資訊和濾波器內影象畫素灰度值相似性的濾波演算法,可以實現在保留區域資訊的基礎上實現對雜訊的去除 對區域性邊緣的平滑。雙邊濾波對高頻率的波動訊號起到平滑的作用,同時保留大幅值變化的訊號波動,進而實現對保留影象中邊緣資訊的作用。雙邊濾波具有美顏效果。include ...
雙邊濾波(Bilateral filter)
強大的雙邊濾波器可平滑平坦區域,同時保持邊緣銳化。因此,它可作為乙個自動的 化或圖畫濾波器,其缺點是效率低 即該濾波器執行的時間要按秒,甚至分鐘而不是毫秒來計算 那麼如何 化一副影象時,還可接受其執行時間。最重要的技巧就是在低解析度下使用雙邊濾波,這會得到與高解析度下相似的效果,但執行速度更快。可將...
雙邊濾波(Bilateral filter)
雙邊濾波器 bilateral filter 是一種可以保邊去噪的濾波器。可以濾除影象資料中的雜訊,且還會保留住影象的邊緣 紋理等 因雜訊是高頻訊號,邊緣 紋理也是高頻資訊,高斯濾波會在濾除雜訊的同時使得邊緣模糊 那這麼優秀的乙個濾波器,他到底是個什麼呢,其實,它和我們普通的高斯濾波器一樣,也是使用...