1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
import java.util.List;
import imageTiTi.Image;
import mathematics.Bresenham;
import mathematics.primitives.pointsTiTi.PointI;
import utils.chronometre.Chronometre;
/**
* <p>Description : Cette classe propose le calcul des differents histogrammes de projections d'une forme contenue dans une image.
* Elle permet egalement de calculer la projection centrale (en anglais CPT pour Central Projection Transformation).</p>
* <p>Packages necessaires : imageTiTi, mathematics.</p>
* <p>Dernieres modifications :<br>
* 14 Mai 2008 => Mise a jour de la classe, notamment pour le calcul a repetition.<br>
* 21 aout 2007 => Creation.</p>
* <p>Copyright : Copyright (c) 2007.</p>
* <p>Laboratoire : LSIS.</p>
* <p>Equipe: Image et Modele, I&M (ex LXAO).</p>
*
* @author Guillaume THIBAULT
* @version 1.2
* @see HistogrammeProjection3D
*/
public class HistogrammeProjection
{
private short[] DiagonaleD = null ;
private short[] DiagonaleG = null ;
private short[] Horizontale = null ;
private short[] Verticale = null ;
private Image Cpt = null ;
/** Un constructeur vide.*/
public HistogrammeProjection()
{
}
/** Methode qui permet d'allouer les differents histrogrammes en fonction de la taille de l'image contenante.
* @param largeur Largeur de l'image.
* @param hauteur Hauteur de l'image.*/
private void SetDimensions(int largeur, int hauteur)
{
int i ;
DiagonaleD = null ;
DiagonaleD = new short[largeur+hauteur] ; // on alloue
DiagonaleG = null ;
DiagonaleG = new short[largeur+hauteur] ;
Horizontale = null ;
Horizontale = new short[hauteur] ;
Verticale = null ;
Verticale = new short[largeur] ;
for (i=0 ; i < largeur ; i++) Verticale[i] = 0 ;
for (i=0 ; i < hauteur ; i++) Horizontale[i] = 0 ;
for (i=0 ; i < largeur+hauteur ; i++) DiagonaleD[i] = DiagonaleG[i] = 0 ;
}
/** Methode qui lance le calcul des histrogrammes. Si le calcul a deja ete effectue, la methode renvoi ECHEC.
* @param image Image contenant la forme.
* @param CalculerCpt Est ce que l'on doit calculer la CPT ?*/
public void Calculer(Image image, boolean CalculerCpt) // Remplissage des Histogrammes
{
int y, x ;
int largeur = image.getWidth() ;
int hauteur = image.getHeight() ;
SetDimensions(largeur, hauteur) ;
for (y=0 ; y < hauteur ; y++)
for (x=0 ; x < largeur ; x++)
if ( image.Pixel(y, x) > 0 )
{ // On remplit les Histogrammes
DiagonaleG[y + x]++ ;
DiagonaleD[hauteur-1-y + x]++ ;
Horizontale[y]++ ;
Verticale[x]++ ;
}
if ( CalculerCpt ) CPT(image) ;
}
/** Methode qui calcule la Central Projection Transformation.
* @param image L'image contenant la forme.*/
private void CPT(Image image)
{
boolean fin ;
int i, j, k, x, y ;
int largeur = image.getWidth() ;
int hauteur = image.getHeight() ;
int Bx, By, nb ;
List<PointI> Trajectoire ;
Bx = By = nb = 0 ;
Cpt = null ;
Cpt = new Image(largeur, hauteur, Image.TYPE_3BYTE_BGR) ;
for (i=0 ; i < hauteur ; i++) // On clone l'image et on calcule le barycentre
for (j=0 ; j < largeur ; j++)
if ( image.Pixel(i, j) > 0 )
{
Cpt.Pixel(i, j, image.Pixel(i, j)) ;
nb++ ;
Bx += j ;
By += i ;
}
Bx = (int)((double)Bx/(double)nb + 0.5) ;
By = (int)((double)By/(double)nb + 0.5) ;
fin = false ;
while ( !fin )
{
fin = true ;
for (i=0 ; i < hauteur ; i++)
for (j=0 ; j < largeur ; j++)
if ( Cpt.Pixel(i, j) > 0 ) // Si on rencontre un pixel
{
Trajectoire = null ;
Trajectoire = Bresenham.TracerListe(j, i, Bx, By) ;
k = Trajectoire.size() - 1 ;
while ( k >= 0 ) // on part du barycentre jusqu'à rencontrer un pixel vide
{
x = Trajectoire.get(k).getX() ;
y = Trajectoire.get(k).getY() ;
if ( Cpt.Pixel(y, x) == 0 )
{
Cpt.Pixel(y, x, Cpt.Pixel(i, j)) ;
Cpt.Pixel(i, j, 0) ;
k = -1 ;
fin = false ;
}
k-- ;
}
}
}
}
/* ----------------------------------------------------------- Les getters ----------------------------------------------------------- */
/** Methode qui retourne le resultat de la Cpt.
* @return L'image contenant le resultat de la Cpt.*/
public Image getCpt()
{
return Cpt ;
}
/** Methode qui renvoit le resultat de la projection sur la diagonale droite.
* @return La projection sur la diagonale droite.*/
public short[] getDiagonaleD()
{
return DiagonaleD ;
}
/** Methode qui renvoit le resultat de la projection sur la diagonale gauche.
* @return La projection sur la diagonale gauche.*/
public short[] getDiagonaleG()
{
return DiagonaleG ;
}
/** Methode qui renvoit le resultat de la projection horizontale.
* @return La projection a l'horizontale.*/
public short[] getHorizontale()
{
return Horizontale ;
}
/** Methode qui renvoit le resultat de la projection verticale.
* @return La projection verticale.*/
public short[] getVerticale()
{
return Verticale ;
}
} |
Partager