首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >软件keystone校正算法

软件keystone校正算法
EN

Stack Overflow用户
提问于 2011-09-05 08:26:21
回答 1查看 2.9K关注 0票数 4

作为我的软件的一部分,我想写一个keystone校正过滤器,以避免当投影仪以不垂直于屏幕的角度显示时出现的墓碑/ keystone效果。

目前我已经得到了一些工作,但它是令人难以置信的慢(整个图像约100ms),理想情况下,我希望有更快的东西(最好在10ms范围内)。我基本上只是逐个像素地循环整个图像,并将我想要的像素复制到一个新的数组中,然后将新图像的rgb内容设置到这个新的数组中:

代码语言:javascript
复制
public BufferedImage getCorrectedImage() {
    double width = originalImage.getWidth(null) * 0.5;
    double increment = (originalImage.getWidth(null) - width)/originalImage.getHeight();

    BufferedImage ret = new BufferedImage(originalImage.getWidth(null), originalImage.getHeight(null), BufferedImage.TYPE_INT_ARGB);

    for (int h = 0; h < originalImage.getHeight(); h++) {
        int[] arr = new int[originalImage.getWidth()];
        for (int w = 0; w < originalImage.getWidth(); w++) {
            arr[w] = originalImage.getRGB(w, h);
        }
        int[] newPixels = getShortLine(arr, (int) (width + 0.5));

        for (int w = 0; w < originalImage.getWidth(); w++) {
            ret.setRGB(w, h, newPixels[w]);
        }
        width += increment;
    }

    return ret;
}

private int[] getShortLine(int[] original, int newSize) {
    int[] newArr = new int[original.length];
    double scale = original.length / newSize;
    int start = (original.length - newSize) / 2;
    int end = original.length - ((original.length - newSize) / 2);
    for (int i = start; i < end-1; i++) {
        newArr[i] = original[(int) ((i - start) * scale)];
    }
    return newArr;
}

做这件事最好的方法是什么?自定义仿射变换最初是我要看的,但我找不到任何代码/示例来为我指明正确的方向。有没有比上述更好的方法来达到我想要的结果呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-09-05 08:48:36

有几件事你可以做来加速你现有的代码。需要注意的是,这些代码会让你的代码变得更混乱,更难阅读……和调试。但是,如果算法是有效的,那么重构以获得更好的性能可能并不太困难:

  • 尝试使用profiler来查看您的算法中是否存在不太明显的瓶颈。
  • 您每次在getCorrectedImage函数中的循环中重新定位一个新数组。这是随着时间的推移将累积起来的内存分配。为了加快速度,只创建一个数组(最大的像素宽度/高度),并在函数的整个生命周期中重用它。您可能需要添加一些额外的变量来跟踪实际使用的内容。
  • 尝试内联您的getShortLine方法。我不确定JVM是否会在运行时内联它,或者是否有一种方法可以检查它是否会内联。在任何情况下,如果数组重用不能提高您的性能,那么可能值得尝试一下内联"manually."
  • Just,您也可以将此函数设为静态函数。只需将originalImage成员作为变量传递即可。这也可能对性能有轻微影响,特别是对于类加载。将其定义为静态也是有意义的,因为唯一的变量似乎是图像,而且可以很容易地传入。即没有其他类成员依赖项。它看起来确实应该是实用程序类中的实用程序方法。

请查看ImageJ,它完全是用Java语言编写的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7302970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档