【问题标题】:Calculating Image Displacement - Java计算图像位移 - Java
【发布时间】:2013-12-27 05:39:00
【问题描述】:

简而言之,我正在做与光学鼠标相同的事情。
我正在使用两个灰度二维数组,现在正在比较相等的值,看看有什么区别。

示例:
数组1:
1 1 0 0
0 1 0 0
0 0 0 0
0 0 0 0

数组2:
0 0 0 0
0 1 1 0
0 0 1 0
0 0 0 0

这是我现在用来测试它的代码。我现在只检查 1,就好像它是实际图像一样。改变并不难。

int[][] t1 = new int[][]{
                {1,1,0,0},
                {0,1,0,0},
                {0,0,0,0},
                {0,0,0,0}
        };
        int[][] t2 = new int[][]{
                {0,0,0,0},
                {0,1,1,0},
                {0,0,1,0},
                {0,0,0,0}   
        };
        double mag = 0.0;
        double angle = 0.0;
        int num = 0;
        for (int i = 0; i < t2.length; i++){
            for (int j = 0; j < t2[i].length; j++){
                if(t2[i][j] == 0) continue;
                //scan through and calculate average magnitude/angle
                if(t2[i][j] == 1){
                    for (int k = 0; k < t1.length; k++){
                        for (int l = 0; l < t1[k].length; l++){
                            if(t1[k][l] == 1){
                                mag += calculateMagnitude(l, k, j, i);
                                angle -= calculateAngle(l, k, j, i);
                                num++;
                            }
                        }
                    }
                }
            }
        }
        double fMag = mag/num;
        double fAngle = angle/num;
        System.out.println(fMag);
        System.out.println(fAngle);
public static double calculateAngle(int x1, int y1, int x2, int y2){
    if(y2 == y1){
        if(x2 > x1) return 90.0;
        else if(x2 < x1) return -90.0;
        else return 0.0;
    } else if(x2 == x1){
        if(y2 > y1) return 0.0;
        else if(y2 < y1) return -180.0;
    }
    return Math.toDegrees(Math.atan( ((double)(y2-y1))/(x2-x1) ));
}

public static double calculateMagnitude(int x1, int y1, int x2, int y2){
    double d1 = Math.pow((x2 - x1),2);
    double d2 = Math.pow((y2 - y1), 2);
    return Math.sqrt(d1 + d2);
}  

但是,这是相当繁重的,因为它是 O(n^4),我相信有更有效的方法可以做到这一点。我已经做了很多研究,但到目前为止还没有弄清楚如何去做。同样,现在确切的答案应该是 1.414 和 -45,这意味着我偏离了大约 6%。这没关系,但我想更准确一点。

如果有人知道或能想出一种更有效和/或更准确地做到这一点的方法,请发布。不要听起来像个混蛋,但将我链接到博士研究论文并说它应该有效并不是我想要的。我已经进行了大量研究,这些论文主要是指图像是否仍完全显示在屏幕上。

我正在寻找一种方法来计算图像位移,即使图像的一部分离开屏幕。

【问题讨论】:

  • 两个图像是否相同但位置不同,或者您需要模糊匹配吗?也是纯位移还是旋转?
  • 你要的最大排量是多少?
  • 纯位移。理想情况下,它们将是相同的,但可能有一部分被置换的图像会从屏幕上消失,因此它可能是最佳匹配。
  • 听起来像光流算法可能会派上用场......
  • @Tim B:最大位移未知,但图像将具有 60Hz 的刷新率,所以我认为不会过度。

标签: java image algorithm image-processing


【解决方案1】:

这个答案不是太具体,但太长了,无法放在评论中:

适当的方法取决于您的输入和场景。我不清楚您是要查看图像中的特定点如何移动,还是要尝试将整个图像与下一帧对齐。您问题的不同部分向我提出了其中一个建议。

您能否添加要使用的图像/框架示例?他们是如何被俘虏的?这会有很大帮助。我不确定您是否正在尝试将复杂的照片或基本屏幕截图与鼠标光标或其他东西完全对齐。如果您在此处尽可能具体,希望人们可以帮助您使用该技术,而不仅仅是将您链接到研究论文。

如果您要查找一张图像的特定部分在下一帧中的位置,您应该查找“模板匹配”。

如果您尝试将整张图像与下一张对齐,并且您知道这是通过图像的简单翻译给出的,那么您应该查找图像对齐、图像配准以及术语“从粗到细” ”。

一种“从粗到细”的技术通常如下工作:您从两个图像的一个小的、调整大小的版本开始,找到那里的位移,然后放大并找到下一个比例的位移,粗解为初始猜测(并且您搜索接近此初始猜测)并重复直到您达到完整分辨率。目的是加快速度并避免解决方案陷入局部最小值。

如果有两帧包含大量复杂运动,那么您需要查找“光流”,旨在找到每个像素的位移。

【讨论】:

  • 我的想法就像你拍摄一张图像,比如说一个圆圈,然后将它移开任意幅度和角度。这可能会导致屏幕上只剩下四分之一的圆圈。所以我必须将第二张图片与第一张图片进行比较,看看它出现在哪里。从你提到的那些对我来说这听起来像光流
  • 所以您看到的是人造图像,而不是照片?你从哪里得到输入?听起来更像是模板匹配。
  • 将从智能手机的摄像头输入。它只是灰度。所以我要比较图像的灰度值
  • 您应该记住,帧之间的灰度值几乎永远不会相同。手机摄像头会记录什么样的事情?您能否显示示例输入图像?计算完平移/光流后,您需要做什么?对于带有移动相机的一般场景,您不能只计算图像的单个平移 - 您将需要光流算法 - 但在受限场景(例如场景仅包含平面表面)中,您可以使用更快的方法。
  • 我希望我能提供一张照片。这是一个两个人的项目,另一个人还没有完全工作。它将位于像桌子一样的平面上。它会像光学鼠标一样工作,因此可以检测到它在哪里移动。我知道它不会是精确的灰度图像,所以我想我会给它一个误差范围。
【解决方案2】:

您似乎有一个简单的注册问题,我很确定有更简单的方法可以解决您的问题,但最快(就实施时间而言)就是使用类似SIFT 的方法,如果您不这样做'使用 3rd 方没有问题,您可以使用此列表中的某些内容Implementing SIFT in Java

Sift 会在两幅图像中找到相似的补丁,并从那里很容易计算图像的平移。

【讨论】:

    猜你喜欢
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多