RETOUCHE D'IMAGES (FLOUS, SEUIL, HISTOGRAMMES, OPÉRATIONS ARITHMÉTIQUES)

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 1 juin 2005 à 15:27
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 - 22 avril 2011 à 13:45
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/31753-retouche-d-images-flous-seuil-histogrammes-operations-arithmetiques

cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
22 avril 2011 à 13:45
Bonjour,

Voiçi une variante plus rapide utilisant les Scanlines et un tri-par-comptage-d'occurences appliqués au filtre Médian de Cedricbi :

type
TRGBArray = ARRAY[0..0] OF TRGBTriple; // élément de bitmap (API windows)
pRGBArray = ^TRGBArray; // type pointeur vers tableau 3 octets 24 bits

var ScanLinesS : array[Word] of pRGBArray; // BmpSource
ScanLinesD : array[Word] of PRGBArray; // BmpDestination

// Filtre Médian anti poivre et sel -------------------------------------

function FiltreMedian2(const BmpSrc : TBitMap; TailleFiltre : Integer) : tBitMap;
type tAOB = array of byte;
var X, Y : Integer;
X2, Y2 : Integer;
Rouge,Vert,Bleu : tAOB;
NombrePixels : Integer;
NumPixel : Integer;
NumPixel2 : Integer;

procedure TriParOcc( var T : tAOB; sens2tri : boolean);
// Tri du tableau T par comptage d'occurences
// Si sens2tri=True alors tri en ordre croissant
var nbOcc : array [0..255] of integer; va,i,j,k : integer;
begin FillChar(nbOcc,SizeOf(nbOcc),0); // r.à.z du tableau des occurrences
for i := Low(T) to High(T) // recherche des nombres d'occurrences dans le tableau des valeurs :
do nbOcc[ T[i] ] := nbOcc[ T[i] ] + 1;

k := Low(T);
if sens2tri = true then // restitution en ordre croissant
begin for va:=0 to 255
do if nbOcc[va] <> 0
then for j:=1 to nbOcc[va] do begin T[k]:=va; inc(k); end;
end else // restitution en ordre décroissant
begin for va := 255 downto 0
do if nbOcc[va] <> 0
then for j:=1 to nbOcc[va] do begin T[k]:=va; inc(k); end;
end;
end;

begin Result:=tBitMap.create;
with Result do begin
width:=BmpSrc.width; height:=BmpSrc.height; PixelFormat:=pf24bit;
end;
for y := 0 to BmpSrc.height-1 do begin
ScanLinesS[y] := BmpSrc.scanline[y]; // Source
ScanLinesD[y] := Result.scanline[y]; // Destination
end;

TailleFiltre := TailleFiltre div 2;

SetLength(Rouge, (TailleFiltre * 2 + 1) * (TailleFiltre * 2 + 1));
SetLength(Vert, (TailleFiltre * 2 + 1) * (TailleFiltre * 2 + 1));
SetLength(Bleu, (TailleFiltre * 2 + 1) * (TailleFiltre * 2 + 1));

for X := 0 to BmpSrc.Width- 1 do // Parcourir tous les pixels
begin //frmFiltres.labX.caption:=intToStr(X); frmFiltres.labX.update;
for Y := 0 to BmpSrc.Height - 1 do // de l'image
begin
NombrePixels := 0;

for X2 := -TailleFiltre to TailleFiltre do
if (X + X2 >= 0) and (X + X2 < BmpSrc.Width) then // Teste si la colonne X + X2 est sur l'image
for Y2 := -TailleFiltre to TailleFiltre do
if (Y + Y2 >= 0) and (Y + Y2 < BmpSrc.Height) then // Teste si la ligne Y + Y2 est sur l'image
begin
Rouge[NombrePixels]:= ScanLinesS[Y + Y2, X + X2].rgbtRed; // Mémorisation des valeurs
Vert[NombrePixels] := ScanLinesS[Y + Y2, X + X2].rgbtGreen; // des pixels
Bleu[NombrePixels] := ScanLinesS[Y + Y2, X + X2].rgbtBlue; // dans les tableaux

Inc(NombrePixels); // Augmente de 1 le nombre de pixels additionnés
end;

TriParOcc(Rouge, true); // Trier les couleurs par ordre croissant
TriParOcc(Vert, true);
TriParOcc(Bleu, true);

if Odd(NombrePixels) then
begin
ScanLinesD[Y, X].rgbtRed := Rouge[NombrePixels div 2]; // Calculer la
ScanLinesD[Y, X].rgbtGreen := Vert[NombrePixels div 2]; // couleur
ScanLinesD[Y, X].rgbtBlue := Bleu[NombrePixels div 2]; // du pixel
end
else
begin
ScanLinesD[Y, X].rgbtRed := trunc((Rouge[NombrePixels div 2] + Rouge[NombrePixels div 2 + 1]) / 2); // Calculer la
ScanLinesD[Y, X].rgbtGreen:= trunc((Vert[NombrePixels div 2] + Vert[NombrePixels div 2 + 1]) / 2); // couleur
ScanLinesD[Y, X].rgbtBlue := trunc((Bleu[NombrePixels div 2] + Bleu[NombrePixels div 2 + 1]) / 2); // du pixel
end;
end;
end;
end; // FiltreMedian2

