我有一幅使用较冷和较冷的颜色表示2D空间中深度的图像。我希望能够像在Matlab中一样将其绘制为3D表面图。我一直在玩jzy3d,但是我是java的新手,所以在执行此操作时遇到了麻烦。理想情况下,像在Matlab中一样,实现此目的的最佳方法是将其转换为灰度然后绘制它,但我不知道如何做,因此不胜感激。

先感谢您。

最佳答案

您应该更详细地描述实际的困难是什么。

但是,我很好奇(并且想尝试jzy3d)。因此,我修改了SurfaceDemo.java样本以加载图像并绘制各个像素的Hue值。



从本质上讲,它可以归结为“较暖”和“较冷”的确切含义(无双关语),但是应该可以从色相值中得出。 (注意:图像中的颜色仅是绘图的颜色,与图像中的颜色无关。图像中的颜色仅决定绘图在每个点的高度。)

import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

import org.jzy3d.analysis.AbstractAnalysis;
import org.jzy3d.analysis.AnalysisLauncher;
import org.jzy3d.chart.factories.AWTChartComponentFactory;
import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.colors.colormaps.ColorMapRainbow;
import org.jzy3d.maths.Range;
import org.jzy3d.plot3d.builder.Builder;
import org.jzy3d.plot3d.builder.Mapper;
import org.jzy3d.plot3d.builder.concrete.OrthonormalGrid;
import org.jzy3d.plot3d.primitives.Shape;
import org.jzy3d.plot3d.rendering.canvas.Quality;

public class BasicJzy3D extends AbstractAnalysis
{
    public static void main(String[] args) throws Exception
    {
        BufferedImage image = ImageIO.read(new File("lena512color.png"));
        AnalysisLauncher.open(new BasicJzy3D(image));
    }

    private final BufferedImage image;

    BasicJzy3D(BufferedImage image)
    {
        this.image = image;
    }


    /**
     * Returns the RGB value in the given image at the specified location,
     * which is given in relative coordinates (between 0.0 and 1.0).
     * Invalid coordinates will be clamped to the border
     *
     * @param image The image
     * @param x The x coordinate
     * @param y The y coordinate
     * @return The RGB value
     */
    private static int getRGB(BufferedImage image, double x, double y)
    {
        int w = image.getWidth();
        int h = image.getHeight();
        int ix = (int)(x * w);
        int iy = (int)(y * h);
        ix = Math.max(0, Math.min(w-1, ix));
        iy = Math.max(0, Math.min(h-1, iy));
        int rgb = image.getRGB(ix, iy);
        return rgb;
    }

    /**
     * Returns the hue for the given RGB color
     * @param rgb The RGB color
     * @return The hue
     */
    private static float getHue(int rgb)
    {
        int r = (rgb >> 16) & 0xFF;
        int g = (rgb >>  8) & 0xFF;
        int b = (rgb >>  0) & 0xFF;
        float hsb[] = new float[3];
        java.awt.Color.RGBtoHSB(r, g, b, hsb);
        float hue = hsb[0];
        return hue;
    }

    static class ImageToValueMapper extends Mapper
    {
        private final BufferedImage image;

        ImageToValueMapper(BufferedImage image)
        {
            this.image = image;
        }

        @Override
        public double f(double x, double y)
        {
            int rgb = getRGB(image, x, y);
            float hue = getHue(rgb);
            return hue;
        }
    }


    @Override
    public void init()
    {
        Mapper mapper = new ImageToValueMapper(image);

        // Define range and precision for the function to plot
        Range range = new Range(0, 1);
        int steps = 80;

        // Create the object to represent the function over the given range.
        final Shape surface = Builder.buildOrthonormal(
            new OrthonormalGrid(range, steps, range, steps), mapper);
        surface.setColorMapper(
            new ColorMapper(new ColorMapRainbow(),
                surface.getBounds().getZmin(),
                surface.getBounds().getZmax(),
                new Color(1, 1, 1, 1.0f)));
        surface.setFaceDisplayed(true);
        surface.setWireframeDisplayed(false);

        // Create a chart
        chart = AWTChartComponentFactory.chart(
            Quality.Advanced, getCanvasType());
        chart.getScene().getGraph().add(surface);
    }
}

10-07 19:12
查看更多