Solution de Négatif et binarisation d'une image - Sujet 14 - EP NSI 2025
Énoncé du problème
EXERCICE 1 (10 points)
Dans cet exercice les tableaux sont représentés par des listes Python (type list).
Écrire en python deux fonctions :
lancerde paramètre n, un entier positif, qui renvoie un tableau de n entiers obtenus aléatoirement entre 1 et 6 (1 et 6 inclus) ;paire_6de paramètre tab, un tableau de n entiers compris entre 1 et 6 et qui renvoie un booléen égal àTruesi le nombre de 6 est supérieur ou égal à 2,Falsesinon.
On pourra utiliser la fonction randint(a,b) du module random pour laquelle la documentation officielle est la suivante :
random.randint(a, b)
Renvoie un entier aléatoire N tel que a <= N <= b.
Exemples :
>>> lancer1 = lancer(5)
>>> lancer1
[5, 6, 6, 2, 2]
>>> paire_6(lancer1)
True
>>> lancer2 = lancer(5)
>>> lancer2
[6, 5, 1, 6, 6]
>>> paire_6(lancer2)
True
>>> lancer3 = lancer(3)
>>> lancer3
[2, 2, 6]
>>> paire_6(lancer3)
False
>>> lancer4 = lancer(0)
>>> lancer4
[]
>>> paire_6(lancer4)
False
EXERCICE 2 (10 points)
On considère une image en 256 niveaux de gris que l’on représente par une grille de nombres, c’est-à-dire une liste composée de sous-listes toutes de longueurs identiques.
La largeur de l’image est donc la longueur d’une sous-liste et la hauteur de l’image est le nombre de sous-listes.
Chaque sous-liste représente une ligne de l’image et chaque élément des sous-listes est un entier compris entre 0 et 255, représentant l’intensité lumineuse du pixel.
Le négatif d’une image est l’image constituée des pixels x_n tels que x_n + x_i = 255 où x_i est le pixel correspondant de l’image initiale.
Étant donné une valeur seuil, la binarisation d’une image est l’image constituée des pixels x_b valant 0 si x_i < seuil et 255 sinon, où x_i est le pixel correspondant de l’image initiale.
Compléter le programme ci-dessous :
def nombre_lignes(image):
'''renvoie le nombre de lignes de l'image'''
return ...
def nombre_colonnes(image):
'''renvoie la largeur de l'image'''
return ...
def negatif(image):
'''renvoie le negatif de l'image sous la forme
d'une liste de listes'''
# on cree une image de 0 aux memes dimensions
# que le parametre image
nouvelle_image = [[0 for k in range(nombre_colonnes(image))]
for i in range(nombre_lignes(image))]
for i in range(nombre_lignes(image)):
for j in range(...):
nouvelle_image[i][j] = ...
return nouvelle_image
def binaire(image, seuil):
'''renvoie une image binarisee de l'image sous la forme
d'une liste de listes contenant des 0 si la valeur
du pixel est strictement inferieure au seuil et 255 sinon'''
nouvelle_image = [[0] * nombre_colonnes(image)
for i in range(nombre_lignes(image))]
for i in range(nombre_lignes(image)):
for j in range(...):
if image[i][j] < ... :
nouvelle_image[i][j] = ...
else:
nouvelle_image[i][j] = ...
return nouvelle_image
Exemples :
>>> img=[[20, 34, 254, 145, 6], [23, 124, 237, 225, 69],
[197, 174, 207, 25, 87], [255, 0, 24, 197, 189]]
>>> nombre_lignes(img)
4
>>> nombre_colonnes(img)
5
>>> negatif(img)
[[235, 221, 1, 110, 249], [232, 131, 18, 30, 186],
[58, 81, 48, 230, 168], [0, 255, 231, 58, 66]]
>>> binaire(img,120)
[[0, 0, 255, 255, 0],[0, 255, 255, 255, 0],
[255, 255, 255, 0, 0],[255, 0, 0, 255, 255]]
Les contraintes ci-dessous sont ajoutées par la plateforme et ne font pas partie du sujet.
Exercice 1
Contraintes :
nest un entier avec0 <= n <= 10^4;lancer(0)renvoie le tableau vide[]lancer(n)renvoie une liste de longueurndont chaque élément est un entier tiré aléatoirement entre 1 et 6 inclus0 <= len(tab) <= 10^41 <= tab[i] <= 6pour tout indiceipaire_6(tab)renvoie un booléen (TrueouFalse)
Exercice 2
Contraintes :
1 <= nombre_lignes(image) <= 100et1 <= nombre_colonnes(image) <= 100imagen’est jamais vide : elle contient au moins une ligne et chaque ligne au moins un pixel- toutes les sous-listes de
imageont la même longueur 0 <= image[i][j] <= 255, entiersseuilest un entier avec0 <= seuil <= 255negatifetbinairerenvoient une nouvelle liste de listes et ne modifient pasimage
Solution
Solution
Exercice 1 - lancers de dé et paire de 6
L’idée. Il y a deux fonctions indépendantes. Pour lancer(n), on part d’une liste vide et on ajoute n fois un nombre tiré au hasard entre 1 et 6 : c’est exactement ce que fait randint(1, 6). Si n vaut 0, la boucle ne tourne pas et on renvoie la liste vide, ce qui est bien le résultat attendu. Pour paire_6(tab), on n’a pas besoin de savoir où sont les 6 : on les compte, et on répond True dès qu’il y en a au moins deux.
Un petit exemple. Pour tab = [2, 2, 6], le compteur vaut 1 à la fin : un seul 6, donc paire_6 renvoie False. Pour [6, 5, 1, 6, 6], le compteur vaut 3, donc True.
Attention : le module random n’est pas importé dans le fichier de départ, c’est à vous d’écrire la ligne d’import.
from random import randint
def lancer(n):
resultat = []
for i in range(n):
resultat.append(randint(1, 6))
return resultat
def paire_6(tab):
nombre_de_6 = 0
for valeur in tab:
if valeur == 6:
nombre_de_6 = nombre_de_6 + 1
# deux 6 suffisent : la question est "au moins deux", pas "exactement deux"
return nombre_de_6 >= 2
Explications. Dans lancer, resultat est la liste que l’on construit petit à petit ; la variable de boucle i ne sert qu’à compter les tours, on ne s’en sert pas dans le corps. Dans paire_6, nombre_de_6 retient combien de 6 ont été vus depuis le début du parcours. La comparaison nombre_de_6 >= 2 est déjà un booléen : on peut la renvoyer directement, sans écrire if ... : return True else: return False. Le >= et non == est important : trois 6 forment bien une paire de 6.
Exercice 2 - négatif et binarisation d’une image
L’idée. Une image est une liste de lignes, et chaque ligne est une liste de pixels. Le nombre de lignes est donc simplement len(image), et le nombre de colonnes est la longueur d’une ligne quelconque, par exemple la première : len(image[0]). Les deux transformations demandées traitent chaque pixel séparément, sans regarder ses voisins : on parcourt la grille avec deux boucles imbriquées, i pour la ligne et j pour la colonne, et on écrit dans nouvelle_image la valeur transformée du pixel image[i][j]. Pour le négatif, cette valeur est 255 - image[i][j] (puisque l’énoncé demande x_n + x_i = 255). Pour la binarisation, c’est 0 si le pixel est strictement plus petit que seuil, et 255 sinon.
Un petit exemple. Le pixel 20 devient 255 - 20 = 235 dans le négatif, et devient 0 dans la binarisation au seuil 120 car 20 < 120. Le pixel 145 devient 110 dans le négatif et 255 dans la binarisation.
def nombre_lignes(image):
'''renvoie le nombre de lignes de l'image'''
return len(image)
def nombre_colonnes(image):
'''renvoie la largeur de l'image'''
return len(image[0])
def negatif(image):
'''renvoie le negatif de l'image sous la forme
d'une liste de listes'''
# on cree une image de 0 aux memes dimensions
# que le parametre image
nouvelle_image = [[0 for k in range(nombre_colonnes(image))]
for i in range(nombre_lignes(image))]
for i in range(nombre_lignes(image)):
for j in range(nombre_colonnes(image)):
nouvelle_image[i][j] = 255 - image[i][j]
return nouvelle_image
def binaire(image, seuil):
'''renvoie une image binarisee de l'image sous la forme
d'une liste de listes contenant des 0 si la valeur
du pixel est strictement inferieure au seuil et 255 sinon'''
nouvelle_image = [[0] * nombre_colonnes(image)
for i in range(nombre_lignes(image))]
for i in range(nombre_lignes(image)):
for j in range(nombre_colonnes(image)):
# strictement inferieur au seuil : un pixel egal au seuil devient 255
if image[i][j] < seuil:
nouvelle_image[i][j] = 0
else:
nouvelle_image[i][j] = 255
return nouvelle_image
Explications. Les trois trous des boucles se remplissent de la même façon dans les deux fonctions : range(nombre_colonnes(image)) fait varier j sur toutes les colonnes de la ligne i. La ligne nouvelle_image était déjà écrite dans le sujet : elle fabrique une grille de 0 de la bonne taille, ce qui permet ensuite d’écrire dans nouvelle_image[i][j] sans erreur d’indice. C’est aussi ce qui garantit que l’image de départ n’est jamais modifiée : on ne touche qu’à la nouvelle grille.
Le test image[i][j] < seuil reprend mot pour mot l’énoncé : strictement inférieur. Un pixel qui vaut exactement seuil part donc dans le else et vaut 255. Enfin, nombre_colonnes suppose que toutes les lignes ont la même longueur, ce que l’énoncé garantit, et que l’image a au moins une ligne, sans quoi image[0] n’existerait pas.