Solution officielle
import numpy as np
def pipeline_comptage(image_bgr, seuil, taille_flou, taille_erosion):
# 1. Convertir en niveaux de gris
b = image_bgr[:, :, 0].astype(np.float64)
g = image_bgr[:, :, 1].astype(np.float64)
r = image_bgr[:, :, 2].astype(np.float64)
image_gris = (0.299 * r + 0.587 * g + 0.114 * b).astype(np.uint8)
# 2. Flou moyenneur
h, w = image_gris.shape
pad_f = taille_flou // 2
image_floutee = np.zeros_like(image_gris)
for i in range(pad_f, h - pad_f):
for j in range(pad_f, w - pad_f):
region = image_gris[i-pad_f:i+pad_f+1, j-pad_f:j+pad_f+1]
image_floutee[i, j] = int(np.mean(region))
# 3. Seuillage
image_seuillee = ((image_floutee > seuil) * 255).astype(np.uint8)
# 4. Erosion
pad_e = taille_erosion // 2
image_erodee = np.zeros_like(image_seuillee)
for i in range(pad_e, h - pad_e):
for j in range(pad_e, w - pad_e):
region = image_seuillee[i-pad_e:i+pad_e+1, j-pad_e:j+pad_e+1]
if np.all(region == 255):
image_erodee[i, j] = 255
# 5. Compter les composantes connexes
visite = np.zeros_like(image_erodee, dtype=bool)
nb_objets = 0
for i in range(h):
for j in range(w):
if image_erodee[i, j] == 255 and not visite[i, j]:
nb_objets += 1
pile = [(i, j)]
while pile:
ci, cj = pile.pop()
if 0 <= ci < h and 0 <= cj < w and not visite[ci, cj] and image_erodee[ci, cj] == 255:
visite[ci, cj] = True
pile.extend([(ci-1, cj), (ci+1, cj), (ci, cj-1), (ci, cj+1)])
return {
'image_gris': image_gris,
'image_floutee': image_floutee,
'image_seuillee': image_seuillee,
'image_erodee': image_erodee,
'nb_objets': nb_objets,
}