Java 从图像中提取直方图的快速方法

Java 从图像中提取直方图的快速方法,java,image,histogram,Java,Image,Histogram,我正在寻找一种从图像中提取直方图数据的更快方法。 我目前正在使用这段代码,6mpx JPEG图像大约需要1200ms: ImageReader imageReader = (ImageReader) iter.next(); imageReader.setInput(is); BufferedImage image = imageReader.read(0); int height = image.getHeight();

我正在寻找一种从图像中提取直方图数据的更快方法。 我目前正在使用这段代码,6mpx JPEG图像大约需要1200ms:

        ImageReader imageReader = (ImageReader) iter.next();
        imageReader.setInput(is);
        BufferedImage image = imageReader.read(0);
        int height = image.getHeight();
        int width = image.getWidth();
        Raster raster = image.getRaster();
        int[][] bins = new int[3][256];

        for (int i = 0; i < width; i++) 
            for (int j = 0; j < height; j++) {
                bins[0][raster.getSample(i, j, 0)]++;
                bins[1][raster.getSample(i, j, 1)]++;
                bins[2][raster.getSample(i, j, 2)]++;

            }
ImageReader ImageReader=(ImageReader)iter.next();
imageReader.setInput(is);
BuffereImage image=imageReader.read(0);
int height=image.getHeight();
int width=image.getWidth();
光栅=image.getRaster();
int[]bins=新int[3][256];
对于(int i=0;i
你有什么建议吗?

你可以使用getSamples(intx,inty,intw,inth,intb,double[]dArray)方法 这种方法可能有内部优化。 此外,您还可以尝试交换宽度和高度

for (int i = 0; i < width; i++) 
   for (int j = 0; j < height; j++) {
   }
}
for(int i=0;i

for(int i=0;i
这两种变体之间的性能差异将是巨大的。 这是cpu缓存的影响

您正在进行大量的getSamples方法调用,而他们又在进行调用和调用等

我经常处理图片,提高速度的典型技巧是直接操作底层的int[](在这种情况下,您的BuffereImage必须有int[]作为后盾)

访问int[]和执行getRGB之间的区别可能是巨大的。当我写Gignant时,我指的是两个数量级(试着在OSX10.4和int[X]上做一个getRGB,你会看到性能增益)

还有,三次都没有电话。我只需检索一个对应于ARGB像素的int,然后进行位移位以获得RGB波段(您正在为每个R、G和B分量做一个直方图,对吗?)

通过执行以下操作,可以访问像素阵列:

final int[] a = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
你也可以用一个循环来做你想做的事情,在所有的像素上循环

而不是:

for ( int x = 0; x < width; x++ ) {
    for ( int y = 0; y < height; y++ ) {
        ....
for(int x=0;x
你可以做:

for ( int p = 0; p < width*height; p++ ) {
for(int p=0;p
现在,如果您想进行更奇怪的优化,而不太可能证明其有效,您可以:

  • 使用循环展开(在600万像素范围内进行迭代是极少数有帮助的情况之一)

  • 反转循环:for(p=width*height-1;p>=0;p--)


您确定要进行交换吗?如果图像是垂直的,而不是水平的,该怎么办?您假设所有图像都是水平的。根据结果的准确性,您可以采取子样本并进行推断。
for ( int p = 0; p < width*height; p++ ) {