Adloun

Écrire flou(img) , qui remplace chaque pixel intérieur par la moyenne…

Exercice supplémentaire · niveau 3 (difficile) · NSI (première), chapitre 4 — Les types construits · Les matrices au travail : images et automates

Énoncé

Écrire flou(img), qui remplace chaque pixel intérieur par la moyenne des neuf pixels de son voisinage , en recopiant les bords. Pourquoi faut-il absolument construire une nouvelle matrice ?

Corrigé


def flou(img):
    """Moyenne 3x3 sur les pixels interieurs ; les bords sont recopies.

    Precondition : img a au moins 3 lignes et 3 colonnes.
    """
    assert len(img) >= 3 and len(img[0]) >= 3
    L, C = len(img), len(img[0])
    r = [list(ligne) for ligne in img]      # copie PROFONDE : les bords
    for i in range(1, L - 1):
        for j in range(1, C - 1):
            s = 0
            for di in (-1, 0, 1):
                for dj in (-1, 0, 1):
                    s = s + img[i + di][j + dj]     # on LIT dans img
            r[i][j] = s // 9                        # on ECRIT dans r
    return r

Pourquoi une nouvelle matrice est indispensable. La nouvelle valeur du pixel dépend des anciennes valeurs de ses huit voisins. Si l'on écrivait dans img au fur et à mesure, le calcul du pixel utiliserait la valeur déjà floutée de : le flou se propagerait de gauche à droite et de haut en bas, laissant une image dissymétrique. Le résultat ne serait pas seulement inexact — il dépendrait de l'ordre de parcours, ce qu'aucune spécification ne devrait tolérer.

Et la copie doit être profonde. r = list(img) partagerait les lignes : écrire dans r[i][j] modifierait img, et l'on retomberait exactement dans le défaut qu'on voulait éviter. C'est ici que l'exercice sur les copies prend tout son sens.

Vérification.


uni = [[100] * 5 for _ in range(5)]
assert flou(uni) == uni                 # une image uniforme reste uniforme

pic = [[0] * 5 for _ in range(5)]
pic[2][2] = 90
res = flou(pic)
print(res[2][2], res[1][1], res[0][0])  # 10 10 0

Deux contrôles bien choisis. L'image uniforme doit être invariante : la moyenne de neuf fois vaut . Le pic isolé de se répand en neuf cases valant chacune — et le coin, hors du voisinage, reste à . Le total est conservé, ce qui est la signature d'une moyenne.

Hors programme : cette opération s'appelle une convolution, et changer les neuf coefficients change l'effet — flou, netteté, détection de contours. C'est le mécanisme de base du traitement d'images, et celui des réseaux de neurones convolutifs.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.