从图像中提取直方图的更快方法
我正在寻找一种更快的方法来从图像中提取直方图数据。 我目前正在使用这段代码,对于 6mpx JPEG 图像大约需要 1200 毫秒:
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)]++;
}
您有什么建议吗?
I'm looking for a faster way to extract histogram data from an image.
I'm currently using this piece of code that needs about 1200ms for a 6mpx JPEG image:
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)]++;
}
Do you have any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在执行很多的getSamples方法调用,而它们又依次进行调用和调用等。
我经常处理图片和提高速度的典型技巧是直接操作底层的int[](在这种情况下,您的 BufferedImage 必须由 int[] 支持)。
访问 int[] 和执行 getRGB 之间的区别可能是巨大的。当我写巨大时,我的意思是多达两个数量级(尝试在 OS X 10.4 上执行 getRGB 与 int[x] 相比,你会看到性能获得)。
另外,没有调用 3 次 getSamples。我只需检索与您的 ARGB 像素相对应的一个 int,然后进行位移以获得 RGB 波段(您正在为每个 R、G 和 B 分量绘制一个直方图,对吗?)。
您可以通过执行以下操作来访问像素数组:
此外,您还可以使用单个循环执行您想要执行的操作,循环遍历所有像素。
而不是:
您可以这样做:
现在,如果您想进行更奇怪的优化,但不太可能证明有效,您可以:
使用循环展开(迭代超过 600 万像素是可能有帮助的罕见情况之一)< /p>
反转循环:for ( p = width*height - 1; p >= 0; p--)
You're doing a lot of getSamples method calls and they're in turn doing calls and calls etc.
I work often with pictures and the typical trick to gain speed is to manipulate directly the underlying int[] (in this case your BufferedImage must be backed by an int[]).
The difference between accessing the int[] and doing, say, a getRGB can be gigantic. When I write gigantic, I mean by as much as two orders of magnitude (try doing a getRGB on OS X 10.4 vs int[x] and you'll see the perf gain).
Also, there's no call three times getSamples. I'd simply retrieve one int corresponding to your ARGB pixel and then bitshift to get the RGB bands (you're doing one histogram per R, G and B component right?).
You can gain access to the pixels array by doing something like this:
Also you can do what you want to do with a single loop, looping over all the pixels.
Instead of:
You can do:
Now if you want to get into weirder optimizations, not as likely to prove effective you could:
use loop unrolling (iterating over 6 million pixels is one of the rare case where it may help)
invert the loop: for ( p = width*height - 1; p >= 0; p--)
您可以使用 getSamples(int x, int y, int w, int h, int b, double[] dArray) 方法
该方法可能有内部优化。
另外,您可以尝试交换宽度和高度。
并且
这两个变体之间的性能差异将是巨大的。
这是cpu缓存的影响
You can use getSamples(int x, int y, int w, int h, int b, double[] dArray) method
It's possible that this method have internal optimisations.
Also, you can try to swap width and height.
And
Between this two variants performance difference will be huge.
This is influence of the cpu cache