gpt4 book ai didi

image-processing - Javafx 图片到低多边形艺术转换器

转载 作者:行者123 更新时间:2023-12-01 00:17:46 28 4
gpt4 key购买 nike

我正在尝试使用 javafx 制作一个程序来转换这样的图片:
left: normal picture, right : low poly picture

在这张照片中,背景并不是我想要的样子,但中间的鳄梨是我想要实现的一个很好的例子。我现在拥有的是两个过滤器,它们将根据亮度在图片中找到边缘,如下所示:

public void processImage() {
ww = (int) Math.ceil(image.getWidth());
hh = (int) Math.ceil(image.getHeight());
pixelAmount = (long) ww * (long) hh;
pxDA = new pxInfo[ww][hh];
PixelReader pr = image.getPixelReader();
if(pr != null) {
System.out.println("pixel reader found");
WritableImage i = new WritableImage(ww, hh);
for(int x = 0; x < ww; x++) {
for(int y = 0; y < hh; y++) {
Color c = pr.getColor(x, y);
double a = c.getOpacity();
double r = c.getRed();
double g = c.getBlue();
double b = c.getBlue();

double[][] gray = new double[3][3];
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
if(!((j == 0 && x == 0) || (k == 0 && y == 0) || (j
== 2 && x == ww - 1) || (k == 2 && y == hh - 1))) {
Color cl = pr.getColor(x - 1 + j, y - 1 + k);
gray[j][k] = 0.299 * cl.getRed() + 0.587 *
cl.getGreen() + 0.114 * cl.getBlue();
}
}
}

// apply filter
double gray1 = 0, gray2 = 0;
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
gray1 += gray[j][k] * filter1[j][k];
gray2 += gray[j][k] * filter2[j][k];
}
}
double magnitude = clamp(0.0, 1.0 - Math.sqrt(gray1 * gray1 +
gray2 * gray2), 1.0);
Color color = new Color(magnitude, magnitude, magnitude, 1);
i.getPixelWriter().setColor(x, y, color);
}
}
stackPane.getChildren().add(new ImageView(i));
}
}

这部分代码运行良好,以下是一些结果:

过滤前:
before applying filters
过滤后:
after applying filters
但问题是我不知道从哪里开始。我在互联网上寻找各种算法,但我真的找不到任何有明确解释的东西,所以我想我会在这里问。因此,如果您知道我可以应用的一些算法/过滤器来改进这一点,我想听听。

然后还有我实际上需要创建三角形/多边形的部分。假设我已经应用了所有过滤器等,然后我该怎么办?比如我如何区分形状和灰度图片?任何帮助将不胜感激。

提前致谢,

莱纳吉

最佳答案

我特别不熟悉 JavaFX,但我尝试使用 解决一个非常相似的问题。 python OpenCV :

https://github.com/tasercake/lowpolypy

这就是我如何去做的。

一般流程:

  • 预处理图像(双边/高斯模糊以去除噪声等)
  • 从图像中获取关键点(使用下面详述的方法)
  • 从关键点获取多边形(使用 Delaunay 三角剖分或类似算法)
  • 阴影多边形(例如,使用多边形内所有像素的平均颜色)
  • 后期处理(对比度、饱和度调整等)


  • 1. 预处理

    在继续进行关键点提取之前,对图像进行预处理有助于去除许多不必要的高频细节。

    您可以使用诸如 之类的过滤器来实现此目的。双边过滤器高斯滤波器 .

    您可能还想在此处缩小图像以加快处理速度,但这并不是绝对必要的。

    2.关键点提取

    这可能是最困难的部分,也是最需要微调/实验的部分。

    您可以尝试的一些方法是:

    Canny Edge Detection

    任何物有所值的图像处理/计算机视觉库(例如 OpenCV)都应该内置它。

    此方法为您提供一个 bool 图像,其中潜在边缘标记为“真”。然后,您可以选择这些点的随机子集并将它们转换为 (X, Y) 坐标(或任何对您最方便的格式)。

    我发现这种方法加上一点点随机化,需要最少的调整。

    Laplacian of Gaussian

    这是另一种检测图像显着特征的方法,但基于图像像素的二阶导数(与基于一阶导数的 Canny 滤波器相反)。

    此过滤器返回一个图像,您可以将其标准化并用作权重掩码以从中随机采样一组关键点(也许有比这更好的过滤器使用方法,但我不会被打扰)。

    随机替换

    一旦您从所有其他方法中积累了一组关键点,您可以选择用一组随机生成的关键点替换所有点的一个小的随机子集。

    我发现这有助于在最终输出中引入一些美观的不规则之处。

    微动关键点

    除了彻底替换一小部分关键点之外,我还对每个关键点进行了少量“摇晃”(随机翻译)。这有助于引入更多的随机性,并允许您多次运行程序以获得一个潜在的良好输出。

    NOTE: Don't forget to add the 4 corners of your image as keypoints, or you'll end up with empty/black regions around your output.



    3. 将关键点连接成多边形

    Delaunay Triangulation是一种算法,它连接平面中的一组点,以使由此形成的每个三角形中的最小角度最大化。 (显然,如果您不完全想要三角形,这将不起作用)。

    4. 阴影多边形

    对于每个多边形,您需要获得多边形所包含区域内所有图像像素的平均值。 OpenCV 有一个函数( cv2.mean(image, mask) ),通过将多边形作为二进制掩码传递,您可以在很少的行中完成此操作。

    一些结果:

    fox |
    fox_lowpoly

    eminem |
    eminem_lowpoly

    关于image-processing - Javafx 图片到低多边形艺术转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51037903/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com