1

我正面临算法问题。事情是这样的:我有一个球的图像,它是通过分析一个数组来完成的。这几乎是这样的:

      ....####......
      .##########....
   ...############.....
      .##########....
      ....####......

我如何用算法找到球的中心(近似地)?并显示如下内容:

      ....####......
      .##########....
   ...#####0######.....
      .##########....
      ....####......

我正在考虑使用 # 的较长线的宽度和高度之类的东西。

对于高度:

k = 0
for i in range (0, 10) :
for j in range (0, 20) :
# if one line contain a # then k = k+1 
center = (k/2)

但我不知道从那里..

4

2 回答 2

2

计算球的质心应该可以解决问题。基本上,它是属于球的所有像素的坐标的平均值。这巧妙地分解,因此您可以分别计算 x 和 y 的平均值。这些方面的东西:

sum_x = 0
sum_y = 0
count = 0
for x in range(0, 10):
  for y in range(0, 20):
    if image[x][y] == '#':
      sum_x += x
      sum_y += y
      count += 1
centre_x = sum_x / count # this will truncate; round or use float if you want
centre_y = sum_y / count

(我在这里使用xandy是因为它们的含义比iand更清晰j。根据口味调整。)

于 2012-03-25T19:44:07.327 回答
1

如果你的图片很大,红色区域比较小,使用floodfill算法会有更好的效果。一旦你找到一个红色像素,你就开始填充,它的时间成本将与区域的大小成正比。

from collections import deque
def floodfill(x0, y0,  is_red):
    # here is_red is a function to judge if is_red(x, y)
    que = deque()
    inque = set()
    que.append((x0, y0))
    D = ((-1, 0), (1, 0), (0, -1), (0, 1))
    sumx, sumy = 0, 0
    cnt = 0
    while que:
        x, y = que.popleft()
        sumx += x
        sumy += y
        cnt += 1
        for dx, dy in D:
            x1 = x + dx
            y1 = y + dy
            if is_red(x1, y1) and (x1, y1) not in inque:
                que.append((x1, y1))
                inque.add((x1, y1))
    return sumx/cnt, sumy/cnt

def find_center(img):
    size = img.size()
    def is_red(x, y):
        # you may change the judge condition by your self
        return img[x, y] == '#'
    for x in xrange(size[0]):
        for y in xrange(size[1]):
            if is_red(x, y):
                return floodfill(x, y, is_red)
于 2012-03-25T20:33:55.390 回答