【发布时间】:2014-01-11 06:29:52
【问题描述】:
我一直在尝试使用现有 SVG 滤镜工具箱中有限的一组图元来复制双边滤镜效果(边缘保留、颜色范围感知)。我尝试了多种方法。我迄今为止最成功的是一个三部分操作,它进行 Sobel 边缘检测,扩大 Sobel 边缘,通过合成操作提取与这些边缘相对应的像素,高斯模糊源图像,然后在顶部合成原始边缘像素图像模糊。结果保留了边缘,但不支持颜色范围。
<filter id="surfaceBlur" color-interpolation-filters="sRGB">
<!-- convert source image to luminance map-->
<feColorMatrix type="luminanceToAlpha" />
<!-- sober edge detection-->
<feConvolveMatrix order="3" kernelMatrix="-1 -2 -1
0 0 0
1 2 1 "
preserveAlpha="true"
/>
<feConvolveMatrix order="3" kernelMatrix="-1 0 1
-2 0 2
-1 0 1 "
preserveAlpha="true"
/>
<!-- dilate the edges to produce a wider mask-->
<feMorphology operator="dilate" radius="1"
result="mask"/>
<!-- extract just the detail from the source graphic using the dilated edges -->
<feComposite operator="in" in="SourceGraphic" in2="mask" result="detail" />
<!-- blur the source image -->
<feGaussianBlur stdDeviation="3" in="SourceGraphic" result="backblur"/>
<!-- slap the detail back on top of the blur! -->
<feComposite operator="over" in="detail" in2="backblur"/>
您可以看到原始的 gaussianBlur,这个过滤器,在右下角,一个真正的双边过滤器:
http://codepen.io/mullany/details/Dbyxt
如您所见,这不是一个糟糕的结果,但它与双边过滤器不是很接近。此方法也仅适用于灰度图像,因为它使用亮度差异来查找边缘 - 因此不会检测到相似亮度颜色之间的边缘。
所以问题是是否有边缘保留颜色范围感知过滤器(引导边缘视图、双边等)的算法变体 - 可以使用 SVG 中可用的有限原语构建 - 对于不熟悉 SVG 的人来说是:
- 高斯模糊
- 卷积(任何内核大小)
- 侵蚀/扩张
- 颜色矩阵
- 所有 porter duff 合成操作
- 基本混合操作(乘法、加网、变亮、变暗)
- 一种组件传输原语,它允许通过表格查找(以及将底限/上限转换为特定值)来转换颜色通道
只有 RGB 颜色空间可用。多次迭代没问题,这些操作的任何有向图都可以构造出来。
更新:
我成功创建了一个中值过滤器,使用 feBlend lighten 和 darken 作为冒泡排序中的 Max 和 Min 运算符(感谢 cs.stackexchange.com 的帮助)。然而这是低效的:http://codepen.io/mullany/pen/dmbvz,并且缺乏双边滤镜的颜色范围感知。
【问题讨论】:
-
您总是可以建议在dev.w3.org/fxtf/filters 中添加额外的过滤器@ Firefox 和 Chrome 正在实现此规范中的功能。
-
是的,罗伯特,我有一封很长的电子邮件,我正在为需要的过滤器撰写邮件,现在自定义过滤器已被取消。
标签: algorithm image-processing svg