Resultats des tests de vitesses comparatifs pour une image-bitMap de 500x347 pixels et une Taille de filtre égale à 10 :
- avec le code de Cedricbi : Mis 63250 millisecondes (hors durée de la prévisualisation)
- avec le code ci-dessus : Mis 2687 millisecondes soit 23,5 fois plus rapide.

A+.
cs_pseudo3 Messages postés 268 Date d'inscription mardi 24 juillet 2007 Statut Membre Dernière intervention 2 février 2021 1
19 avril 2011 à 16:41
Bonjour,

Beau travail ... mais bigrement lent : quelle idée d'utiliser Pixels[] qui rame.
Préférer l'utilisation de Bitmap.Scanline pour la vitesse.
En plus, pour le filtre médian, la vitesse est de surcroît ralantie par le Tri des couleurs par ordre croissant avec la procedure Swap(var X, Y : Double) qui peut être avantageusement remplacée par un tri-par-comptage-d'occurences, sous réserver de remplacer le type double par de l'integer.

A+.
malek2008 Messages postés 1 Date d'inscription vendredi 30 novembre 2007 Statut Membre Dernière intervention 20 décembre 2010
20 déc. 2010 à 23:26
merci pour le code source et bon chace continuation
vienbv Messages postés 14 Date d'inscription lundi 1 novembre 2004 Statut Membre Dernière intervention 17 mars 2010
20 déc. 2007 à 00:27
Bonjour,

Merci pour le code source, c'est ce que je cherche, c'est très gentil.

BVV
bahiatoon Messages postés 5 Date d'inscription lundi 10 avril 2006 Statut Membre Dernière intervention 30 août 2006
19 juil. 2006 à 16:31
Bonjour,
Je veux implémenter un programme qui exécute les mêmes fonctions que le votre mais en Borland C++ Builder 6, j'ai téléchargé le ZIP mais je n'ai rien compris car je suis nulle en Delphi. Je vous écris pour vous demander l'exécutable du programme, pour voir qu'es que vous avez utilisé dans la Form MDI.
Merci par anticipation
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
2 mai 2006 à 16:14
Bonjour,

Je suis désolé d'avoir suspendu ce projet mais pour le moment je suis sur un autre programme !

LBBENSCH -> voici le site internet duquel j'ai pris le plus d'idée : http://homepages.inf.ed.ac.uk/rbf/HIPR2/featops.htm
lbensch Messages postés 55 Date d'inscription vendredi 1 avril 2005 Statut Membre Dernière intervention 10 juin 2010
2 mai 2006 à 14:03
Bonjour,

Je recherche une fonction graphique qui me permettrais d'extraire les contours d'une image. Maheureusement, étant novice dans le domaine graphique, je ne connais son nom. Tout ce que je cherche, c'est une fonction qui me permet de récupérer une image avev un contour en N/B sans dégradés.

Merci.
aymenk Messages postés 77 Date d'inscription samedi 25 janvier 2003 Statut Membre Dernière intervention 29 octobre 2018
17 juin 2005 à 12:41
Trés intéressant , Merci .
Very Usefull Thanks...
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
12 juin 2005 à 19:45
Ma nouvelle version à prit un peu de retard ! Je vous prie de m'excusez ! Elle arrivera je vais dire... prochainement !
Merci à tous pour votre soutient et vos encouragements !
cs_bloom1 Messages postés 328 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 8 mars 2007
10 juin 2005 à 18:05
Merci, vous avez répondu vite a ma question !
Vous êtes fin !
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
10 juin 2005 à 17:41
Merci JIHELB !
La suite arrivera surement (j'espère) dimanche !
Nouvelle présentation, nouvelles fonctions, code plus commenté et plus simple.
jihelb Messages postés 49 Date d'inscription lundi 27 janvier 2003 Statut Membre Dernière intervention 24 mars 2017
10 juin 2005 à 11:38
Bravo Cedricbi pour ton travail, et ton enthousiasme est raffraichissant !
Impatient de connaitre la suite !
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
9 juin 2005 à 18:49
Oui, il me semble que tu peux telecharger Delphi6 en français !
ok, tu vas me demander où? demande dans le forum !!!
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
9 juin 2005 à 18:38
Oui, on place les boutons visuellement mais le code est différent du VB ! Le Delphi est beaucoup plus structuré, beaucoup plus rapide et beaucoup plus "logique". Maintenant je ne programme plus que en Delphi même si le passage VB->Delphi a été difficile !
Par contre je ne sais si tu peux trouver des versions gratuites sur Internet !
cs_bloom1 Messages postés 328 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 8 mars 2007
9 juin 2005 à 18:03
Dans le sens que tu places tes boutons visuellement et non avec du code ?
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
8 juin 2005 à 20:22
Euh... Delphi ! pourquoi ?
cs_bloom1 Messages postés 328 Date d'inscription jeudi 26 août 2004 Statut Membre Dernière intervention 8 mars 2007
8 juin 2005 à 18:27
c'est quel logiciel que vous utilisez pour faire du Delphi ???
Merci de me répondre et merci d'avance !
Bloom1
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
6 juin 2005 à 19:06
OAMRAM -> C'est très gentil à toi de me proposer des idées. Voila les réponses à tes "questions" :
1) Merci pour les sources mais le Delphi est plus compréhensible pour moi !
2) Sinon pour les idées j'en ai encore plein mais il me faut le temps de les mettre en forme ! Mais vous pouvez toujours m'en donner d'autre soit en laissant un commentaire ou en m'écrivant un mail (bignon.cedric@wanadoo.fr).
3) Mes fonctions de TI sont déjà partiellement indépendantes de mon programme (grâce à l'objet TCalcImage) mais pas encore à 100% !
4) Par contre, je ne suis pas trop pour l'idée de pouvoir appeler les fonctions directement par la ligne de commande car pour cela il faudrait que je revois toute la structure de mon programme !

