function [germes, img_labelise, E] = super_pixel(img, K, m, n, seuil_E, q_max) img = im2double(img); width = size(img, 1); height = size(img, 2); N = width * height; % création des germes S = sqrt(N / K); X = S / 2:S:width; Y = S / 2:S:height; germes = zeros(length(X) * length(Y), 5); c = 1; for x = X for y = Y germes(c, :) = [x y 0 0 0]; c = c + 1; end end % affichage des germes scatter(germes(:, 2), germes(:, 1), 'g.'); drawnow nocallbacks c = 1; % intialisation des germes (petit déplacement, pour ne pas se trouver sur un contour) for germe = germes' x = germe(1); y = germe(2); xmin = floor(max(x - n, 1)); interval_x = xmin:min(x + n, width); ymin = floor(max(y - n, 1)); interval_y = ymin:min(y + n, height); Gmag = imgradient(img(interval_x, interval_y)); [~, ind_min] = min(Gmag(:)); [nr, nc] = ind2sub(size(Gmag), ind_min); x = xmin + nr - 1; y = ymin + nc - 1; germes(c, :) = [x y img(x, y, 1) img(x, y, 2) img(x, y, 3)]; c = c + 1; end % affichage des germes scatter(germes(:, 2), germes(:, 1), 'r.'); drawnow nocallbacks % création de l'image labelisée par les germes img_labelise = zeros(width, height); % mélange mélange mélange germes = germes(randperm(length(germes)), :); % boucle princiaple for q = 1:q_max for x = 1:width for y = 1:height % initialisation des minimums min_Ds = 1e5; for index_germe = 1:length(germes) germe = germes(index_germe, :); % on récupère les coordonnées du germe xg = germe(1); yg = germe(2); % on calcule la distance spatiale entre le germe et le pixel Dxy = norm([x - xg y - yg]); % si le germe est trop loin on skip if Dxy > S continue; end % on récupère les couleurs du germe rg = germe(3); gg = germe(4); bg = germe(5); % on récupère les couleurs du pixel r = img(x, y, 1); g = img(x, y, 2); b = img(x, y, 3); % on calcule la distance chromatique entre le germe et le pixel Dlab = norm([r - rg g - gg b - bg]); % on calcule Ds Ds = Dlab + m / S * Dxy; % Si Ds est meilleur on le prend if Ds < min_Ds img_labelise(x, y) = index_germe; min_Ds = Ds; end end end end % affichage des labels image(img_labelise * 255 / length(germes)); colormap hsv; drawnow nocallbacks title("itération " + num2str(q) + "/" + num2str(q_max)); old_germes = germes; % kmeans, déplacement des germes par rapport à leurs pixels associés for index_germe = 1:length(germes) truc = img_labelise == index_germe; truc_rgb = reshape(img(repmat(truc, [1 1 3])), [], 3); m_rgb = mean(truc_rgb); mx = 0; my = 0; for i = find(truc == 1)' [x, y] = ind2sub(size(img), i); mx = mx + x; my = my + y; end mx = mx / sum(truc, 'all'); my = my / sum(truc, 'all'); germes(index_germe, :) = [mx my m_rgb]; end % affichage des germes scatter(germes(:, 2), germes(:, 1), 'w.'); drawnow nocallbacks % calcul de l'erreur résiduel E = norm(old_germes(:, 1:2) - germes(:, 1:2)); % si notre erreur est inférieur au seuil, on stop l'algo if E < seuil_E break end end end