1. #1
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    décembre 2006
    Messages
    10 027
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2006
    Messages : 10 027
    Points : 15 578
    Points
    15 578

    Par défaut [Image] Synthèse de texture

    Pour faire plaisir a progfou et PRomu@ld (), un petit algo pour faire de la synthese de texture...



    A gauche: image originale (64x64)
    A droite: image générée (256x256)

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    /**
     * @author Xavier Philippeau
     * 
     * TextureSynthesis (Mono scale) 
     *
     */
    public class TextureSynthesis {
     
    	// class NeighborhoodCache: precomputed "Neighborhood" value (rgb) around a pixel
    	private class NeighborhoodCache extends ArrayList<int[]> {};
     
    	// size of the half-window used as neighborhood
    	private int neighborhoodHalfSize = 0;
     
    	// precomputed "Neighborhood" for all pixels in the sample
    	private NeighborhoodCache neighboroodCache = null;; 
     
    	/**
             * Constructor
             * 
             * @param neighborhoodHalfSize size of the half-window used as neighborhood
             */
    	public TextureSynthesis(int neighborhoodHalfSize) {
    		this.neighborhoodHalfSize = neighborhoodHalfSize;
    	}
     
    	/**
             * Create, then initialize the output image with pseudo-random values
             * 
             * @param input the input sample
             * @param width the width of the output image to create
             * @param height the height of the output image to create
             * @return the output image
             */
    	private BufferedImage initialize(BufferedImage input, int width, int height) {
    		BufferedImage output = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
     
    		Random rand = new Random(width+height);
     
    		for(int y=0;y<height;y++) {
    			for(int x=0;x<width;x++) {
     
    				// only the right & bottow bands are needed due to
    				// the toric boundary in neighborhood computation
    				if (x<width-neighborhoodHalfSize && y<height-neighborhoodHalfSize) {
    					continue;
    				}
     
    				// "scanline distance" in output 
    				int d = x+y*width;
     
    				// corresponding "scanline distance" in input 
    				int ds = d % (input.getWidth()*input.getHeight());
    				int ys = ds/input.getWidth();
    				int xs = ds-ys*input.getWidth();
     
    				// copy input to output
    				output.setRGB(x, y, input.getRGB(xs,ys));
    			}
    		}
     
    		return output;
    	}
     
    	/**
             * Return the neighborhood list of pixels 
             * 
             * @param img the image to explore
             * @param x coordinate x of the pixel
             * @param y coordinate y of the pixel
             * @return neighborhood of pixel(x,y)
             */
    	private int[] neighborhood(BufferedImage img, int x, int y) {
    		int width = img.getWidth();
    		int height = img.getHeight();
     
    		// neighborhood = previous pixel in scanline order  
    		//
    		// X X X X X
    		// X X X X X
    		// X X O . .
    		// . . . . .
    		// . . . . .
     
    		int halfsize = this.neighborhoodHalfSize;
     
    		int neighborhood_size = (2*halfsize+1)*(halfsize) + halfsize;
    		int[] neighborhood = new int[neighborhood_size];
    		int index=0;
    		//ArrayList<Integer> neighborhood = new ArrayList<Integer>();
     
    		for(int dy=-halfsize; dy<=0; dy++) {
    			for(int dx=-halfsize; dx<=halfsize; dx++) {
    				int xk = x + dx;
    				int yk = y + dy;
     
    				// Shape constraint
    				if (dy==0 && dx==0) break;
     
    				// toric boundary
    				if (xk<0) xk=width+xk;
    				if (yk<0) yk=height+yk;
    				if (xk>=width) xk=xk-width;
    				if (yk>=height) yk=yk-height;
     
    				//neighborhood.add( img.getRGB(xk,yk) );
    				neighborhood[index++]=img.getRGB(xk,yk);
    			}
    		}
    		return neighborhood;
    	}
     
    	/**
             * Square Difference of two Neighborhoods
             * 
             * @param n1 Neighborhood 1
             * @param n2 Neighborhood 2
             * @param bestscore fast exit condition: exit if difference exceed this threshold
             * @return the Square Difference
             */
    	private double squareDiff(int[] n1, int[] n2, double bestscore) {
     
    		double squareDiff = 0;
    		for(int i=0;i<n1.length;i++) {
     
    			int rgb1 = n1[i], rgb2=n2[i];
    			double dr = ((rgb1>>16)&0xFF)-((rgb2>>16)&0xFF);
    			double dg = ((rgb1>>8)&0xFF)-((rgb2>>8)&0xFF);
    			double db = ((rgb1>>0)&0xFF)-((rgb2>>0)&0xFF);
     
    			squareDiff += dr*dr + dg*dg + db*db;
     
    			// fast exit condition
    			if (squareDiff>=bestscore) break;
    		}
     
    		return squareDiff;
    	}
     
    	/**
             * 
             * Precompute Neighborhood for all pixels in the image
             * 
             * @param img the image to explore
             * @return the list of Neighborhood
             */
    	private NeighborhoodCache precomputeNeighborhood(BufferedImage img) {
    		NeighborhoodCache cache = new NeighborhoodCache();
    		for(int y=0;y<img.getHeight();y++) {
    			for(int x=0;x<img.getWidth();x++) {
    				int[] nb = neighborhood(img,x,y);
    				cache.add(y*img.getWidth()+x,nb);
    			}
    		}
    		return cache;
    	}
     
    	/**
             * compute the value of one pixel
             * 
             * @param sample Image reference
             * @param output Image computed
             * @param x coordinate x of the pixel
             * @param y coordinate y of the pixel
             * @return (r,g,b) value of the computed pixel
             */
    	private int computePixel(BufferedImage sample, BufferedImage output, int x, int y) {
     
    		double bestscore = Double.MAX_VALUE;
    		int bestValue = 0;
     
    		// Neighborhood in the Ouput image
    		int[] outputNeighborhood = neighborhood(output,x,y);
     
    		// Search best matching Neighborhood in the Sample image
            // (exhaustive search !) 
    		int width = sample.getWidth();
    		int height = sample.getHeight();
    		for(int ys=0; ys<height; ys++) {
    			for(int xs=0; xs<width; xs++) {
     
    				// get Sample Neighborhood from the precomputed cache
    				int position = ys*width+xs;
    				int[] sampleNeighborhood = this.neighboroodCache.get(position);
     
    				// compare using square difference
    				double score = squareDiff(sampleNeighborhood,outputNeighborhood,bestscore);
    				//double score = cosDiff(sampleNeighborhood,outputNeighborhood,bestscore);
     
    				// keep the best score
    				if (score<bestscore) {
    					bestscore = score;
    					bestValue = sample.getRGB(xs,ys);	
    				}
    			}
    		}
     
    		return bestValue;
    	}
     
    	/**
             * Generate a new image of size width x height, 
             * using the sample image as a texture seed.
             * 
             * @param sample The sample image
             * @param outputwidth Generated image width
             * @param outputheight Generated image height
             * @return the generated image
             */
    	public BufferedImage synthesis(BufferedImage sample, int outputwidth, int outputheight) {
     
    		// initialize output with pseudo-random values
    		BufferedImage output = initialize(sample,outputwidth,outputheight);
     
    		// precompute the neighborhood of all pixels in the sample
    		this.neighboroodCache = precomputeNeighborhood(sample);
     
    		// compute each pixel of the output
    		for(int y=0; y<outputheight; y++) {
    			System.out.println(y+"/"+outputheight);
    			for(int x=0; x<outputwidth; x++) {
    				int rgb = computePixel(sample,output,x,y);
    				output.setRGB(x,y,rgb);
    			}
    		}
     
    		return output;
    	}
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  2. #2
    Membre éclairé

    Inscrit en
    juin 2004
    Messages
    1 397
    Détails du profil
    Informations forums :
    Inscription : juin 2004
    Messages : 1 397
    Points : 763
    Points
    763

    Par défaut

    Balèze .

    Un papier ? .
    Aucune réponse à une question technique par MP.
    Ce qui vous pose problème peut poser problème à un(e) autre

    http://thebrutace.labrute.fr

  3. #3
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    décembre 2006
    Messages
    10 027
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2006
    Messages : 10 027
    Points : 15 578
    Points
    15 578

    Par défaut

    Citation Envoyé par progfou
    Un papier ? .
    Texture Synthesis -> [J'ai de la chance]
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #4
    Expert éminent
    Avatar de PRomu@ld
    Homme Profil pro
    Ingénieur de Recherche
    Inscrit en
    avril 2005
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur de Recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2005
    Messages : 4 154
    Points : 6 240
    Points
    6 240

    Par défaut

    Pour faire plaisir a progfou et PRomu@ld (), un petit algo pour faire de la synthese de texture...


    http://graphics.stanford.edu/projects/texture/

    J'avais vu la même chose sur LINUX/Mag (n°83), l'algo de base était basé sur les graphes, principalement basé là dessus :

    http://www.cc.gatech.edu/cpl/projects/graphcuttextures/

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    mai 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2008
    Messages : 20
    Points : 10
    Points
    10

    Par défaut

    Bonjour,
    j ai une petite question : (sachant que je suis débutant...)
    ce code est utilisable?
    chez moi, le type Image n'a pas de constructeur tel que celui ci :
    new Image(width, height)

    Merci pour vos réponses

  6. #6
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    décembre 2006
    Messages
    10 027
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : décembre 2006
    Messages : 10 027
    Points : 15 578
    Points
    15 578

    Par défaut

    Citation Envoyé par simonphenix Voir le message
    Bonjour,
    j ai une petite question : (sachant que je suis débutant...)
    ce code est utilisable?
    chez moi, le type Image n'a pas de constructeur tel que celui ci :
    new Image(width, height)

    Merci pour vos réponses
    Ah oui, exact. C'est une classe a moi. J'ai modifié le code pour utiliser un BufferedImage
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    mai 2008
    Messages
    20
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mai 2008
    Messages : 20
    Points : 10
    Points
    10

    Par défaut

    merci beaucoup pour ta réponse et surtout pour la modification

Discussions similaires

  1. base d'image homogènes "sans texture"
    Par MasterMaster dans le forum Traitement d'images
    Réponses: 4
    Dernier message: 16/11/2010, 16h51
  2. [OpenSceneGraph] Pb récupération d'image dans une texture
    Par Darri06 dans le forum OpenSceneGraph
    Réponses: 4
    Dernier message: 29/07/2008, 15h45
  3. affichage image video comme texture
    Par ra_haja501 dans le forum OpenGL
    Réponses: 1
    Dernier message: 12/04/2007, 17h47
  4. Découpage d'une grande image vers des textures
    Par djar dans le forum OpenGL
    Réponses: 14
    Dernier message: 26/02/2005, 18h46
  5. Changer l'image d'une texture
    Par alltech dans le forum DirectX
    Réponses: 5
    Dernier message: 21/08/2002, 01h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo