IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Optimisation de codes utilisant CIMG


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut Optimisation de codes utilisant CIMG
    Bonjour à tous,
    Merci de me consacrer un peu de temps !

    J'explique mon problème, j'ai réalisé un logiciel de calcul en c++ pour une application mécanique en utilisant une technique d'image processing, et il fonctionne très bien.

    Je lis une image BMP a l'aide de CIMG, et je réalise des calculs en utilisant cette image. Tout ceci fonctionne très bien, mais lorsque j'ai augmenté la taille de mes images, le temps d'execution de mon programme est devenu insoutenable, peut une demi heure pour faire un calcul sur une image de 4200x2200 px. Je pense que les enchainements de boucle y sont pour beaucoup mais j'ai pas trop d'idée pour faire autrement... surtout que le resultat final est correct.

    J'aimerais optimisre mon code, au niveau langage, car je pense qu'au niveau algorithme sa risque d'etre compliqué, et je voulais savoir si vous pouviez m'aider à me donner des pistes pour diminuer le temps d'execution de mon programme.

    Je vous le joint, je vous remercie de votre aide par avance.

    Code : 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
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    #define NOMINMAX
    #include "CImg.h"
    #include <windows.h> 
    #include <iostream>
    #include <fstream>
    #include <limits>
    #include <cmath>
    #include <string> 
    #define round(x) (x<0?ceil((x)-0.5):floor((x)+0.5))
    #define PI (3.1415926535897932384626433832795028841971693992)
    using namespace cimg_library;
    using namespace std;
     
     
    bool is_readable( const std::string & file ) 
    { 
    	std::ifstream fichier( file.c_str() ); 
    	return !fichier.fail(); 
    } 
     
     
    int main() {
    	/** Import of the image of the Workpiece using CImg Library
            For more information about this Image Processing Library go to http://cimg.sourceforge.net/ */
    	CImg<double> image("Workpiece.bmp");
    	CImg<double> image_w=image;	
    	int nx = image.dimx();
    	int ny = image.dimy();
     
     
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"********** CALCULUS OF THE ENGAGEMENT ANGLE USING IMAGE PROCESSING ************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"******* LICP- Created by Nicolas Planquet - Master Thesis - June 2009 *********"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"****************SWISS FEDERAL INSTITUTE OF TECHNOLOGY**************************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout<<"Information about input picture : "<<endl;
    	cout << "Number of Pixel in x : " << nx << " and in y : " << ny << " total of pixels : " << nx*ny <<std::endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout<<"Information about the tool and the workpiece : "<<endl;
    	double WorkpieceLength = 210;
    	double ToolDiameter = 20;
    	double scale = WorkpieceLength/nx ;
    	int compteur=0;
    	// Calcul de la taille d'un pixel en mm (représente la résolution de la matrice)
    	int NbToolPixel = round(ToolDiameter / scale) ;
    	int NbToolPixelReel = NbToolPixel;
    	int n = NbToolPixel/2;
    	if(NbToolPixel%2==0)
    	NbToolPixel++;
    	int startX=-1;
    	int startY=-1;
    	cout << "Tool Diameter : " << ToolDiameter <<" mm"<<endl;
    	cout << "Workpiece Length : " << WorkpieceLength <<" mm"<<endl;
    	cout <<"Scale : "<< scale <<" mm/px"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	cout <<"*******************************************************************************"<<endl;
    	/** Lecture du fichier d'entrée pour construire le tableau 2D représentant l'outil */
    	cout<<" "<<endl;
     
    	int** Tool = new int* [NbToolPixel] ;
    	for (int i=0 ;i<NbToolPixel ;i++)
    	{
    		Tool[i] = new int[NbToolPixel] ;
    	}
     
    	int** ToolDetect = new int* [NbToolPixel] ;
    	for (int i=0 ;i<NbToolPixel ;i++)
    	{
    		ToolDetect[i] = new int[NbToolPixel] ;
    	}
     
     
    	for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++)
    		{
    			ToolDetect[i][j]=0;
    			double distance = 0 ;
    			distance = sqrt((double)(i-n)*(i-n)+(j-n)*(j-n));
    			if(round(distance)<n)
    				Tool[i][j]=0;
    			else
    				Tool[i][j]=1;
    		}
    	}
     
     
    	for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++)
    		{
    			int testvoisin=0;
    			if(Tool[i][j]==0)
    			{
    				if(i>0 && j>0 && Tool[i-1][j-1]==1)
    					testvoisin++;
    				if(i>0 && Tool[i-1][j]==1)
    					testvoisin++;
    				if(i>0 && j<NbToolPixel-1 && Tool[i-1][j+1]==1)
    					testvoisin++;
    				if(j<NbToolPixel-1 && Tool[i][j+1]==1)
    					testvoisin++;
    				if(j<NbToolPixel-1 && i<NbToolPixel-1 && Tool[i+1][j+1]==1)
    					testvoisin++;
    				if(i<NbToolPixel-1 && Tool[i+1][j]==1)
    					testvoisin++;
    				if(i<NbToolPixel-1  && j>0 && Tool[i+1][j-1]==1)
    					testvoisin++;
    				if(j>0 &&  Tool[i][j-1]==1)
    					testvoisin++;
    				if(testvoisin>=2)
    					Tool[i][j]=5;
    			}
    		}
    	}
    	Tool[0][n]=5;
    	Tool[n][0]=5;
    	Tool[NbToolPixel-1][n]=5;
    	Tool[n][NbToolPixel-1]=5;
     
    	/** Recherche du point de depart du toolpath */
    	for(int i=0;i<nx;i++){
    		for(int j=0;j<ny;j++){
    			if(image_w(i,j,0)==255 && image_w(i,j,1)==255 && image_w(i,j,2)==0){
    				startX=i;
    				startY=j;
    				// Blanc
    				image_w(startX,startY,0)=255;
    				image_w(startX,startY,1)=255;
    				image_w(startX,startY,2)=255;	
    			}
    		}
    	}
     
    	if(startX==-1 || startY==-1){
    			cout<<"ERROR : Starting point of the toolpath not found, please mark it with this color (yellow in paint) R:255 V:255 B:0"<<endl;
    			Sleep(20000);
    			return 0;}
     
     
    /** Usinage au point de départ du toolpath
    On parcourt le tableau contenant l'information sur l'outil et l'image aux coordonnées 
    correspondantes et on réalise une operation booleenne*/
    		for(int i =-n ; i<=n;i++){
    			for(int j =-n ; j<=n;j++){
    				if(startX+i>=0 && startY+j>=0 && startX+i<nx && startY+j<ny && i+n>=0 && j+n>=0 && i+n<NbToolPixel && j+n<NbToolPixel){
    					int PieceStart1 = image_w(startX+i,startY+j,0);
    					int PieceStart2 = image_w(startX+i,startY+j,1);
    					int PieceStart3 = image_w(startX+i,startY+j,2);
    					int ToolStart = Tool[i+n][j+n];
    					if(PieceStart1==0 && PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    						if(ToolStart == 5) {
    							// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    							ToolDetect[i+n][j+n]=6;
    						}
    						image_w(startX+i,startY+j,0)=255;
    						image_w(startX+i,startY+j,1)=255;
    						image_w(startX+i,startY+j,2)=255;
    					}
    				}
    			}
    		}
     
    	ofstream resultat;
    	resultat.open("resultat.txt", ios::out);
    	if (resultat.bad())
    	return 1; 
     
    	cout<<"SIMULATION AND COMPUTATION IN PROGRESS ..."<<endl;
    	double EngagementAngle=0;
    	int cas=0;
    	int CoordAngleStartX1=0;
    	int CoordAngleStartY1=0;
    	int CoordAngleStartX2=0;
    	int CoordAngleStartY2=0;
    	double distance=0;
    	double distanceUpdate=0;	
    	double coordinateX=0;
    	double coordinateY=0;
    	double distanceStartAngle1=0;
    	double distanceStartAngle2=0;
    	int OrigineX=0;
    	int OrigineY=0;
    	double StartAngle=-1;
    	double ExitAngle=-1;
    	double min=-1;
    	double longueur=0;
     
     
    	while((image_w(startX-1,startY-1,0)==255 && image_w(startX-1,startY-1,1)==0 && image_w(startX-1,startY-1,2)==0) ||
    		  (image_w(startX-1,startY,0)==255 && image_w(startX-1,startY,1)==0 && image_w(startX-1,startY,2)==0)  || 
    		  (image_w(startX-1,startY+1,0)==255 && image_w(startX-1,startY+1,1)==0 && image_w(startX-1,startY+1,2)==0) || 
    		  (image_w(startX,startY+1,0)==255 && image_w(startX,startY+1,1)==0 && image_w(startX,startY+1,2)==0)  ||
    		  (image_w(startX+1,startY+1,0)==255 && image_w(startX+1,startY+1,1)==0 && image_w(startX+1,startY+1,2)==0) || 
    		  (image_w(startX+1,startY,0)==255 && image_w(startX+1,startY,1)==0 &&  image_w(startX+1,startY,2)==0) || 
    		  (image_w(startX+1,startY-1,0)==255 && image_w(startX+1,startY-1,1)==0 && image_w(startX+1,startY-1,2)==0) ||
    		  (image_w(startX,startY-1,0)==255 && image_w(startX,startY-1,1)==0 && image_w(startX,startY-1,2)==0))
    	{
     
    		if(image_w(startX+1,startY,0)==255 && image_w(startX+1,startY,1)==0 && image_w(startX+1,startY,2)==0){
    			startX=startX+1;
    			cas=1;
    		}
    		else if(image_w(startX-1,startY,0)==255 && image_w(startX-1,startY,1)==0 && image_w(startX-1,startY,2)==0){
    			startX=startX-1;
    			cas=2;
    		}
    		else if(image_w(startX,startY-1,0)==255 && image_w(startX,startY-1,1)==0 && image_w(startX,startY-1,2)==0){
    			startY=startY-1;
    			cas=4;
    		}
    		else if(image_w(startX,startY+1,0)==255 && image_w(startX,startY+1,1)==0 && image_w(startX,startY+1,2)==0){
    			startY=startY+1;
    			cas=3;
    		}
    		else if(image_w(startX-1,startY+1,0)==255 && image_w(startX-1,startY+1,1)==0 && image_w(startX-1,startY+1,2)==0){
    			startX=startX-1;
    			startY=startY+1;
    		}
    		else if(image_w(startX+1,startY+1,0)==255 && image_w(startX+1,startY+1,1)==0 && image_w(startX+1,startY+1,2)==0){
    			startX=startX+1;
    			startY=startY+1;
    		}
    		else if(image_w(startX+1,startY-1,0)==255 && image_w(startX+1,startY-1,1)==0 && image_w(startX+1,startY-1,2)==0){
    			startX=startX+1;
    			startY=startY-1;
    		}
    		else if(image_w(startX-1,startY-1,0)==255 && image_w(startX-1,startY-1,1)==0 && image_w(startX-1,startY-1,2)==0){
    			startX=startX-1;
    			startY=startY-1;
    		}
     
     
     
    		coordinateX=startX*scale;
    		coordinateY=(ny-startY)*scale;
     
     
    		//On efface le point rouge du toolpath
    		image_w(startX,startY,0)=255;
    		image_w(startX,startY,1)=255;
    		image_w(startX,startY,2)=255;
     
    		//On efface la piece en contact avec l'outil
    		for(int i =-n ; i<=n;i++){
    			for(int j =-n ; j<=n;j++){
    				if(startX+i>=0 && startY+j>=0 && startX+i<nx && startY+j<ny  && i+n>=0 && j+n>=0 && i+n<NbToolPixel && j+n<NbToolPixel){
    					int PieceStart1 = image_w(startX+i,startY+j,0);
    					int PieceStart2 = image_w(startX+i,startY+j,1);
    					int PieceStart3 = image_w(startX+i,startY+j,2);
    					int ToolStart = Tool[i+n][j+n]; 
    					if((PieceStart1==0||PieceStart1==255) && PieceStart2==0 && PieceStart3==0 && ToolStart == 5){
    							// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    							ToolDetect[i+n][j+n]=6;
    						}
    					if(PieceStart1==0 && PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    						image_w(startX+i,startY+j,0)=255;
    						image_w(startX+i,startY+j,1)=255;
    						image_w(startX+i,startY+j,2)=255;
    					}
    				}
    			}
    		}
     
    	/** Calcul de l'angle en fonction du nombre de pixel relevés */
     
    	for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++){
    			if(ToolDetect[i][j]==6){
    				for(int x=0;x<NbToolPixel;x++){
    					for(int y=0;y<NbToolPixel;y++){
    						if(ToolDetect[x][y]==6||ToolDetect[x][y]==7){
    							// Compute the euclidian distance between the current point and the past point
    							distanceUpdate=sqrt((double)(x-i)*(x-i)+(y-j)*(y-j));
    							//Check if the distance is the max
    							if(distanceUpdate>distance){
    								//if yes save the max and update it with the new value
    								distance=distanceUpdate;
    								CoordAngleStartX1=i;
    								CoordAngleStartY1=j;
    								CoordAngleStartX2=x;
    								CoordAngleStartY2=y;
    							}
    						}
    					}
    				}
    			}
    		}
    	}
     
     
    	if(cas==1)
    	{
    	// if it goes right origin is
    	OrigineX=n;
    	OrigineY=0;
    	}
    	else if(cas==2)
    	{
    	// if it goes left origin is
    	OrigineX=n;
    	OrigineY=NbToolPixel-1;
    	}
    	else if(cas==3)
    	{
    	// if it goes down origin is
    	OrigineX=NbToolPixel-1;
    	OrigineY=n;
    	}
    	else if(cas==4)
    	{
    	// if it goes up origin is
    	OrigineX=0;
    	OrigineY=n;
    	}
     
    	distanceStartAngle1=sqrt((double)(CoordAngleStartX1-OrigineX)*(CoordAngleStartX1-OrigineX)+(CoordAngleStartY1-OrigineY)*(CoordAngleStartY1-OrigineY));
    	distanceStartAngle2=sqrt((double)(CoordAngleStartX2-OrigineX)*(CoordAngleStartX2-OrigineX)+(CoordAngleStartY2-OrigineY)*(CoordAngleStartY2-OrigineY));
     
    	if(distanceStartAngle1<distanceStartAngle2)
    	min=distanceStartAngle1;
    	else
    	min=distanceStartAngle2;
     
     
     
    	if(min!=0)
    	StartAngle=2*asin(min/(NbToolPixel-1))*(180/PI);
    	else
    	StartAngle=0;
     
     
    	for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++){
    			ToolDetect[i][j]=0;
    		}
    	}
     
    		/** CF formule Planquet Master Thesis report */
    		if(distance!=0)
    		EngagementAngle = 2*asin(distance/(NbToolPixel-1))*(180/PI);
    		else
    		EngagementAngle = 0 ;
     
    		ExitAngle=StartAngle+EngagementAngle;
     
     
    	compteur++;
    	longueur=compteur*scale;
    	//cout<<compteur<<endl;
        resultat<<compteur<<" "<<coordinateX<<" "<<coordinateY<<" "<<round(StartAngle)<<" "<<round(ExitAngle)<<endl;
     
    	}
     
    	cout<<"... COMPUTATION ENDED ! see resultat.txt"<<endl;
    	//resultat.close(); //on ferme le fichier pour liberer la mémoire 
     
    	return 0;
    }

  2. #2
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    En placant des choses en commentaires, j'ai remarqué que si prenais enormement de temps sont ces deux morceaux de codes :
    Si quelqu'un a une idee pour ameliorer ces boucles, et surtout en m'indiquant ce qui est le plus couteux en temps machine dans ces boucles :


    Ici j'actualise l'image en faisant une sorte d'opération booleaine avec mon tableau... je pense que c'est ici que le temps est important :
    Code : 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
    		for(int i =-n ; i<=n;i++){
    			for(int j =-n ; j<=n;j++){
    				if(startX+i>=0 && startY+j>=0 && startX+i<nx && startY+j<ny  && i+n>=0 && j+n>=0 && i+n<NbToolPixel && j+n<NbToolPixel){
    					int PieceStart1 = image_w(startX+i,startY+j,0);
    					int PieceStart2 = image_w(startX+i,startY+j,1);
    					int PieceStart3 = image_w(startX+i,startY+j,2);
    					int ToolStart = Tool[i+n][j+n]; 
    					if((PieceStart1==0||PieceStart1==255) && PieceStart2==0 && PieceStart3==0 && ToolStart == 5){
    							// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    							ToolDetect[i+n][j+n]=6;
    						}
    					if(PieceStart1==0 && PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    						image_w(startX+i,startY+j,0)=255;
    						image_w(startX+i,startY+j,1)=255;
    						image_w(startX+i,startY+j,2)=255;
    					}
    				}
    			}
    		}
    Ici je cherche a trouver la plus grande distance entre 2 6 dans un tableau, les 4 boucles for sont particulieremnt horribles, si quelqu'un a une idée...

    Code : 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
    for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++){
    			if(ToolDetect[i][j]==6){
    				for(int x=0;x<NbToolPixel;x++){
    					for(int y=0;y<NbToolPixel;y++){
    						if(ToolDetect[x][y]==6||ToolDetect[x][y]==7){
    							// Compute the euclidian distance between the current point and the past point
    							distanceUpdate=sqrt((double)(x-i)*(x-i)+(y-j)*(y-j));
    							//Check if the distance is the max
    							if(distanceUpdate>distance){
    								//if yes save the max and update it with the new value
    								distance=distanceUpdate;
    								CoordAngleStartX1=i;
    								CoordAngleStartY1=j;
    								CoordAngleStartX2=x;
    								CoordAngleStartY2=y;
    							}
    						}
    					}
    				}
    			}
    		}
    	}

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    327
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Janvier 2009
    Messages : 327
    Points : 402
    Points
    402
    Par défaut
    Bonjour,
    Je répond certainement à côté mais tu pourrais pas diminuer ton image au traiter un pixels sur 2 par exemple ?
    A bientôt

  4. #4
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par wakan Voir le message
    Bonjour,
    Je répond certainement à côté mais tu pourrais pas diminuer ton image au traiter un pixels sur 2 par exemple ?
    A bientôt
    Le soucis c'est que mon resultat demande une grande précision et qu'il m'est impossible de diminuer la précison et donc la taille de mes images, mais je sais que mon code est lojn d'être parfait, mais je suis pas assez calé en c++ pour pouvoir réduire le cout en temps (je ne connais pas vraiment ce qui est couteux en terme de temps machine en c++, meme si j'ai une peu regardé sur Wiki)

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(int i =-n ; i<=n;i++){
    	for(int j =-n ; j<=n;j++){
    		if(
                startX+i>=0 // (1)
             && startY+j>=0 // (2)
             && startX+i<nx // (3)
             && startY+j<ny  // (4)
             && i+n>=0 // (5)
             && j+n>=0 // (6)
             && i+n<NbToolPixel // (7)
             && j+n<NbToolPixel// (8)
          ){
    Hypothèse: n>=0
    (5) : i+n>=0 inutile car i varie de -n à n
    (6) : j+n>=0 inutile car j varie de -n à n
    (1) : faire commencer ta boucle sur i à max(startX,-n)
    (2) : faire commencer ta boucle sur j à max(startY,-n)
    (3) et (7) : faire cesser ta boucle sur i à min (n, nx-startX, NbToolPixel)
    (4) et (7): faire cesser ta boucle sur j à min (n, nx-startY, NbToolPixel)
    Donc plus besoin du test dans ta boucle.

    Au lieu de faire startX+i et startY+j, fait ++startX dans la boucle i et ++startY dans la boucle j.

    De la même façon, sort le déréférencement de Tool[i+n][j+n] une partie dans la boucle sur i et une autre sur la boucle sur j. Idem pour ToolDetect

    Change :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    			if((PieceStart1==0||PieceStart1==255) && PieceStart2==0 && PieceStart3==0 && ToolStart == 5){
    					// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    					ToolDetect[i+n][j+n]=6;
    				}
    			if(PieceStart1==0 && PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    				image_w(startX+i,startY+j,0)=255;
    				image_w(startX+i,startY+j,1)=255;
    				image_w(startX+i,startY+j,2)=255;
    			}
    En
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
             if(PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    			   if((PieceStart1==0||PieceStart1==255) && ToolStart == 5){
    					   // on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    					   ToolDetect[i+n][j+n]=6;
    				}
    			   if(PieceStart1==0){
    				   image_w(startX+i,startY+j,0)=255;
    				   image_w(startX+i,startY+j,1)=255;
    				   image_w(startX+i,startY+j,2)=255;
    			   }
             }
    Ces deux dernières choses ne te feront peut être pas gagner tant que ça. C'est le travail sur les boucles qui sera le plus efficace si beaucoup de pixel était ignorés.
    Après, il faudrait revoir l'algo pour éviter la double boucle.

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Sur ta deuxième boucle, tu dois avoir une symétrie, non ? tu dois pouvoir arrêter la boucle sur x en i+1 et y en j+1 ? Ou quelque chose avoisinant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i=0;i<NbToolPixel;i++){
    		for(int j=0;j<NbToolPixel;j++){
    			if(ToolDetect[i][j]==6){
    				for(int x=0;x<i+1;x++){
    					for(int y=0;y<j+1;y++){
    J'ai pas trop réfléchi, mais tu dois calculer la distance P1(x,y)<->P2(i,j) puis P1(i,j)<->P2(x,y) -> D'où ta symétrie?

  7. #7
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for(int i =-n ; i<=n;i++){
    	for(int j =-n ; j<=n;j++){
    		if(
                startX+i>=0 // (1)
             && startY+j>=0 // (2)
             && startX+i<nx // (3)
             && startY+j<ny  // (4)
             && i+n>=0 // (5)
             && j+n>=0 // (6)
             && i+n<NbToolPixel // (7)
             && j+n<NbToolPixel// (8)
          ){
    Hypothèse: n>=0
    (5) : i+n>=0 inutile car i varie de -n à n
    (6) : j+n>=0 inutile car j varie de -n à n
    (1) : faire commencer ta boucle sur i à max(startX,-n)
    (2) : faire commencer ta boucle sur j à max(startY,-n)
    (3) et (7) : faire cesser ta boucle sur i à min (n, nx-startX, NbToolPixel)
    (4) et (7): faire cesser ta boucle sur j à min (n, nx-startY, NbToolPixel)
    Donc plus besoin du test dans ta boucle.

    Au lieu de faire startX+i et startY+j, fait ++startX dans la boucle i et ++startY dans la boucle j.

    De la même façon, sort le déréférencement de Tool[i+n][j+n] une partie dans la boucle sur i et une autre sur la boucle sur j. Idem pour ToolDetect
    merci beaucoup pour ton aide, je comprends pas tout... Je dois changer ma boucle en cela, en changeant l'indice i par startX ?
    Mais comment je suis supposé faire cela ?
    Je comprends bien écrire cela (très futé, j'y aurais jamais pensé, cela economise pas mal de tour de boucle, c'est génial!), éais je suis obligé de garder l'indice i non ? ne serait ce que pour l'uttiliser après ?
    J'ai écris cela déja, mais j'ai un mal de crane horrible après avoir essayer de comprendre mes changements, j'imagine qu'une bonne moitié est fausse.

    Code : 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
    		for(int i=max(startX,-n);i<=min(n,nx-startX,NbToolPixel);++startX){
    			for(int j=max(startY,-n);j<=min(n,ny-startY,NbToolPixel);++startY){
    					PieceStart1 = image_w(startX+i,startY+j,0);
    					PieceStart2 = image_w(startX+i,startY+j,1);
    					PieceStart3 = image_w(startX+i,startY+j,2);
    					ToolStart = Tool[i+n][j+n]; 
    					if(PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    						if((PieceStart1==0||PieceStart1==255) && ToolStart == 5){
    							// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    							ToolDetect[i+n][j+n]=6;
    						}
    						if(PieceStart1==0){
    							image_w(startX+i,startY+j,0)=255;
    							image_w(startX+i,startY+j,1)=255;
    							image_w(startX+i,startY+j,2)=255;
    						}
    					}
    					//if((PieceStart1==0||PieceStart1==255) && PieceStart2==0 && PieceStart3==0 && ToolStart == 5){
    					//		// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    					//		ToolDetect[i+n][j+n]=6;
    					//	}
    					//if(PieceStart1==0 && PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    					//	image_w(startX+i,startY+j,0)=255;
    					//	image_w(startX+i,startY+j,1)=255;
    					//	image_w(startX+i,startY+j,2)=255;
    					//}
    				}
    			}
    		}

    Je viens de voir ton nouveau post : En gros, j'ai un arc de cercle compossé de 6 graphiquement dans un tableau de 0 plus ou moins grand stocké dans mon tool detect et je dois calculer la distance de la corde.
    En gros je dois prendre la plus grande distance qui éloigne deux 6 pour trouver cette valeur.
    Ici, je parcours chaque 6, et je calcule toutes les distances avec les autre 6, pour ne suavegarder la plus grande dans une variable distance.

  8. #8
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Ce serait pas plutot --startX étant donné que je commence au max ?
    Et plutot min(nx-startX-1,n,NbToolPixel) sinon je sors du tableau non ?

    Je sais pas si je suis dans les choux ou pas ;D

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Pour le premier :
    Oui, il faut garder tes indices i et j. C'est juste qu'il faut faire varier StartX et StartY en même temps (en particulier pour éviter startX+i à chaque boucle sur j, même s'il peut y avoir des phénomènes de cache).
    Enfin, faut pas se leurrer. Les meilleurs optimisations seront celles qui feront descendre le nombre d'itération de ta boucle. Tout le reste ne sont que des sucres dont les gains restent à démontrer...
    Code : 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
     
    int fin_i = min (n, nx-startX, NbToolPixel);
    int fin_j = min (n, nx-startY, NbToolPixel);
    for(
        int i = max(startX,-n); 
        i<=n;
       ++i,++startX
       ){
    	for(
          int j = max(startY,-n) ; 
          j<=n;
          ++j,++startY
          ){
    			int PieceStart1 = image_w(startX+i,startY+j,0);
    			int PieceStart2 = image_w(startX+i,startY+j,1);
    			int PieceStart3 = image_w(startX+i,startY+j,2);
    			int ToolStart = Tool[i+n][j+n]; 
            if(PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    			   if((PieceStart1==0||PieceStart1==255) && ToolStart == 5){
    					   // on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    					   ToolDetect[i+n][j+n]=6;
    				}
    			   if(PieceStart1==0){
    				   image_w(startX+i,startY+j,0)=255;
    				   image_w(startX+i,startY+j,1)=255;
    				   image_w(startX+i,startY+j,2)=255;
    			   }
             }
    		}
    	}
    }
    Au faute de recopie près

    Citation Envoyé par nicoblade77240
    Je viens de voir ton nouveau post : En gros, j'ai un arc de cercle compossé de 6 graphiquement dans un tableau de 0 plus ou moins grand stocké dans mon tool detect et je dois calculer la distance de la corde.
    En gros je dois prendre la plus grande distance qui éloigne deux 6 pour trouver cette valeur.
    Ici, je parcours chaque 6, et je calcule toutes les distances avec les autre 6, pour ne suavegarder la plus grande dans une variable distance.
    Désolé, j'ai rien compris ! Peux-tu reformuler ? L'idée de base est que tu parcours ton image en 4 boucles imbriquées : les 2 premières (i et j) pour ton premier point et les deux suivantes (x et y) pour le second point. Donc à un moment tu calcules ta distance (i=0,j=0) avec (x=1,y=1) puis tu calcules la distance (i=1;j=1) avec (x=0,y=0) ... qui devraient être identique. C'est pour ça que je pense qu'il y a une symétrie dans ton calcul et que tu dois pouvoir en faire que la moitié.

  10. #10
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    En me relisant je comprends pas non plus

    Vu que je sais pas du tout m'exprimer en français je préfère faire un dessin...

    Mon tableau ToolDetext ressemble a cela :

    111111111151111111111
    111111155555561111111
    111115500000006611111
    111150000000000061111
    111500000000000006111
    115000000000000000611
    115000000000000000611
    150000000000000000061
    150000000000000000061
    150000000000000000061
    550000000000000000055
    150000000000000000051
    150000000000000000051
    150000000000000000051
    115000000000000000511
    115000000000000000511
    111500000000000005111
    111150000000000051111
    111115500000005511111
    111111155555551111111
    111111111151111111111

    L'idée est de calculer la distance entre les deux 6 les plus eloignés :
    voir la pièce jointe.

    Ce que je fais dans l'algorithme :
    -Parcours du tableau
    - Si 6 :
    Je calcule la distance entre les autres 6 (3e et 4e boucle)
    Si distance>max je garde distance
    Fin

    Je me demande de plus en plus si je vais pas stocké cela dans un tableau 1D

    En version corrigée, cela doit etre cela, dis mois si je me trompe !
    Code : 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
    		for(int i = max(startX,-n);i<=min(n,nx-startX-1,NbToolPixel-n);++i,++startX){
    			for(int j = max(startY,-n);j<=min(n,ny-startY-1,NbToolPixel-n);++j,++startY){
    						int PieceStart1 = image_w(startX+i,startY+j,0);
    						int PieceStart2 = image_w(startX+i,startY+j,1);
    						int PieceStart3 = image_w(startX+i,startY+j,2);
    						int ToolStart = Tool[i+n][j+n]; 
    						if(PieceStart2==0 && PieceStart3==0 && ToolStart!=1){
    							if((PieceStart1==0||PieceStart1==255) && ToolStart == 5){
    								// on active la partie de l'outil en contact avec la pièce pour le calcul de l'angle
    								ToolDetect[i+n][j+n]=6;
    							}
    							if(PieceStart1==0){
    								image_w(startX+i,startY+j,0)=255;
    								image_w(startX+i,startY+j,1)=255;
    								image_w(startX+i,startY+j,2)=255;
    							}
    						}
    				}
    		}
    	}
    Images attachées Images attachées  

  11. #11
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Il ne rentre jamais dans la boucle for, je pense qu'il y un problème dans l'utilisation de max pour commencer la boucle...
    i est deja plus grand que la condition d'arret...

    Je continue a chercher ! Merci !

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par nicoblade77240 Voir le message
    En me relisant je comprends pas non plus

    Vu que je sais pas du tout m'exprimer en français je préfère faire un dessin...

    Mon tableau ToolDetext ressemble a cela :

    111111111151111111111
    111111155555561111111
    111115500000006611111
    111150000000000061111
    111500000000000006111
    115000000000000000611
    115000000000000000611
    150000000000000000061
    150000000000000000061
    150000000000000000061
    550000000000000000055
    150000000000000000051
    150000000000000000051
    150000000000000000051
    115000000000000000511
    115000000000000000511
    111500000000000005111
    111150000000000051111
    111115500000005511111
    111111155555551111111
    111111111151111111111

    L'idée est de calculer la distance entre les deux 6 les plus eloignés :
    voir la pièce jointe.

    Ce que je fais dans l'algorithme :
    -Parcours du tableau
    - Si 6 :
    Je calcule la distance entre les autres 6 (3e et 4e boucle)
    Si distance>max je garde distance
    Fin

    Je me demande de plus en plus si je vais pas stocké cela dans un tableau 1D
    Effectivement, tu devrais découper en 2 passes surtout si ta fréquence de 6 est très faible :
    1/ Une première passe linéaire où tu sauvegardes les positions de tes différents 6 sans te poser de question
    2/ Sur cette liste qui devrait être beaucoup plus réduite tu peux faire le calcul de distance :
    Code : 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
     
    distance_max = 0
    Point1 = Vide
    Point2 = Vide
    Pour iterateur1 = premier jusqu'à dernier
       Pour iterateur2 = iterateur1+1 jusqu'à dernier
         distance_courante = distance(iterateur1,iterateur2)
         Si distance_courante>distance_max
             distance_max = distance_courante
             point1 = iterateur1
             point2 = iterateur2
         Fin Si
         ++iterateur2
      Fin Pour (iterateur2)
      ++iterateur1
    Fin Pour (iterateur1)
    Citation Envoyé par nicoblade77240 Voir le message
    En version corrigée, cela doit etre cela, dis mois si je me trompe !
    J'ai l'impression que c'est OK mais j'ai les indices et les boucles qui commencent à se mélanger

  13. #13
    Nouveau membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2008
    Messages
    42
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2008
    Messages : 42
    Points : 28
    Points
    28
    Par défaut
    Ok, faut que je reprenne tout cela calmement avec un papier et un crayon !
    Merci beaucoup pour ton aide !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Optimisation et amélioration d'un code utilisant Artichow
    Par heretik25 dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 05/08/2011, 21h53
  2. [MySQL] Optimisation de mon code utilisant simple xml
    Par heretik25 dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 05/08/2011, 20h13
  3. Réponses: 2
    Dernier message: 24/05/2011, 16h23
  4. [Stratégie][GC] Optimiser la mémoire utiliser
    Par Piolet dans le forum Général Java
    Réponses: 12
    Dernier message: 05/05/2004, 10h51
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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