Détecter le contour d'une forme circulaire

a marqué ce sujet comme résolu.

Bonjour,

Avec un ami, nous développons un petit logiciel en Python qui permet de nous donner le rayon estimé de la Lune (ou tout autre corps céleste de forme circulaire) à partir de points placés par l’utilisateur. Une fois les points placés, nous utilisons la méthode des moindres carrés pour avoir le cercle. Ce qui nous donne quelque chose comme ça :

Les points placés sont en vert
Les points placés sont en vert

On souhaiterai avoir maintenant un algorithme permettant au programme de placer lui même les points. On a regardé avec OpenCV et Hough Circle Transform mais le problème d’OpenCV c’est qu’il est assez compliqué à installer pour partager ce logiciel (il est sensé être utilisé par des astronomes débutants).

Quel est le meilleur moyen de placer les points (5–6 points) définissant le contour de mon objet ? Il faut vraiment placer les points et pas trouver tout de suite le rayon (ce que fait OpenCV).

Merci pour vos réponses !

+0 -0

Vu l’efficacité des transformées de Hough …

Va falloir le recoder à la main. Ça va prendre beaucoup de temps et il faudra lire beaucoup de document pour bien comprendre la chose :(

Bon courage !

+0 -0

En considérant que tes images sont toujours à peu près propres, je la passerais d’abord en niveaux de gris, puis j’utiliserais un filtre médian (tu remplaces chaque pixel par la couleur médiane dans son voisinage de MxN pixels voisins) pour virer le gros du bruit, puis je binariserais l’image (tu choisis un seuil T, tous les pixels plus foncés valent 0, et les autres valent 1) pour segmenter la lune du fond.

À partir de là, il devient relativement facile de trouver des points se situant à la frontière (sur le contour) pour ensuite appliquer ta méthode des moindres carrés ou autre.

+1 -0
Banni

Pourquoi faut-il d’abord placer les points sans trouver le rayon ?

J’ai un peu lu la description de la transformée de Hough, c’est toujours marrant ces techniques de traitement d’image. Ça m’a rendu curieux sur ce que ça donnait, voilà le résultat.

Détection de centre de lune
Détection de centre de lune
Une tête
Une tête
from PIL import Image
import sys
from math import sqrt

img_in = Image.open(sys.argv[1])
img_out = Image.new("RGBA", img_in.size) # img_in.copy()

X, Y = img_in.size
pin = img_in.load()
sq_size = 51
step_size = 31

votes = [[0 for y in range(Y)] for x in range(X)]

for x in range(0,X-sq_size,sq_size):
  for y in range(0,Y-sq_size,sq_size):
    v = [0,0]
    for a in range(sq_size):
      for b in range(sq_size):
        gray = sum(pin[x+a,y+b])
        v[0] += (a-sq_size//2)*gray
        v[1] += (b-sq_size//2)*gray
    n = sqrt(v[0]**2 + v[1]**2)
    if n==0:
      continue
    v[0] = v[0]/n
    v[1] = v[1]/n
    p,q = x+v[0]*step_size,y+v[1]*step_size
    while p<X and q<Y and p>0 and q>0:
      votes[int(p)][int(q)] += n
      p += v[0]*step_size
      q += v[1]*step_size
    p,q = x,y
    while p<X and q<Y and p>0 and q>0:
      votes[int(p)][int(q)] += n
      p -= v[0]*step_size
      q -= v[1]*step_size

cumul_votes = [[0 for _ in range(Y+1)] for _ in range(X+1)]

for x in range(0,X):
  for y in range(0,Y):
    cumul_votes[x+1][y+1] = votes[x][y] + cumul_votes[x][y+1] + cumul_votes[x+1][y] - cumul_votes[x][y]

for x in range(0,X):
  for y in range(0,Y):
    MX = min(x+step_size, X)
    MY = min(y+step_size, Y)
    mX = max(x-step_size, 0)
    mY = max(y-step_size, 0)
    votes[x][y] = cumul_votes[MX][MY] - cumul_votes[mX][MY] - cumul_votes[MX][mY] + cumul_votes[mX][mY]

maxvote = -1
maxvoteX, maxvoteY = -1,-1

for a in range(X):
  for b in range(Y):
    if votes[a][b] > maxvote:
      maxvote = votes[a][b]
      maxvoteX, maxvoteY = a,b

pout = img_out.load()
for a in range(X):
  for b in range(Y):
    if (a-maxvoteX)**2 + (b-maxvoteY)**2 < 100:
      pout[a,b] = (255,0,0)
    else:
      g = int( (255*votes[a][b]) / maxvote )
      pout[a,b] = (g,g,g)

img_out.save(sys.argv[2])

Edit : C’est pas vraiment la transformée de Hough, c’est juste ce que j’ai compris en gros. C’est inspiré d’elle on va dire.

+0 -0

Merci pour vos réponses !

Pour le moment les images que l’on m’a transmis sont propres oui. La Lune est clairement bien définie par rapport au fond. Je ne sais pas si ce sera toujours le cas (je ne pense pas).

J’ai regardé la transformée de Hough d’un peu plus près. En effet, ça n’a pas l’air accessible mais ça vaut le coup d’essayer je pense. :)

Pourquoi faut-il d’abord placer les points sans trouver le rayon ?

Car c’est une condition du cahier des charges. On peut faire une méthode qui place les points automatiquement, à une condition : que ça ne place que les points. Comme ça, l’utilisateur peut toujours intervenir dessus.

Merci @nohar, je vais d’abord essayer comme ça et si les résultats sont moyens, je me pencherais alors sur la transformée de Hough !

Il faudra faire attention à ce que ton algo n’essaye pas de mettre des points à la frontière de la zone sombre de la Lune. Du coup il faut exclure d’office la moitié du limbe de la Lune. Après tu peux repérer tous les pixels qui sont de part et d’autre de la transition noir/blanc (après avoir binairisé ton image comme le préconise @nohar).

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte