Codage d'ellipses sur une matrice

Bonjour à tous,

Tout d’abord merci de vous être arrêtés sur mon topic, je cherche à programmer des ellipses sur une matrice carrée de taille 500 et de les représenter en couleur.

J’ai déjà bien avancé, mon code fonctionne mais le but est d’exécuter la fonction sur une ellipse de base et de voir l’ellipse “s’étendre” au fur et à mesure. Mon but final est de pouvoir changer la direction de “propagation des ellipses”. Mais pour l’instant je veux juste optimiser le code ci-dessous. Comme vous pourrez le constater le temps d’exécution est long car je fais beaucoup de calculs dans la fonction notamment parce que je balaye souvent la matrice par ligne et colonne…

Pour expliquer mon code en plus des commentaires, je défini d’abord la matrice M carrée, dont chaque case est blanche par défaut. Ensuite je trace une ellipse au centre de cette matrice que je colorie en rouge (pour qu’on puisse la voir) et je lui applique la fonction principale enveloppe_ellipses qui renvoie la nouvelle ellipse “étendue”.

Que fait ma fonction pour étendre cette ellipse ? Et bien tout d’abord elle trace une multitude de petites ellipses noires de centres les points de l’ellipse principale, tellement qu’on peut distinguer une nouvelle ellipse. Pour faire reconnaitre cette nouvelle ellipse, j’effectue un balayage par ligne et par colonne de la matrice et chaque case noire située sur le bord de la nouvelle ellipse est coloriée en rouge. Reste à colorier les autres cases en blanc et la nouvelle ellipse apparait.

Cette manière de procéder n’est pas la plus simple mais elle est nécessaire à mon projet, j’ai donc besoin d’aide pour simplifier mon code et le rendre plus rapide mais sur le principe, je ne peux pas changer d’approche.

import numpy as np
from matplotlib import pyplot as plt
from math import pi, floor

'''Ellipse tracée sur la matrice M'''
M = np.zeros((500,500,3)) + 255 # matrice blanche carrée de taille 500
lm = len(M)

x = np.linspace(0, 2*pi, 500)
y = np.array([20*np.cos(x) , 40*np.sin(x)])
ellipse0 = []
for i in range(500): # boucle qui modifie la liste y
    y[0][i] = lm/2 + floor(y[0][i]) # les valeurs de la première colonne de y sont changées en leur partie entière
    y[1][i] = lm/2 + floor(y[1][i]) # les valeurs de la deuxième colonne...
    ellipse0.append([y[0][i],y[1][i]])
    M[int(y[0][i])][int(y[1][i])] = (255,0,0) #on change les cases de M d'indices... en rouge
plt.imshow(M, extent=(0,500,0,500)) # graduation des axes (de 0 à 200)

'''Fonctions minmax'''
def minmaxlignei(i):
    L=[]
    for j in range(lm):
        a,b,c = M[i][j] 
        if a == 0 and b == 0 and c == 0:
            L.append(j)
            #liste des couples [a,b] coordonnées des points noirs avec a la ligne et b la colonne
    if len(L) == 0 :
        L.append(0)
    return [min(L),max(L)]
def minmaxcolonnei(i):
    L=[]
    for j in range(lm):
        a,b,c = M[j][i] 
        if a == 0 and b == 0 and c == 0:
            L.append(j) #liste des couples [a,b] coordonnées des points noirs avec a la colonne et b la ligne'''
    if len(L) == 0 : 
        L.append(0)
    return [min(L),max(L)]


def enveloppe_ellipses(ellipse):
    '''ellipses autour de l'ellipse principale'''
    n = len(ellipse)
    x1 = np.linspace(0, 2*pi, 500)
    y1 = np.array([5*np.cos(x1) , 10*np.sin(x1)])
    for i in range(len(x1)):
        for j in range(n):
            M[int(ellipse[j][0]+y1[0][i])][int(ellipse[j][1]+y1[1][i])] = (0,0,0) # on change les cases de M en noir et on décale

    '''identification de l'enveloppe d'ellipse par balayage selon les lignes puis les colonnes'''
    L1=[]
    for i in range(lm):
        if minmaxcolonnei(i) != [0,0]:
            L1.append([i]+minmaxcolonnei(i))
    n = len(L1)
    for i in range(n):
        M[L1[i][1]][L1[i][0]] = (255,0,0)
        M[L1[i][2]][L1[i][0]] = (255,0,0)
    L1 = []
    for i in range(lm):
        if minmaxlignei(i) != [0,0]:
            L1.append([i]+minmaxlignei(i))
    n = len(L1)
    for i in range(n):
        M[L1[i][0]][L1[i][1]] = (255,0,0)
        M[L1[i][0]][L1[i][2]] = (255,0,0)
    
    '''tracé de la nouvelle ellipse'''
    ellipse = []
    for j in range(lm):
        for i in range(lm):
            a,b,c = M[i][j]
            if int(a)==255 and int(b)==0 and int(c)==0:
                ellipse.append([i,j]) # coordonnées des points de la nouvelle ellipse
            else:
                M[i][j] = (255,255,255)
    return ellipse
ellipse1=enveloppe_ellipses(enveloppe_ellipses(ellipse0))
enveloppe_ellipses(ellipse1)
plt.imshow(M, extent=(0,500,0,500))

Merci pour votre aide et votre temps !