【问题标题】:Faster way to extract histogram from an image从图像中提取直方图的更快方法
【发布时间】:2012-01-03 07:42:55
【问题描述】:

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

            }

你有什么建议吗?

【问题讨论】:

  • 根据结果需要的准确度,您可以抽取子样本并进行推断。

标签: java image histogram


【解决方案1】:

您正在执行 lotgetSamples 方法调用,而它们依次进行调用和调用等。

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

访问 int[] 和执行 getRGB 之间的差异可能是巨大的。当我写 gigantic 时,我的意思是多达两个数量级(尝试在 OS X 10.4 与 int[x] 上执行 getRGB,你会看到性能增益)。

另外,没有调用 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 万像素是可能有帮助的罕见情况之一)

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

【讨论】:

    【解决方案2】:

    您可以使用 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缓存的影响

    【讨论】:

    • 你确定交换?如果图像是垂直的而不是水平的怎么办?
    • 你假设所有的图像都是水平的。
    猜你喜欢
    • 2016-10-20
    • 1970-01-01
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2016-06-20
    • 1970-01-01
    相关资源
    最近更新 更多