0

给定一组点,我如何确定左上、右上、右下和左下(TL、TR、BR、BL)

这些是位于下图中的黑色方块的坐标。(页面两边各 4 个)

以下是坐标 (x,y)(原点 0,0 在左上角):

[(147.68485399616046, 3304.5385975548143),
(168.3419544680192, 2336.686128749161),
(188.1491476566771, 1331.864619054719),
(211.6472437750393, 155.6040367158578),
(2216.6064720878203, 3330.396441392227),
(2233.7510405426237, 2363.6828015004367),
(2250.9856437171966, 1360.935679736544),
(2273.392518618822, 187.8742947415933)]

通过沿 x 轴对这些进行排序,我可以取顶部 4 和底部 4 的 4,这为页面的每一侧提供了两列。

然后我对坐标对求和,即 147+3304 = 3451 等等。通过对这个求和值上的坐标进行排序,我可以将最小值作为 TL 的坐标,将最高的坐标作为 BR(因为这将具有最大的坐标) x+y 组合)

http://i.stack.imgur.com/GxXJd.jpg

这工作正常,除了我遇到这组坐标:

     [(203.68919057903938, 154.66471253728272),
     (2264.8873935264055, 180.78268029528675),
     (987.6169366297244, 1156.4133276499006),
     (184.2811080835604, 1331.004238570996),
     (167.45816773667582, 2336.89386528075),
     (2236.836364657011, 2356.0815089255643),
     (150.94371083838226, 3304.3057324840765),
     (2223.8576991353148, 3323.427188913703)]

如上所述处理时,我得到一个错误的 TR 位置 987, 1156 而不是 2264, 180

    http://i.stack.imgur.com/aVp4f.jpg

那么我如何以编程方式确定我的 4 个角坐标?

注意我已经编辑了这些图像,但它们仍然给出相同的输出。

http://i.stack.imgur.com/cyMG5.jpg
http://i.stack.imgur.com/aVp4f.jpg
http://i.stack.imgur.com/h8ylN.jpg
http://i.stack.imgur.com/rF7Sw.jpg
http://i.stack.imgur.com/GxXJd.jpg
http://i.stack.imgur.com/837nR.jpg
4

1 回答 1

0

这是一种效率低下,但我认为直截了当的方法。

TL、TR、BL、BR的基本特征是它们离每个角最近。如果你取任何一组 xy 点,那么你需要做的就是找到到每个角落的最短距离。

下面的代码正是通过蛮力实现的(将所有点与所有角进行比较)。它可以复制粘贴到解释器。由于我不知道您给定图像的极值,因此我必须根据可用点来获取它们。您可以通过提供图像本身的角来跳过它。


ok = [(147.68485399616046, 3304.5385975548143),
      (168.3419544680192, 2336.686128749161),
      (188.1491476566771, 1331.864619054719),
      (211.6472437750393, 155.6040367158578),
      (2216.6064720878203, 3330.396441392227),
      (2233.7510405426237, 2363.6828015004367),
      (2250.9856437171966, 1360.935679736544),
      (2273.392518618822, 187.8742947415933)]
bad = [(203.68919057903938, 154.66471253728272),
       (2264.8873935264055, 180.78268029528675),
       (987.6169366297244, 1156.4133276499006),
       (184.2811080835604, 1331.004238570996),
       (167.45816773667582, 2336.89386528075),
       (2236.836364657011, 2356.0815089255643),
       (150.94371083838226, 3304.3057324840765),
       (2223.8576991353148, 3323.427188913703)]


def distance(xy1, xy2):
    (x1, y1), (x2, y2) = xy1, xy2
    return ((float(y2-y1))**2 + (float(x2-x1))**2)**0.5


def fake_image_corners(xy_sequence):
    """Get an approximation of image corners based on available data."""
    all_x, all_y = zip(*xy_sequence)
    min_x, max_x, min_y, max_y = min(all_x), max(all_x), min(all_y), max(all_y)
    d = dict()
    d['tl'] = min_x, min_y
    d['tr'] = max_x, min_y
    d['bl'] = min_x, max_y
    d['br'] = max_x, max_y
    return d


def corners(xy_sequence, image_corners):
    """Return a dict with the best point for each corner."""
    d = dict()
    d['tl'] = min(xy_sequence, key=lambda xy: distance(xy, image_corners['tl']))
    d['tr'] = min(xy_sequence, key=lambda xy: distance(xy, image_corners['tr']))
    d['bl'] = min(xy_sequence, key=lambda xy: distance(xy, image_corners['bl']))
    d['br'] = min(xy_sequence, key=lambda xy: distance(xy, image_corners['br']))
    return d


def main():
    for xy_sequence in (ok, bad):
        image_corners = fake_image_corners(xy_sequence)
        d = corners(xy_sequence, image_corners)
        print '********'
        for k, v in d.items():
            print k, v

main()

输出:

********
bl (147.68485399616046, 3304.5385975548143)
tl (211.6472437750393, 155.6040367158578)
tr (2273.392518618822, 187.8742947415933)
br (2216.6064720878203, 3330.396441392227)
********
bl (150.94371083838226, 3304.3057324840765)
tl (203.68919057903938, 154.66471253728272)
tr (2264.8873935264055, 180.78268029528675)
br (2223.8576991353148, 3323.427188913703)
于 2013-12-03T14:39:13.710 回答