计算图像位移 - Java

时间:2013-12-09 22:17:25

标签: java image algorithm image-processing

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

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

ARRAY2:
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%。这没关系,但我想更确切。

如果有人知道某种方式或者能够找到更有效和/或精确地做到这一点的方法,请发布。不要听起来像屁股,但把我与博士研究论文联系起来并说它应该有效并不是我想要的。我做了大量的研究,这些论文主要是指图像是否仍然完全显示在屏幕上。

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

2 个答案:

答案 0 :(得分:1)

您似乎有一个简单的注册问题,我很确定有更简单的方法来解决您的问题,但最快(就实施时间而言)只是使用类似SIFT的内容,如果你使用第三方时没有问题,您可以使用此列表中的内容Implementing SIFT in Java

Sift将在两个图像中找到类似的补丁,从那里可以很容易地计算出图像的平移。

答案 1 :(得分:0)

这个答案不是太具体,但是太长而不适合评论:

适当的方法取决于您的输入和方案。我不清楚你是否试图看到图像中的特定点如何移动,或者你是否试图将整个图像与下一帧对齐。你问题的不同部分向我提出了一个或另一个。

您是否可以添加要使用的图像/帧的示例?他们是如何被捕获的?这将有很大帮助。我不确定您是否尝试使用鼠标光标或其他完全对齐复杂照片或基本屏幕截图。如果您可以在这里尽可能具体,那么人们可以帮助您完成这项技术,而不必仅仅将您链接到研究论文。

如果您试图找到下一帧中某个图像的特定部分的位置,则应该查找“模板匹配”。

如果你试图将一个完整的图像与下一个图像对齐并且你知道这是通过图像的简单转换给出的,那么你应该查找图像对齐,图像配准以及术语“粗到细”等内容。 ”

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

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