Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中的图像:最有效的浮点表示法?_Java_Image_Image Processing - Fatal编程技术网

java中的图像:最有效的浮点表示法?

java中的图像:最有效的浮点表示法?,java,image,image-processing,Java,Image,Image Processing,我需要用java做一些图像处理。我正在移植python代码,它使用numpy数组,数组的维数为cols、rows、channels;这些是浮点。我知道如何将RGB从BuffereImage中取出并将其放回原处;这个问题是关于如何布局生成的浮动图像 以下是一些选项: 直接翻译: float[][]img=新的float[cols][rows][channels]; 将频道放在首位: float[][]img=新的float[channels][cols][rows]; 合并索引: float[

我需要用java做一些图像处理。我正在移植python代码,它使用numpy数组,数组的维数为cols、rows、channels;这些是浮点。我知道如何将RGB从BuffereImage中取出并将其放回原处;这个问题是关于如何布局生成的浮动图像

以下是一些选项:

  • 直接翻译:
  • float[][]img=新的float[cols][rows][channels];
    
  • 将频道放在首位:
  • float[][]img=新的float[channels][cols][rows];
    
  • 合并索引:
  • float[]img=新浮点[行*列*通道];
    img[i*cols*通道+j*通道+k]=。。。;
    
    选项1的优点是它读取的代码与原始代码相同;但对于Java来说,它似乎不是惯用语言,可能也不太快

    如果我理解Java N维数组在引擎盖下是如何工作的,那么选项2应该更快;以看起来有点古怪为代价。这似乎分配了
    channels*cols
    大小为
    rows
    的数组,而选项1分配了
    rows*cols
    大小为
    channels
    的数组(非常多的小数组=很大的开销)

    选项3似乎最接近AWT和其他Java代码的功能;但是它需要传递维度(它们没有内置到数组中),并且很容易导致索引错误(特别是在有其他索引算法的情况下)

    哪一个更好?为什么?其他的优点和缺点是什么?还有更好的办法吗

    更新


    我在一个非平凡的图像处理示例上对选项1和选项2进行了基准测试,该示例运行四种不同的算法(在10倍循环中,因此VM开始预热)。这是在Ubuntu上的OpenJDK 7上,Intel i5 cpu。令人惊讶的是,速度差别不大:选项2比选项1慢约6%。在收集的内存垃圾量上有很大的不同(使用
    java-verbose:gc
    ):选项1在整个运行期间收集1.32GB内存,而选项2只收集0.87GB(不是一半,但也不是所有使用的图像都是彩色的)。我想知道Dalvik会有多大的不同?

    你是对的,选项3的内存占用更小

    至于哪一个性能更好,您必须对选项进行评测和/或基准测试


    如果您声明行数和列数都很大,我会选择选项3,但将数组包装在一个知道维度的类中,例如称为
    Image
    您是对的,选项3的内存占用较小

    至于哪一个性能更好,您必须对选项进行评测和/或基准测试


    如果您声明行和列计数很大,我会选择选项3,但将数组包装在一个知道维度的类中,例如称为
    Image

    选项3由Java中的BuffereImage使用。正如Andreas所说,这对记忆有好处,但对于图像处理和信息连续性来说,这并不是最优的。 最实际的是:

    float[][] img = new float[channels][cols*rows];
    

    这样,通道是分离的,因此可以独立处理。如果要调用本机代码,此表示将是最佳的。

    选项3由Java中的BuffereImage使用。正如Andreas所说,这对记忆有好处,但对于图像处理和信息连续性来说,这并不是最优的。 最实际的是:

    float[][] img = new float[channels][cols*rows];
    
    这样,通道是分离的,因此可以独立处理。如果要调用本机代码,此表示将是最佳的。

    具有浮点图像类型,可以直接操作原始像素数据。看

    BoofCV提供了几个例程,用于将BuffereImage快速转换为不同的BoofCV映像类型。使用BoofCV例程转换缓冲区图像非常快

    使用BoofCV将缓冲区图像转换为多光谱浮点型图像:

    MultiSpectral<ImageFloat32> image =
        ConvertBufferedImage.convertFromMulti(image,null,true,ImageFloat32.class);
    
    获取和设置像素值的另一种方法:

    float value = image.getBand(i).data[ image.startIndex + y*image.stride + x];
    
    float f = image.getBand(i).get(x, y);
    ...
    image.getBand(i).set(x, y, f);
    
    BufferedImage bufferedImage =
        new BufferedImage(image.width, image.height, BufferedImage.TYPE_4BYTE_ABGR);
    BufferedImage bufferedImage = ConvertBufferedImage.convertTo(
        image, bufferedImage, true);
    
    其中i表示颜色通道的索引

    将BoofCV图像转换回buffereImage:

    float value = image.getBand(i).data[ image.startIndex + y*image.stride + x];
    
    float f = image.getBand(i).get(x, y);
    ...
    image.getBand(i).set(x, y, f);
    
    BufferedImage bufferedImage =
        new BufferedImage(image.width, image.height, BufferedImage.TYPE_4BYTE_ABGR);
    BufferedImage bufferedImage = ConvertBufferedImage.convertTo(
        image, bufferedImage, true);
    
    具有浮点图像类型,可以直接操作原始像素数据。看

    BoofCV提供了几个例程,用于将BuffereImage快速转换为不同的BoofCV映像类型。使用BoofCV例程转换缓冲区图像非常快

    使用BoofCV将缓冲区图像转换为多光谱浮点型图像:

    MultiSpectral<ImageFloat32> image =
        ConvertBufferedImage.convertFromMulti(image,null,true,ImageFloat32.class);
    
    获取和设置像素值的另一种方法:

    float value = image.getBand(i).data[ image.startIndex + y*image.stride + x];
    
    float f = image.getBand(i).get(x, y);
    ...
    image.getBand(i).set(x, y, f);
    
    BufferedImage bufferedImage =
        new BufferedImage(image.width, image.height, BufferedImage.TYPE_4BYTE_ABGR);
    BufferedImage bufferedImage = ConvertBufferedImage.convertTo(
        image, bufferedImage, true);
    
    其中i表示颜色通道的索引

    将BoofCV图像转换回buffereImage:

    float value = image.getBand(i).data[ image.startIndex + y*image.stride + x];
    
    float f = image.getBand(i).get(x, y);
    ...
    image.getBand(i).set(x, y, f);
    
    BufferedImage bufferedImage =
        new BufferedImage(image.width, image.height, BufferedImage.TYPE_4BYTE_ABGR);
    BufferedImage bufferedImage = ConvertBufferedImage.convertTo(
        image, bufferedImage, true);
    

    这些都是在桌面上进行基准测试(只比python慢10倍)。但在选项1中,内存使用率似乎要高出2倍。如果我理解这一点,那么选项2和选项3的内存占用都将比选项1小得多。另一方面,2和3将非常接近(使用典型的维度:rows和cols~1000,channels~3),这些都在桌面上进行适当的基准测试(仅比python慢10倍)。但在选项1中,内存使用率似乎要高出2倍。如果我理解这一点,那么选项2和选项3的内存占用都将比选项1小得多。另一方面,2和3将非常接近(使用典型尺寸:行和列~1000,通道~3)