我正在寻找一种算法来有效地确定一个2D图像到另一个2D图像的最佳平移(仅限于x和y轴,不旋转)。目标是找到最大公共像素,其中像素被认为是黑色在白色背景上,反之亦然。前景与背景的比例明显偏向背景。
范例:
x1c 0d1x的数据
的
这里,最好的翻译是[-171,97]。
我已经实现了一个算法,它比较所有像素,并通过递增x和y来迭代平移。然而,这种方法很耗时。为了解决这个问题,我试图通过只关注第二张图像中白色像素到其他白色像素的平移来加快这个过程。虽然它可以工作,但仍然很慢。
下面是我当前算法的代码片段(arrayImage只包含0和1,它是一个二进制图像)。
public static int[] findBestTranslation(int[][] arrayImage1, int[][] arrayImage2) {
int[] bestTranslation = new int[2];
int bestSimilarity = Integer.MIN_VALUE;
int img2Length = arrayImage2.length;
int img2Width = arrayImage2[0].length;
List<int[]> whitePixelsImage1 = findWhitePixels(arrayImage1);
List<int[]> whitePixelsImage2 = findWhitePixels(arrayImage2);
boolean[][] checkedOffsets = new boolean[img2Length * 2][img2Width * 2];
int i = 0;
for (int[] pixel1 : whitePixelsImage1) {
System.out.println(i++ + ": " + bestSimilarity);
for (int[] pixel2 : whitePixelsImage2) {
//calculate translation
int xOffset = pixel2[0] - pixel1[0];
int yOffset = pixel2[1] - pixel1[1];
// Check if this offset has been selected before
if (checkedOffsets[xOffset + img2Length][yOffset + img2Width]) {
continue;
} else {
checkedOffsets[xOffset + img2Length][yOffset + img2Width] = true;
}
int similarity = 0;
for (int[] pixelNotTranslated : whitePixelsImage1) {
int xTranslated = pixelNotTranslated[0] + xOffset;
int yTranslated = pixelNotTranslated[1] + yOffset;
if (xTranslated >= 0 && xTranslated < img2Length && yTranslated >= 0 && yTranslated < img2Width) {
similarity += arrayImage2[xTranslated][yTranslated];
}
}
if (similarity > bestSimilarity) {
bestSimilarity = similarity;
bestTranslation[0] = xOffset;
bestTranslation[1] = yOffset;
}
}
}
return bestTranslation;
}
字符串
1条答案
按热度按时间qeeaahzv1#
我不会说Java,但我认为你想要一个 “相位相关性”,你可以在Python中使用scikit-image如下所示:
字符串
输出
对于您的两个图像,它在大约1秒内输出以下内容:
型
我猜您可以使用某种类型的
exec()
或system()
函数“shell out”到Python中,或者找到相位相关技术的Java实现。还有一个OpenCV实现,它可能有Java bindings。它明显比上面的方法快,并且在1秒内得到结果:
型
输出
型
这是我得到的,如果我用绿色绘制一幅图像,然后用红色绘制第二幅图像,移动计算的量。
x1c 0d1x的数据
我使用了一个 “hardmix” 混合模式,所以黄色部分是红色和绿色重合的地方。作为我自己的参考,这是我使用ImageMagick的混合命令:
型