在C#中查找两个图像的交集

时间:2016-07-22 17:16:20

标签: c# image intersection

我有两个图像(A和B),想知道图像的矩形交叉点。图像表示滚动的屏幕内容,我只想要没有交叉点的图像的独占值。所以A代表一个捕获,然后B代表相同的屏幕区域,但滚动了一些%的内容,底部有额外的内容。但因为滚动并不总是代表整个内容卷(例如,最后)

所以基本上如果B只是内容的部分滚动视图,我想减少B,因此它不包含A中存在的任何图像数据;因此,当我合并A和B(以及A之前的任何其他卷轴)时,它们不包含重复数据。

这是我将A和B拼接在一起的示例图像;如你所见,内容是重复的。

enter image description here

1 个答案:

答案 0 :(得分:1)

这里有一些含糊之处,因为可能有多个交叉点。我的意思是可能有一个像素高的交叉点以及一个100像素的高交叉点。解决这种模糊性的一种方法是在两个图像之间采用最大的交叉点。这是一种蛮力方法。我假设这两个屏幕截图具有相同的维度w x h

Compare  each of `h` rows of A to B.
Perform the same comparison on `h-1` rows with A's y coordinates offset by +1 (down 1).
Perform the same comparison on `h-2` rows with A's y coordinates offset by +2 (down 2).
...

每当比较成功时,返回该偏移量。这是A的Y坐标,应该缝在B的顶部。

这里的主要问题是表现。最糟糕的情况是非常糟糕(宽度*高度*高度),但如果每个像素的比较相同,直到最后一个像素为每行。只要一个像素不匹配就通过早期返回,性能可能实际上足够好。

与memcp

比较

这是一种从给定的Y偏移开始比较图像的简单快捷的方法。

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
static extern int memcmp(IntPtr b1, IntPtr b2, long count);
static bool compareIntersection(int width, int height, int yOffset, IntPtr a, IntPtr b)
{
    int bytesPerPixel = 4; // this needs to be set to reflect your image format
    int bytesToRead = (height - yOffset) * width * bytesPerPixel;
    IntPtr aStart = a + yOffset * width * bytesPerPixel;
    return 0 == memcmp(aStart, b, bytesToRead);
}

函数的参数是图像的宽度,图像的高度,A中的y偏移以及指向每个位图内存开头的指针。您可以使用Bitmap.LockBits然后使用BitmapData.Scan0来获取这些指针。

代码未经测试,因此可能会出现问题。