MAURICO -> Merci beaucoup ! Je vais voir ce que je peux en faire mais je pense que cela va m'être très utile !
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
6 juin 2005 à 10:27
Oui biensûr Cedricbi, tu peux choper ma fonction et l' intégrer dans ton appli. Laisse juste un petit commentaire et le link de ma source :)
A+
oamram Messages postés 15 Date d'inscription mercredi 29 mai 2002 Statut Membre Dernière intervention 23 janvier 2006
6 juin 2005 à 07:55
Je n'ai pas regardé ton programme, mais voici quelques liens qui pourront te donner des idéees pour compléter ton programme. Ils ne sont malheureusement pas en Delphi !
- http://www.codeproject.com/cs/media/Image_Processing_Lab.asp
- http://www.codeproject.com/script/articles/list_articles.asp?userid=6556 ==> Voir Rubrique Multimedia/GDI+. Il y a 6 articles.

Idéees :
1) Si tu peux (et veux), essaye de construire ton prg de manière à ca que les fonctions de TI soient totalement indépendantes de ton interface, afin qu'on puisse les ré-utiliser dans d'autres programmes
2) Dans le même esprit, qu'on puisse appeler les fonctions directement en passant les paramètres dans la ligne de commande. Cela est très pratique en TI de pouvoir faire des batchs(des macros) pour des traitements répétitifs.

Si tu veux me joindre n'hésite pas j'ai pleins d'autres idées...
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
3 juin 2005 à 19:32
Oui, je viens de la faire ! Ce n'est pas tellement la valeur la plus logique mais c'est une valeur ! lol
Sinon j'avais déjà vu ton programme pour redimensionner les images sans perdre trop en qualité. Si tu me le permet, j'essaierai de l'integrer dans mon programme !
a+
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
3 juin 2005 à 17:49
Ayant déjà fait des fonctions dans le même genre (j' en ai une postée sur ce site pour redimensionner une image sans perdre la qualité de celle-ci), il faut que tu donnes la valeur la plus logique selon le l' effet voulu. a+
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
3 juin 2005 à 17:23
Merci Maurico ,

J'ai aussi pensé à cette erreur qui pourrais survenir ! C'est pour cela que j'ai mis ce "désagrement" à corriger dans la liste A Faire !
Mais ce qui m'ennui c'est que je ne sais pas par quelle valeur je peut remplacer le résultat !
cs_MAURICIO Messages postés 2106 Date d'inscription mardi 10 décembre 2002 Statut Modérateur Dernière intervention 15 décembre 2014 5
3 juin 2005 à 17:06
Salut Cedricbi,
ça fait un moment que je voulais tester ta source :)

Je la trouve interessante pour apprendre comment on fait les diverses effets graphiques ...

J' en profite pour te signaler une erreur de division par 0 sur la ligne 80 de ton unité untFiltreDivImage_Image laquelle, par sa nature, pourrait exister dans d' autres unités.
a+
cedricbi Messages postés 185 Date d'inscription mercredi 18 décembre 2002 Statut Membre Dernière intervention 21 mars 2011
1 juin 2005 à 15:49
Merci pour la source !
Je pense que je vais utiliser ta source pour le "Emboss", et le "Sharpen".

Merci encore !
Toute autre source et commentaire est le bienvenue !
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
1 juin 2005 à 15:27
Va voir la source
http://vbfrance.com/code.aspx?id=18759

elle devrais t'interesser.... même si c'est en VB
Rejoignez-nous