位图阿尔法斜角算法?

信息处理 图像处理 过滤器 算法
2021-12-22 04:37:04

我正在寻找一种算法,它使用它的 alpha 作为凹凸贴图为位图添加斜角效果。

我怎么会去做这样的事情?我尝试过镜面反射照明,但我只得到高光而不是阴影。

这是我正在谈论的效果(使用Photoshop制作): 在此处输入图像描述

所有这些都是使用size: 30px(位图轮廓的斜角深度)完成的angle 130,,altitude 50

从左到右,从上到下:

  1. 凿子硬斜面
  2. 凿子软斜面
  3. 光滑斜面
  4. 凿硬与soften: 16px- 一个模糊的斜面?

我正在尝试创建这些效果中的每一个,我将如何创建基本斜面?我需要什么才能从那个斜面到达每一个

2个回答

这可以通过距离变换的卷积来完成。

在蒙版边缘使用距离变换。然后阈值此距离变换以删除超出某个距离的值。我认为获得阴影的秘诀是将距离变换结果与看起来像这样的内核进行卷积:

[ -1.0  -1.0  -1.0
  -1.0   0.0   0.0
  -1.0   0.0   1.0 ]

这应该让您朝着正确的方向开始:

#include "opencv/cv.h"
#include "opencv/highgui.h"

using namespace cv;
using namespace std;

int main() {
    Mat mask, dist, bevel;
    mask = Mat::zeros(200, 400, CV_8U);
    rectangle(mask, Point(30,30), Point(180,180), Scalar(255), -1);
    circle(mask, Point(30,30), 50, Scalar(0), -1);
    circle(mask, Point(180,180), 50, Scalar(0), -1);
    circle(mask, Point(300,100), 75, Scalar(255), -1);
    imshow("1",mask);

在此处输入图像描述

    //find edges and invert image for distance transform
    Canny(mask, dist, 50, 150);
    dist = 255-dist;
    distanceTransform(dist, dist, CV_DIST_L2, CV_DIST_MASK_5);
    threshold(dist, dist, 20, 20, CV_THRESH_TRUNC);
    blur(dist, dist, Size(3,3));
    dist.convertTo(bevel, CV_8U);
    equalizeHist(bevel, bevel);
    imshow("2",bevel);

在此处输入图像描述

    //convolve with secret sauce
    float d[] = {-1,-2,-3,
                 -2, 0, 0,
                 -3, 0, 1 };
    Mat kernel(3, 3, CV_32F, d);
    kernel = kernel - mean(kernel)[0];
    filter2D(dist, dist, CV_32F, kernel);

    //normalize filtering result to [-1, 1]
    double maxVal;
    minMaxLoc(dist, NULL, &maxVal);
    dist = 128 * dist / maxVal;

    //convert and display result
    dist.convertTo(bevel, CV_8U, 1, 128);
    bevel = bevel.mul(mask)/255;
    imshow("3", bevel);

在此处输入图像描述

    waitKey(0);
}

Photoshop 的斜面和浮雕效果可以预见:

1) 在临时 8 位单通道图像中计算距离变换

  • Chisel 使用带有倒角度量的欧几里得距离变换(3x3、5x5 或 7x7,具体取决于尺寸)。如果愿意,您可以使用精确的欧几里德距离变换,我更喜欢 Meijster 的那个,因为它可以抗锯齿(“A General Algorithm for Computing Distance Transforms in Linear Time”,MEIJSTER)。

  • Smooth Bevel 使用 Chamfer 5-7-11 距离变换和两次应用盒模糊来生成凹凸贴图。

2) 对中间距离变换图像应用凹凸映射。Blinn 的原始技术是合适的。

3) 对于软化,您可以对表面法线执行卷积,也可以使用内核对其进行过滤。

4) 使用凹凸贴图,将表面法线与全局光源相结合,将光照强度计算为从 -1 到 1 的值,其中负值是阴影,正值是高光,绝对值是光的大小资源。

5) 计算两个 8 位单通道临时图像,一个来自高光强度,另一个来自阴影。从那里开始,使用每个蒙版使用颜色、混合模式和不透明度为图层着色是一件小事——一个蒙版用于高光,另一个用于阴影。

可以在此处找到用于实现其中一些的 Visual Basic 源代码:

http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=51640&lngWId=1

请访问我的开源 LayerEffects 项目以了解更多信息:

https://github.com/vinniefalco/LayerEffects.git

我希望这可以帮助别人。