1

I followed the code in this link to find the object center for my graylevel image,

def find_center(im):
    immat = im
    (X, Y) = [im.shape[0],im.shape[1]]
    m = np.zeros((X, Y))

    for x in range(X):
        for y in range(Y):
            m[x, y] = immat[(x, y)] != 0
    m = m / np.sum(np.sum(m))


    # marginal distributions
    dx = np.sum(m, 1)
    dy = np.sum(m, 0)

    # expected values
    cx = np.sum(dx * np.arange(X))
    cy = np.sum(dy * np.arange(Y))
    return [cx,cy]

xy1=find_center(img)  #img is a binary image, object has value==1 and back ground value of 0
print xy1
plt.imshow(img)
plt.annotate('center', xy1, xycoords='data',
             xytext=(0.5, 0.5), textcoords='figure fraction',
             arrowprops=dict(arrowstyle="->"))
plt.show()

However, I am not getting the right answer (the center is not inside the object), the following image shows the output:

enter image description here

What am I doing wrong?

Community
  • 1
  • 1
S.EB
  • 1,966
  • 4
  • 29
  • 54
  • It looks like if the image was rotated by 180 degrees then the centre would be correct. – 101 Feb 21 '18 at 22:06
  • On that note, `im.shape[0]` returns image height, not width, so you perhaps are meaning to assign it to `Y` instead of `X`. – 101 Feb 21 '18 at 22:21
  • @101 it does not make any changes. – S.EB Feb 22 '18 at 13:53

1 Answers1

3

I think the function find_center is computing the center coordinates correctly. There is a much more elegant and efficient way to perform this calculation though (see the snippet below).

The problem is that you are passing xy1, i.e. [cx, cy] to plt.annotate, but you need to pass [cy, cx]. If you change your code to xy1 = find_center(img)[::-1] the issue should be fixed.

Give this code a try:

import numpy as np
from skimage import io
import matplotlib.pyplot as plt
from matplotlib.patches import Circle

triskele = io.imread('https://i.stack.imgur.com/fczjh.png')
img = triskele > 0

[cx, cy] = np.transpose(np.nonzero(img)).mean(axis=0)

fig, ax = plt.subplots(1)
ax.imshow(img, cmap=plt.cm.gray)
ax.axis('off')
ax.add_patch(Circle((cy, cx), radius=12, color='red'))
plt.show(fig)

Center position

Tonechas
  • 13,398
  • 16
  • 46
  • 80
  • Thank you very much for your help, this is working very well and it is very efficient :) – S.EB Feb 25 '18 at 21:24