水泥效应 - 艺术效果

时间:2010-01-13 10:02:54

标签: c++ c algorithm graphics image-processing

我希望对图像产生影响,其中所得到的图像看起来好像是在粗糙的水泥背景上绘制的,并且水泥背景在边缘附近自定义以突出它们...请帮我写一个算法产生这样的效果。 第一张图片是原始图片

alt text

并且第二个图像是我正在寻找的输出。 alt text

请注意检测到边缘并且边缘在边缘附近变化以清楚地指示边缘

3 个答案:

答案 0 :(得分:4)

您需要阅读Bump Mapping。有很多凹凸贴图algorithms

基本算法是:

每个像素

  1. 在凹凸贴图纹理上查找与凸起图像上的位置对应的位置。
  2. 计算凹凸贴图的表面normal
  3. 将步骤2中的曲面法线添加到几何曲面法线(如果是图像,则为向上的矢量),使法线指向新的方向。
  4. 使用例如Phong阴影计算新“凹凸”曲面与场景中灯光的相互作用 - 灯光位置取决于您,并决定阴影所在的位置。
  5. 最后,这是2D图像的plain C implementation

答案 1 :(得分:2)

从开始 1)输入图像为R,G,B和 2)纹理图像,灰度。

图像可能以字节为单位,0到255.将其除以255.0,因此我们将它们从0.0到1.0。这使得数学更容易。对于性能,你实际上不会这样做,而是使用聪明的定点数学,这是我留给你的实现问题。

首先,要获得不同颜色区域之间的边缘效果,请在纹理图像中添加或减去R,G和B通道的某些部分:

texture_mod = texture - 0.2*R - 0.3*B

你可以通过非线性论坛得到更好的体验,例如:对R,G和B通道进行阈值处理,或者计算涉及它们的一些数学表达式。实验总是很有趣;我不确定什么能最好地重现你的例子。

接下来,计算texture_mod的浮雕版本以创建光照效果。这是纹理滑动向上和向右一个像素(或者你喜欢多少)的差异,并且相同的纹理滑动。这给出了3D照明效果。

emboss =  shift(texture_mod, 1,1) - shift(texture_mod, -1, -1)

(您应该在此公式中使用texture_mod还是原始纹理数据?实验并查看。)

这是动力步骤。将输入图像转换为HSV空间。 (LAB或其他颜色空间可能效果更好,或者没有 - 实验和看到。)请注意,在您想要的最终图像中,“mesas”之间的裂缝较暗,因此我们将使用原始的texture_mod和浮雕差异来改变V通道,具有控制效果强度的系数:

Vmod = V * ( 1.0 + C_depth * texture_mod + C_light * emboss)

C_depth和C_light都应该介于0和1之间,可能是较小的分数,如0.2到0.5左右。你需要一个软糖因子来防止Vmod溢出或夹紧它的最大值 - 除以(1 + C_depth + C_light)。明亮端的一些夹紧可能有助于高光看起来更亮。一如既往的实验,看看......

作为精确点,你也可以用某种方式修改饱和度通道,也许在texture_mod较低的地方减少它。

最后,将(H,S,Vmod)转换回RGB色彩空间。

如果内存紧张或性能至关重要,您可以跳过HSV转换,并将Vmod公式应用于单独的R,G,B通道,但这会导致色调和饱和度发生变化。这是速度与美观之间的权衡。

答案 2 :(得分:1)

这称为凹凸贴图。它用于使表面具有不平坦的外观。