Retouche d'images (flous, seuil, histogrammes, opérations arithmétiques)

Soyez le premier à donner votre avis sur cette source.

Vue 11 583 fois - Téléchargée 5 499 fois

Description

Ce programme est le début d'un logiciel de traitement d'image.
J'ai mis pas mal de commentaires pour pouvoir s'y retrouver ! et ainsi, donner aux débutant des explications claires.
Ce programme met en avant l'utilisation des Form MDI, et aussi l'utilisation du OnDrawItem du TListBox et bien sur des routines arithmétiques !

Tous les commentaires sont les bienvenue !

Un des avantage de mon programme est qu'il travaille sur les pixels complètement indépendament à l'affichage sur l'écran : c'est à dire qu'un pixel peut avoir une valeur décimale quelconque (utile pour les divisions) !

Liste des fonctions disponibles :
- Addition Image + Image ou Image + Couleur
- SoustractionImage - Image ou Image - Couleur
- Multiplication Image * Image ou Image * Couleur
- Division Image / Image ou Image / Couleur
- AND Image AND Image ou Image AND Couleur
- OR Image OR Image ou Image OR Couleur
- XOR Image XOR Image ou Image XOR Couleur
- Fondu ou Fusion de 2 Images
- NOT
- Valeur Absolue
- Transformation en Niveaux de gris
- Flou Moyenne
- Flou Gaussien
- Flou Min / Max
- Flou Médian
- Seuil
- Seuil Adaptatif (contours)
- Histogrammes
- Modification de l'histogramme
- Pixelisation

Conclusion :


Si quelqu'un remarque un quelconque bug, ajoutez un commentaire.

S'il bous plaît mettez une note et ajouter un petit commentaire !

Je vais refaire complètement "l'architecture" de mon programme. Si quelqu'un à des idées à apporter à propos de nouvelles fonctionnalités ou autre qu'il m'en fasse part (commentaire ou mail : bignon.cedric@wanadoo.fr) pour pouvoir adapter la structure de mon programme à toutes les fonctions !

Codes Sources

A voir également

Ajouter un commentaire

Commentaires

Messages postés
267
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018

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+.
Messages postés
267
Date d'inscription
mardi 24 juillet 2007
Statut
Membre
Dernière intervention
7 juin 2018

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+.
Messages postés
1
Date d'inscription
vendredi 30 novembre 2007
Statut
Membre
Dernière intervention
20 décembre 2010

merci pour le code source et bon chace continuation
Messages postés
14
Date d'inscription
lundi 1 novembre 2004
Statut
Membre
Dernière intervention
17 mars 2010

Bonjour,

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

BVV
Messages postés
5
Date d'inscription
lundi 10 avril 2006
Statut
Membre
Dernière intervention
30 août 2006

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
Afficher les 26 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.