从图像中提取直方图的更快方法

发布于 2024-12-17 13:26:03 字数 695 浏览 3 评论 0原文

我正在寻找一种更快的方法来从图像中提取直方图数据。 我目前正在使用这段代码,对于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

dawn曙光 2024-12-24 13:26:03

您正在执行很多getSamples方法调用,而它们又依次进行调用和调用等。

我经常处理图片和提高速度的典型技巧是直接操作底层的int[](在这种情况下,您的 BufferedImage 必须由 int[] 支持)。

访问 int[] 和执行 getRGB 之间的区别可能是巨大的。当我写巨大时,我的意思是多达两个数量级(尝试在 OS X 10.4 上执行 getRGBint[x] 相比,你会看到性能获得)。

另外,没有调用 3 次 getSamples。我只需检索与您的 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 p = 0; p < width*height; p++ ) {

现在,如果您想进行更奇怪的优化,但不太可能证明有效,您可以:

  • 使用循环展开(迭代超过 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:

final int[] a = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

Also you can do what you want to do with a single loop, looping over all the pixels.

Instead of:

for ( int x = 0; x < width; x++ ) {
    for ( int y = 0; y < height; y++ ) {
        ....

You can do:

for ( int p = 0; p < width*height; p++ ) {

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--)

源来凯始玺欢你 2024-12-24 13:26:03

您可以使用 getSamples(int x, int y, int w, int h, int b, double[] dArray) 方法
该方法可能有内部优化。
另外,您可以尝试交换宽度和高度。

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

并且

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

这两个变体之间的性能差异将是巨大的。
这是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.

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

And

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

Between this two variants performance difference will be huge.
This is influence of the cpu cache

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文