加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 软件梯形失真校正算法

发布时间:2020-12-15 02:27:49 所属栏目:Java 来源:网络整理
导读:作为我的软件的一部分,我正在寻找一个梯形失真校正滤镜,以避免在投影仪以不垂直于屏幕的角度显示时可以获得的墓碑/梯形失真效果. 目前我已经有了一些工作,但速度非常慢(整个图像约为100毫秒),理想情况下我想要更快的速度(最好是在10毫秒范围内).我基本上只是
作为我的软件的一部分,我正在寻找一个梯形失真校正滤镜,以避免在投影仪以不垂直于屏幕的角度显示时可以获得的墓碑/梯形失真效果.

目前我已经有了一些工作,但速度非常慢(整个图像约为100毫秒),理想情况下我想要更快的速度(最好是在10毫秒范围内).我基本上只是循环整个图像像素按像素将我想要的像素复制到一个新数组中,然后将新图像的rgb内容设置为这个新数组:

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;
}

这样做最好的方法是什么?一个自定义仿射变换最初是我要看的,但我找不到任何代码/示例,指出我正确的方向.有没有比上面更好的方法来实现我想要的结果?

解决方法

您可以采取一些措施来加快现有代码的速度.请注意,这些将使您的代码更加混乱,更难以阅读……并进行调试.但是,如果算法正在运行,那么重构以获得更好的性能可能不会太困难:

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

查看完全用Java编写的ImageJ.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读