Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果 - 描边

相对浮雕效果来说,描边(边缘检测)的代码并不复杂多少,只是在理论上相对来说稍微复杂一点,而且效果看上去更加的讨人喜欢一些。

如果在图像的边缘处,灰度值肯定经过一个跳跃,我们可以计算出这个跳跃,并对这个值进行一些处理,来得到边缘浓黑的描边效果。

首先考虑对这个象素的左右两个象素进行差值,得到一个差量,这个差量越大,表示图像越处于边缘,而且这个边缘应该左右方向的。同样我们能得到上下方向和两个对角线上的图像边缘。这样我们需要构造一个滤波器

Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十二)

经过这个滤波器后得到的是图像在这个象素处的变化差值,把它转化成灰度值并求绝对值(差值可能为负),然后我们定义差值的绝对值越大的地方越黑(边缘显然是黑的),否则越白,可以得到如下的效果:

Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十三)

该效果的代码如下(其中dip_filter函数代码同上):

Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十四)

上面演示的效果种用到的模板就是一种边缘检测器,在信号处理上是一种基于梯度的滤波器,又称边缘算子。梯度是有方向的,和边沿的方向总是正交(垂直)的,在上面的代码中,我们采用的就是一个梯度为45度方向模板,它可以检测出135度方向的边沿。

以上是简单的边缘检测算子。更加严格的,我们可以采样Sobel算子。Sobel 算子有两个,一个是检测水平边沿的Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十五),另一个是检测垂直平边沿的Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十六)同样,Sobel算子另一种形式是各向同性Sobel算子,也有两个,一个是检测水平边沿的Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十七),另一个是检测垂直边沿的Direct3D提高篇:HLSL编程实现PhotoShop滤镜效果(1)(图二十八)。各向同性Sobel算子和普通Sobel算子相比,它的位置加权系数更为准确,在检测不同方向的边沿时梯度的幅度一致。读者可以自行尝试Sobel算子的效果,只要修改pencil_filter的值就可以了。

你可能感兴趣的:(photoshop)