c++ - 如何实现梯度高斯模糊?

标签 c++ image image-processing

我想实现渐变 高斯模糊效果。 渐变 是指与 Photoshop 相同的效果。以下图为例:

Gradient Gaussian Blur image
(来源:photokaboom.com)

图像的模糊度随着y坐标的增加而降低(以左上角为原点)。

我知道如何使用内核和 FFT 实现普通高斯模糊,但我不知道如何随着 y 坐标的变化来改变模糊程度。我尝试将图像分成不同的线(在 y 轴方向)并对这些 block 应用不同的内核,但在这些线的连接部分效果非常烦人。

我也试过逐个计算结果像素,运行时填充核,效果还不错,就是算法太慢了!!

所以我想知道如何实现快速梯度高斯模糊算法?

非常感谢!

最佳答案

模糊是二维操作,很难按行处理,每行都有不同程度的模糊。在考虑高斯模糊之前,我建议探索一种在视觉上与高斯模糊几乎无法区分的方框模糊解决方案。

一种方法是使用 Integral image .自己创建它是一个很好的练习,而且非常简单:积分图像的大小与原始图像的大小相同。内容是当前像素上方和左侧所有像素强度的总和(我们分别讨论每个 rgb channel )。构建积分图像的一种简单迭代方法是使用以下公式:

I(x,y)= Gray(x, y) + I(x-1, y) + I(x, y-1) - I(x-1, y-1) 

提示:如果您先计算一个时间数组,其中每个元素只是将同一行中它左侧的强度相加,则可以更快地完成计算。

积分图像的美妙之处在于它们允许在恒定时间内计算任意 大小的窗口中的总和。实际上,这只需要4个操作:对于x1, y1, x2, y2处的窗口和积分图像I(x, y)

sum(x1, y1, x2, y2) = I(x2, y2)+I(x1, y1)-I(x1, y2)-I(x2, y1)

这样你就可以实现一个快速的blur box filter(你不会在视觉上看到box和Gaussian filter效果的区别)

Iblur(x, y, sz) = I(x+sz, y+sz)+I(x, y)-I(x+sz, y)-I(x, y+sz)/[sz*sz]

您现在需要做的就是将快速模糊操作应用于所有随 y 变化的 sz 像素。只需要 4*w*h 操作;建立你的积分图像也是 O(h*w) 所以你实际上可以在线性时间内完成。分别为每个 channel 执行此操作并将它们组合成一个新的 rgb。

最后,积分图像计算是 Haar 盒滤波器(而不是小波或 Gabors)的基础,用于快速检测人脸或物体、跟踪等。它们的速度是当今实时寻找人脸的关键,因此它们值得学习。

关于c++ - 如何实现梯度高斯模糊?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22436502/

相关文章:

c++ - 带有无符号整数的奇怪 gcc 行为

javascript - 更改 img src 单击监听器以更改第二个 img src

image - react native : is it recommended to use PNG or SVG images?

python - Yolo Darknet 仅检测特定类别,如人、猫、狗等

c++ - 在 openCV 中为 oclMat 添加小图像到大图像

matlab - 如何在 Matlab 中绘制二维 FFT?

c++ - 使用 Boost 的进程间读/写锁

c++ - 写在文件上,信息最终出现在控制台中

c++ - 使用模板和构造函数从两个派生类进行多重继承

python - 多线程时 cv2 图像显示不起作用