Surface Blur 效果
PhotoShop 中有一种叫做 Surface Blur 的效果。
与其他模糊效果不同, Surface Blur 可以在模糊的同时保留图像的边缘特征。使用 Surface Blur 得到的图片,像是油画一般被划分为多个色块。
双边滤波 Bilateral filter
双边滤波,是结合图像的空间邻近度和像素值相似度的一种折衷处理。双边滤波器能够做边缘保存(edge preserving),不能干净地滤掉彩色图像里的高频噪声,只对低频信息滤波。
本质上,双边滤波就是考虑到灰度差距的高斯滤波。高斯核会根据像素间的灰度差调整权值,达成保留边缘的目的。
代码示例
使用 Python 下的 OpenCV 库,利用双边滤波实现 Surface Blur 效果。
import cv2 as cv
im = cv.imread('input.png')
blur = cv.bilateralFilter(im,9,75,75)
cv.bilateralFilter(src, d, sigmaColor, sigmaSpace)
的输入参数解释如下:
src
就是输入图像d
,处理半径。该值过大会造成严重的性能问题sigmaColor
,滤波处理时选取的颜色差值范围。值越大,图片越模糊sigmaSpace
,坐标空间的标注方差。数值越大,越远的像素会相互影响,图片的 “色块感” 会越强烈
借助 GPT4 写了个实时预览三个参数效果的 UI 界面,把输入图像 input.png
放在同目录下即可。可以用来玩玩:
import cv2
import tkinter as tk
from PIL import Image, ImageTk
im = cv2.imread('input.png')
window = tk.Tk()
label = tk.Label(window)
label.pack()
def update_image(d, sigmaColor, sigmaSpace):
blur = cv2.bilateralFilter(im, d, sigmaColor, sigmaSpace)
image = Image.fromarray(cv2.cvtColor(blur, cv2.COLOR_BGR2RGB))
size = image.size
# image = image.resize((int(size[0] * 0.75), int(size[1] * 0.75)))
photo = ImageTk.PhotoImage(image)
label.config(image=photo)
label.image = photo
d_scale = tk.Scale(
window,
from_=1,
to=40,
orient='horizontal',
length=400,
command=lambda d: update_image(int(d), sigmaColor_scale.get(), sigmaSpace_scale.get()),
)
d_scale.pack()
sigmaColor_scale = tk.Scale(
window,
from_=1,
to=255,
orient='horizontal',
length=400,
command=lambda sigmaColor: update_image(d_scale.get(), int(sigmaColor), sigmaSpace_scale.get()),
)
sigmaColor_scale.pack()
sigmaSpace_scale = tk.Scale(
window,
from_=1,
to=255,
orient='horizontal',
length=400,
command=lambda sigmaSpace: update_image(d_scale.get(), sigmaColor_scale.get(), int(sigmaSpace)),
)
sigmaSpace_scale.pack()
window.mainloop()
参考来源
- https://stackoverflow.com/questions/64980097/implement-surface-blur-in-python
- Jargon,“OpenCV 学习:9 双边滤波bilateralFilter”,https://zhuanlan.zhihu.com/p/127023952