Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Globals

cntcdg.c

Go to the documentation of this file.
00001 /************************************************************************* 00002 * $Id: cntcdg.c,v 1.1 2005/09/09 08:22:22 bellet Exp $ 00003 ************************************************************************** 00004 This software is governed by the CeCILL license under French law and 00005 abiding by the rules of distribution of free software. You can use, 00006 modify and/ or redistribute the software under the terms of the CeCILL 00007 license as circulated by CEA, CNRS and INRIA at the following URL 00008 "http://www.cecill.info". 00009 00010 As a counterpart to the access to the source code and rights to copy, 00011 modify and redistribute granted by the license, users are provided only 00012 with a limited warranty and the software's author, the holder of the 00013 economic rights, and the successive licensors have only limited 00014 liability. 00015 00016 In this respect, the user's attention is drawn to the risks associated 00017 with loading, using, modifying and/or developing or reproducing the 00018 software by the user in light of its specific status of free software, 00019 that may mean that it is complicated to manipulate, and that also 00020 therefore means that it is reserved for developers and experienced 00021 professionals having in-depth computer knowledge. Users are therefore 00022 encouraged to load and test the software's suitability as regards their 00023 requirements in conditions enabling the security of their systems and/or 00024 data to be ensured and, more generally, to use and operate it in the 00025 same conditions as regards security. 00026 00027 The fact that you are presently reading this means that you have had 00028 knowledge of the CeCILL license and that you accept its terms. 00029 00030 Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de 00031 l'Image). All rights reserved. See License.txt for details. 00032 00033 Version 1.0 05/09/2005 00034 *************************************************************************/ 00035 00036 #include <stdio.h> 00037 #include <stdlib.h> 00038 #include <math.h> 00039 #include "idcnt.h" 00040 #include "iderr.h" 00041 00042 static int pic=0; 00043 static int ravin=0, supprec=0, infprec=0, supsuiv=0, infsuiv=0, fourche=0, seul=1, flag=0, i, j; 00044 static PPIMAGE_UCHAR imtmp=0; 00045 00046 static void testprec (void); 00047 static void testsuiv (void); 00048 00049 00050 /* FUNCTION DESCRIPTION ************************************************** 00051 00052 IdCntCentreGravite (fonction) 00053 00054 RESUME: Calcule le Centre de Gravite (non pondere) d'un contour 00055 00056 DESCRIPTION: Calcule le Centre de Gravite (non pondere) d'un contour 00057 Les points doivent etre 'assez proches' les uns des autres 00058 Remarque: ds le cas de points 'tres eloignes' il faudrait rendre 00059 le CNT connexe 00060 00061 SYNTAXE: void IdCntCentreGravite (PCONTOUR_USHORT cnt, int *x, int *y ); 00062 00063 RETOUR: type : viod 00064 00065 PARAMETRES: nom : cnt 00066 type : PCONTOUR_USHORT 00067 role : Pointeur vers le contour 00068 00069 nom : x 00070 type : int * 00071 role : Pointeur vers la coordonne X du cdg 00072 00073 nom : y 00074 type : int * 00075 role : Pointeur vers la coordonne Y du cdg 00076 00077 FICHIER: cntcdg.c 00078 00079 EXEMPLE: 00080 ******************************************************** END DESCRIPTION */ 00081 00082 void IdCntCentreGravite(Pts, GravX, GravY) 00083 PCONTOUR_USHORT Pts; 00084 int *GravX, *GravY; 00085 { 00086 int i,xt,yt; 00087 int NbPts; 00088 00089 NbPts=IdCntUsedNbX(Pts); 00090 for(i=0, xt=0, yt=0; i<NbPts; i++) 00091 { 00092 xt += IdCntGetX(Pts,i); 00093 yt += IdCntGetY(Pts,i); 00094 } 00095 *GravX= xt/NbPts; 00096 *GravY= yt/NbPts; 00097 } 00098 00099 /* FUNCTION DESCRIPTION ************************************************** 00100 00101 IdCntRectEnglob (fonction) 00102 00103 RESUME: Calcule le Rectangle Englobant (Xmin,Ymin, Xmax, Ymax) d'un contour USHORT 00104 00105 DESCRIPTION: 00106 00107 Calcule le Rectangle Englobant (Xmin,Ymin, Xmax, Ymax) d'un contour USHORT 00108 00109 SYNTAXE: void IdCntRectEnglob (PCONTOUR_USHORT cnt, int *xmin, int *ymin, int *xmax, int *ymax); 00110 00111 RETOUR: type : viod 00112 00113 PARAMETRES: nom : cnt 00114 type : PCONTOUR_USHORT 00115 role : Pointeur vers le contour 00116 00117 nom : xmin,ymin,xmax,ymax 00118 type : int * 00119 role : Pointeur vers les coordonnees du Rectangle Englobant 00120 00121 FICHIER: cntcdg.c 00122 00123 EXEMPLE: 00124 00125 ******************************************************** END DESCRIPTION */ 00126 00127 void IdCntRectEnglob(Pts, Xmin, Ymin, Xmax, Ymax) 00128 PCONTOUR_USHORT Pts; 00129 int *Xmin, *Ymin, *Xmax, *Ymax; 00130 { 00131 int i; 00132 int NbPts; 00133 00134 NbPts=IdCntUsedNbX(Pts); 00135 *Xmin= *Ymin= 0x7FFF; /* CM au lieu de 65535 */ 00136 *Xmax= *Ymax= 0; 00137 00138 for(i=0; i<NbPts; i++) 00139 { 00140 if(IdCntGetX(Pts,i) > *Xmax) *Xmax=IdCntGetX(Pts,i); 00141 if(IdCntGetX(Pts,i) < *Xmin) *Xmin=IdCntGetX(Pts,i); 00142 if(IdCntGetY(Pts,i) > *Ymax) *Ymax=IdCntGetY(Pts,i); 00143 if(IdCntGetY(Pts,i) < *Ymin) *Ymin=IdCntGetY(Pts,i); 00144 } 00145 } 00146 00147 00148 /* FUNCTION DESCRIPTION ************************************************** 00149 00150 IdCntClean (macro) 00151 00152 RESUME: Supprime les points consecutifs identiques d'un CNT USHORT. 00153 00154 DESCRIPTION: Supprime les points consecutifs identiques d'un CNT USHORT. 00155 A l'attention des developpeurs LibIDO: 00156 On remarquera que le fait qu'il y ait une Macro derriere 00157 ne sert A RIEN ... JPRx 00158 00159 SYNTAXE: int retCode = IdCntClean(PCONTOUR_USHORT cntSource); 00160 00161 RETOUR: 00162 type : int 00163 role : code retour booleen. 00164 00165 PARAMETRES: 00166 nom : cntSource 00167 type : PCONTOUR_USHORT 00168 role : pointeur sur le contour 00169 00170 FICHIER: 00171 00172 ******************************************************** END DESCRIPTION */ 00173 int _IdCntClean(cnt1) 00174 PCONTOUR_USHORT *cnt1; 00175 { 00176 00177 int ai, bi, aj, bj; 00178 int i, j, n1, n2; 00179 00180 if (*cnt1==NULL) return 0; 00181 00182 n1 =n2= IdCntUsedNbX(*cnt1); 00183 00184 for (i=0,j=1; j < n1;j++) 00185 { 00186 ai=IdCntGetX(*cnt1, i); 00187 bi=IdCntGetY(*cnt1, i); 00188 aj=IdCntGetX(*cnt1, j); 00189 bj=IdCntGetY(*cnt1, j); 00190 if ((ai==aj) && (bi==bj)) 00191 { 00192 n2=n2-1; 00193 } 00194 else {IdCntSetX(*cnt1, i+1, aj); 00195 IdCntSetY(*cnt1, i+1, bj); 00196 i++; 00197 } 00198 } 00199 IdCntSetUsedNbX(*cnt1,n2); 00200 return (1); 00201 } 00202 00203 00204 /* FUNCTION DESCRIPTION ************************************************** 00205 00206 IdCntCleanFromStart (macro) 00207 00208 RESUME: Supprime les points consecutifs identiques d'un CNT USHORT a partir d'1 pt donne. 00209 00210 DESCRIPTION: Supprime les points consecutifs identiques d'un CNT USHORT a partir d'1 pt donne. 00211 00212 SYNTAXE: int retCode = IdCntCleanFromStart(PCONTOUR_USHORT cntSource, int startPoint); 00213 00214 RETOUR: 00215 type : int 00216 role : code retour booleen. 00217 00218 PARAMETRES: 00219 nom : cntSource 00220 type : PCONTOUR_USHORT 00221 role : pointeur sur le contour 00222 00223 nom : startPoint 00224 type : int 00225 role : point de depart 00226 00227 FICHIER: 00228 00229 ******************************************************** END DESCRIPTION */ 00230 int _IdCntCleanFromStart(cnt1,stP) 00231 PCONTOUR_USHORT *cnt1; 00232 int stP; 00233 { 00234 00235 int ai, bi, aj, bj; 00236 int i, j, n1, n2; 00237 00238 if (*cnt1==NULL) return 0; 00239 00240 n1 =n2= IdCntUsedNbX(*cnt1); 00241 00242 for (i=stP,j=stP+1; j < n1;j++) 00243 { 00244 ai=IdCntGetX(*cnt1, i); 00245 bi=IdCntGetY(*cnt1, i); 00246 aj=IdCntGetX(*cnt1, j); 00247 bj=IdCntGetY(*cnt1, j); 00248 if ((ai==aj) && (bi==bj)) 00249 { 00250 n2=n2-1; 00251 } 00252 else {IdCntSetX(*cnt1, i+1, aj); 00253 IdCntSetY(*cnt1, i+1, bj); 00254 i++; 00255 } 00256 } 00257 IdCntSetUsedNbX(*cnt1,n2); 00258 return (1); 00259 } 00260 00261 /* FUNCTION DESCRIPTION ************************************************** 00262 00263 IdCntConnexPts (Macro) 00264 00265 RESUME: Intercale des points ds un CNT USHORT pour le rendre connexe (8). 00266 00267 DESCRIPTION: Intercale des points ds un CNT USHORT pour le rendre connexe (8) 00268 Le pointeur sur contour est modifie! 00269 00270 SYNTAXE: int retCode = IdCntConnexPts(PCONTOUR_USHORT cntSource, int ferme); 00271 00272 RETOUR: 00273 type : int 00274 role : code retour booleen. 00275 00276 PARAMETRES: 00277 nom : cntSource 00278 type : PCONTOUR_USHORT 00279 role : pointeur sur le contour 00280 00281 nom : ferme 00282 type : int 00283 role : semantique du CNT (ouvert:0 ferme:1) 00284 00285 FICHIER: 00286 00287 ******************************************************** END DESCRIPTION */ 00288 00289 int _IdCntConnexPts (cnt1, ferme) 00290 PCONTOUR_USHORT *cnt1; 00291 int ferme; 00292 { 00293 00294 int ai, bi, aj = 0, bj = 0; 00295 int j, n1, retCode; 00296 PCONTOUR_USHORT cnt2; 00297 00298 if (*cnt1==NULL) return 0; 00299 00300 IdCntClean(*cnt1); 00301 00302 n1 = IdCntUsedNbX(*cnt1); 00303 if (n1==1) return 1; 00304 00305 cnt2 = IdCntAlloc(n1,CNT_USHORT); 00306 if(!cnt2) return 0; 00307 00308 ai=IdCntGetX(*cnt1,0); 00309 bi=IdCntGetY(*cnt1,0); 00310 00311 IdCntAddPoint(cnt2,ai,bi); 00312 00313 for(j=1;j<n1;j++) 00314 { 00315 aj=IdCntGetX(*cnt1,j); 00316 bj=IdCntGetY(*cnt1,j); 00317 if( (abs((int)(aj-ai))<2) && (abs((int)(bj-bi))<2) ) 00318 { IdCntAddPoint(cnt2,aj,bj); 00319 } 00320 else 00321 { 00322 retCode=IdCntAddPointsOfSegment(cnt2,ai,bi,aj,bj); 00323 if (!retCode) return 0; 00324 } 00325 ai=aj; bi=bj; 00326 } 00327 00328 if (ferme) 00329 { 00330 retCode=IdCntAddPointsOfSegment(cnt2,aj,bj, 00331 IdCntGetX(*cnt1,0),IdCntGetY(*cnt1,0)); 00332 if (!retCode) return 0; 00333 } 00334 00335 IdCntFree(*cnt1); 00336 *cnt1=cnt2; 00337 00338 return 1; 00339 } 00340 00341 /* FUNCTION DESCRIPTION ************************************************** 00342 00343 IdCntSurfacePoly (fonction) 00344 00345 RESUME: Calcule le nb de pixels a l'interieur d'un CNT USHORT. 00346 00347 DESCRIPTION: Calcule le nb de pixels a l'interieur d'un CNT USHORT. 00348 00349 SYNTAXE: double nbPixels = IdCntSurfacePoly(PCONTOUR_USHORT cntSource); 00350 00351 RETOUR: 00352 type : double 00353 role : renvoie le nb de pixels a l'interieur d'un CNT USHORT 00354 00355 PARAMETRES: 00356 nom : cntSource 00357 type : PCONTOUR_USHORT 00358 role : pointeur sur le contour 00359 00360 FICHIER: 00361 00362 ******************************************************** END DESCRIPTION */ 00363 double IdCntSurfacePoly(cntSource) 00364 PCONTOUR_USHORT cntSource; 00365 00366 { 00367 double surface=0.0; 00368 int ox,oy,fx,fy,precedent, conseq; 00369 00370 if (cntSource==NULL) return 0; 00371 00372 IdCntClean(cntSource); 00373 if (IdCntUsedNbX(cntSource)<3) return 0; 00374 00375 IdCntRectEnglob(cntSource,&ox,&oy,&fx,&fy); 00376 imtmp=(PPIMAGE_UCHAR)IdImaAlloc(fx-ox+1,fy-oy+1,IMA_UCHAR); 00377 00378 if(!imtmp) return 0; 00379 imtmp=(PPIMAGE_UCHAR)IdImaClear((PPIMAGE)imtmp); 00380 00381 IdCntDrawPolygonOffset(cntSource,ox,oy,imtmp,0,255); /* 0: trace directe */ 00382 00383 for(i=0;i<IdImaDimY(imtmp);i++) 00384 { 00385 precedent=0; 00386 flag=0; 00387 conseq=0; 00388 seul=1; 00389 for(j=0;j<IdImaDimX(imtmp);j++) 00390 { 00391 if ( imtmp[i][j] == 255 ) 00392 { 00393 surface ++; 00394 00395 if (precedent==255) 00396 { 00397 conseq=1; 00398 } 00399 else /* 1 er pt blanc */ 00400 { 00401 conseq=0; 00402 00403 if (j==0){ 00404 if(i==IdImaDimY(imtmp)-1){ if(imtmp[i][1]==0) flag=0; continue; } 00405 if(i==0) { if(imtmp[0][1]==0) flag=0; continue; } 00406 } 00407 testprec(); 00408 00409 if ((!pic) && (!ravin)) 00410 { 00411 if (seul==1){ if (flag==0) flag=1; else flag=0; } 00412 } 00413 } 00414 } 00415 00416 else /* point noir */ 00417 { 00418 if (conseq!=0) /* il y a eu +sieurs pts blancs consecutifs */ 00419 { 00420 testsuiv(); 00421 if (fourche != 1) /* sur une fourche, le flag ne bouge pas */ 00422 { 00423 if ( (supprec && infsuiv) || (infprec && supsuiv) ) { 00424 if (flag==0) flag=1; else flag=0; 00425 } 00426 } 00427 } 00428 if (flag==1) { surface ++; 00429 } 00430 conseq=0; 00431 } 00432 precedent=imtmp[i][j]; 00433 } 00434 } 00435 return surface; 00436 } 00437 00438 /* FUNCTION DESCRIPTION ************************************************** 00439 00440 IdCntFillExtPolygon (fonction) 00441 00442 RESUME: Rempli sur une image UCHAR l'exterieur d'un CNT USHORT (polygone qcq). 00443 00444 DESCRIPTION: Rempli sur une image UCHAR l'exterieur d'un CNT USHORT (polygone qcq) 00445 00446 SYNTAXE: int retCode = IdCntFillExtPolygon(PCONTOUR_USHORT cntSource, PPIMAGE_UCHAR im, int nivGris); 00447 00448 RETOUR: 00449 type : int 00450 role : code de retour booleen. 00451 00452 PARAMETRES: 00453 nom : cntSource 00454 type : PCONTOUR_USHORT 00455 role : pointeur sur le contour 00456 00457 nom : im 00458 type : PPIMAGE_UCHAR 00459 role : pointeur sur l'image 00460 00461 nom : nivGris 00462 type : int 00463 role : niveau de gris de remplissage 00464 00465 FICHIER: 00466 00467 ******************************************************** END DESCRIPTION */ 00468 00469 int IdCntFillExtPolygon(cntSource, im, nivGris) 00470 PCONTOUR_USHORT cntSource; 00471 PPIMAGE_UCHAR im; 00472 int nivGris; 00473 { 00474 PPIMAGE_UCHAR im2; 00475 00476 im2=(PPIMAGE_UCHAR)IdImaAllocLikeImage(im); 00477 if(!im2) return (0); 00478 IdImaClear((PPIMAGE)im2); 00479 IdCntFillPolygon(cntSource, im2, 255); 00480 for(i=0;i<IdImaDimY(im2);i++) 00481 for(j=0;j<IdImaDimX(im2);j++) 00482 if ( im2[i][j] == 0 ) 00483 im[i][j]= nivGris; 00484 return(1); 00485 00486 } 00487 00488 /* FUNCTION DESCRIPTION ************************************************** 00489 00490 IdCntFillPolygon (fonction) 00491 00492 RESUME: Rempli sur une image UCHAR l'interieur d'un CNT USHORT (polygone qcq). 00493 00494 DESCRIPTION: Rempli sur une image UCHAR l'interieur d'un CNT USHORT (polygone qcq) 00495 00496 SYNTAXE: int retCode = IdCntFillPolygon(PCONTOUR_USHORT cntSource, PPIMAGE_UCHAR im, int nivGris); 00497 00498 RETOUR: 00499 type : int 00500 role : code de retour booleen. 00501 00502 PARAMETRES: 00503 nom : cntSource 00504 type : PCONTOUR_USHORT 00505 role : pointeur sur le contour 00506 00507 nom : im 00508 type : PPIMAGE_UCHAR 00509 role : pointeur sur l'image 00510 00511 nom : nivGris 00512 type : int 00513 role : niveau de gris de remplissage 00514 00515 FICHIER: 00516 00517 ******************************************************** END DESCRIPTION */ 00518 int IdCntFillPolygon(cntSource, im, nivGris) 00519 PCONTOUR_USHORT cntSource; 00520 PPIMAGE_UCHAR im; 00521 int nivGris; 00522 { 00523 00524 if (cntSource==NULL) return 0; 00525 if (im==NULL) return 0; 00526 00527 IdCntClean(cntSource); 00528 if (IdCntUsedNbX(cntSource)<3) return 0; 00529 00530 imtmp=(PPIMAGE_UCHAR)IdImaAllocLikeImage(im); 00531 00532 if(!imtmp) return 0; 00533 imtmp=(PPIMAGE_UCHAR)IdImaClear((PPIMAGE)imtmp); 00534 00535 00536 IdCntDrawPolygon(cntSource,imtmp,0,255); /* 0: trace directe */ 00537 00538 IdImaFill(imtmp,imtmp,1); /* JPR */ 00539 00540 for(i=0;i<IdImaDimY(im);i++)for(j=0;j<IdImaDimX(im);j++) 00541 00542 if(imtmp[i][j]==255)im[i][j]=nivGris; 00543 00544 /*if(imtmp[i][j]==0)im[i][j]=nivGris; */ /* GROS pb JPRx */ 00545 00546 IdImaFree(imtmp); /* JPR */ 00547 00548 return (1); 00549 00550 } 00551 00552 /* ********************************************************************** */ 00553 00554 00555 int IdCntFillPolygonXXX(PCONTOUR_USHORT cntSource, PPIMAGE_UCHAR im, int nivGris) 00556 { 00557 int ox,oy,fx,fy; 00558 int precedent, conseq; 00559 00560 if (cntSource==NULL) return 0; 00561 if (im==NULL) return 0; 00562 00563 IdCntClean(cntSource); 00564 if (IdCntUsedNbX(cntSource)<3) return 0; 00565 00566 IdCntRectEnglob(cntSource,&ox,&oy,&fx,&fy); 00567 imtmp=(PPIMAGE_UCHAR)IdImaAlloc(fx-ox+1,fy-oy+1,IMA_UCHAR); 00568 00569 if(!imtmp) return 0; 00570 imtmp=(PPIMAGE_UCHAR)IdImaClear((PPIMAGE)imtmp); 00571 00572 IdCntDrawPolygonOffset(cntSource,ox,oy,imtmp,0,255); /* 0: trace directe */ 00573 00574 for(i=0;i<IdImaDimY(imtmp);i++) 00575 { 00576 precedent=0; 00577 flag=0; 00578 conseq=0; 00579 seul=1; 00580 for(j=0;j<IdImaDimX(imtmp);j++) 00581 { 00582 if ( imtmp[i][j] == 255 ) 00583 { 00584 im[i+oy][j+ox]= nivGris; 00585 00586 if (precedent==255) 00587 { 00588 conseq=1; 00589 } 00590 else /* 1 er pt blanc */ 00591 { 00592 conseq=0; 00593 00594 if (j==0){ 00595 if(i==IdImaDimY(imtmp)-1){ if(imtmp[i][1]==0) flag=0; continue; } 00596 if(i==0) { if(imtmp[0][1]==0) flag=0; continue; } 00597 } 00598 testprec(); 00599 00600 if ((!pic) && (!ravin)) 00601 { 00602 if (seul==1) {if (flag==0) flag=1; else flag=0; } 00603 } 00604 } 00605 } 00606 00607 else /* point noir */ 00608 { 00609 if (conseq!=0) /* il y a eu +sieurs pts blancs consecutifs */ 00610 { 00611 testsuiv(); 00612 if (fourche != 1) /* sur une fourche, le flag ne bouge pas */ 00613 { 00614 if ( (supprec && infsuiv) || (infprec && supsuiv) ) 00615 { 00616 if (flag==0) flag=1; else flag=0; 00617 } 00618 } 00619 00620 } 00621 if (flag==1) { im[i+oy][j+ox]= nivGris; 00622 } 00623 conseq=0; 00624 } 00625 precedent=imtmp[i][j]; 00626 } 00627 } 00628 return 1; 00629 } 00630 00631 /* ===================================================================================================== */ 00632 00633 static void testprec() 00634 { 00635 pic=ravin=infprec=supprec=0; 00636 seul=1; 00637 00638 if (j !=IdImaDimX(imtmp)-2) if (imtmp[i][j+1]==255) seul=0; 00639 00640 if (i==0) 00641 { 00642 if (imtmp[0][j+1]==0) { pic=1; ravin=0;if(imtmp[1][j]==255) imtmp[0][j]=0; } else { infprec=1; supprec=0;} 00643 } 00644 00645 else if (i==IdImaDimY(imtmp)-1) 00646 { 00647 if (imtmp[i][j+1]==0) { pic=0; ravin=1; } else { infprec=0; supprec=1;} 00648 } 00649 00650 else if (j==0) /* premiere colonne */ 00651 00652 { 00653 if ( (imtmp[i-1][j]==0) && (imtmp[i-1][j+1]==0) && (imtmp[i][j+1]==0) ) 00654 { pic=1; if(imtmp[i+1][j]==255) imtmp[i][j]=0; } 00655 00656 else if ( (imtmp[i+1][j]==0) && (imtmp[i+1][j+1]==0) && (imtmp[i][j+1]==0) ) 00657 { ravin=1;} 00658 00659 else if ( ( (imtmp[i-1][j]==255) || (imtmp[i-1][j+1]==255)) && (imtmp[i+1][j+1]==0) ) 00660 { supprec=1; } 00661 00662 else if ( imtmp[i+1][j]==255 ) 00663 { infprec=1; } 00664 return; 00665 } 00666 00667 /* autres colonnes */ 00668 else { 00669 if ( (imtmp[i-1][j-1]==0) && (imtmp[i-1][j]==0) && (imtmp[i-1][j+1]==0) && (imtmp[i][j+1]==0) ) 00670 { pic=1; if(imtmp[i+1][j]==255) imtmp[i][j]=0; } 00671 00672 else if ( (imtmp[i+1][j-1]==0) && (imtmp[i+1][j]==0) && (imtmp[i+1][j+1]==0) && (imtmp[i][j+1]==0) ) 00673 { ravin=1;} 00674 00675 else if ( ((imtmp[i-1][j-1]==255) || (imtmp[i-1][j]==255) || (imtmp[i-1][j+1]==255)) && (imtmp[i+1][j+1]==0) ) 00676 { supprec=1; } 00677 00678 else if ( ((imtmp[i+1][j-1]==255) || (imtmp[i+1][j]==255) || (imtmp[i+1][j-1]==255)) && (imtmp[i-1][j-1]==0) ) 00679 { infprec=1; } 00680 } 00681 00682 return; 00683 00684 } 00685 00686 static void testsuiv() 00687 { 00688 fourche=supsuiv=infsuiv=0; 00689 00690 if (i==0) { infsuiv=1; } 00691 00692 else if (i==IdImaDimY(imtmp)-1) { supsuiv=1; } 00693 00694 else if (j==IdImaDimX(imtmp)-1) 00695 { if ( (imtmp[i-1][j-1]==255) || (imtmp[i-1][j]==255)) { supsuiv=1;} 00696 else if ( (imtmp[i+1][j-1]==255) || (imtmp[i+1][j]==255)) { infsuiv=1;} 00697 } 00698 00699 else 00700 { if ( (imtmp[i-1][j+1]==0) && ((imtmp[i+1][j+1]==255) || (imtmp[i+1][j]==255)) ) 00701 { infsuiv=1; } 00702 if ( (imtmp[i+1][j+1]==0) && ((imtmp[i-1][j+1]==255) || (imtmp[i-1][j]==255)) ) 00703 { supsuiv=1; } 00704 00705 if ( ((imtmp[i-1][j-1]==255) || (imtmp[i-1][j]==255)) 00706 && ((imtmp[i+1][j-1]==255) || (imtmp[i+1][j]==255)) ) 00707 { fourche=1;} 00708 } 00709 return; 00710 } 00711 00712 /* FUNCTION DESCRIPTION ************************************************** 00713 00714 IdImaFillContour (fonction) 00715 00716 RESUME: Rempli dans une image UCHAR l'interieur de contours a 255. 00717 00718 DESCRIPTION: Rempli dans une image UCHAR l'interieur de contours a 255 00719 00720 SYNTAXE: int retCode = IdImaFillContour(PPIMAGE_UCHAR im, int nivGris); 00721 00722 RETOUR: 00723 type : int 00724 role : code de retour booleen. 00725 00726 PARAMETRES: 00727 nom : im 00728 type : PPIMAGE_UCHAR 00729 role : pointeur sur l'image 00730 00731 nom : nivGris 00732 type : int 00733 role : niveau de gris de remplissage 00734 00735 FICHIER: 00736 00737 ******************************************************** END DESCRIPTION */ 00738 00739 int IdImaFillContour(PPIMAGE_UCHAR im, int nivGris) 00740 { 00741 int precedent, conseq; 00742 00743 if (im==NULL) return 0; 00744 00745 imtmp=(PPIMAGE_UCHAR)IdImaAllocLikeImage(im); 00746 00747 if(!imtmp) return 0; 00748 imtmp=(PPIMAGE_UCHAR)IdImaClear((PPIMAGE)imtmp); 00749 00750 for(i=0;i<IdImaDimY(im);i++)for(j=0;j<IdImaDimY(im);j++) if (im[i][j]==255) imtmp[i][j]=255; 00751 00752 for(i=0;i<IdImaDimY(imtmp);i++) 00753 { 00754 precedent=0; 00755 flag=0; 00756 conseq=0; 00757 seul=1; 00758 for(j=0;j<IdImaDimX(imtmp);j++) 00759 { 00760 if ( imtmp[i][j] == 255 ) 00761 { 00762 im[i][j]= nivGris; 00763 00764 if (precedent==255) 00765 { 00766 conseq=1; 00767 } 00768 else /* 1 er pt blanc */ 00769 { 00770 conseq=0; 00771 00772 if (j==0){ 00773 if(i==IdImaDimY(imtmp)-1){ if(imtmp[i][1]==0) flag=0; continue; } 00774 if(i==0) { if(imtmp[0][1]==0) flag=0; continue; } 00775 } 00776 testprec(); 00777 00778 if ((!pic) && (!ravin)) 00779 { 00780 if (seul==1) 00781 { 00782 if (flag==0) flag=1; else flag=0; 00783 } 00784 } 00785 } 00786 } 00787 00788 else /* point noir */ 00789 { 00790 if (conseq!=0) /* il y a eu +sieurs pts blancs consecutifs */ 00791 { 00792 testsuiv(); 00793 if (fourche != 1) /* sur une fourche, le flag ne bouge pas */ 00794 { 00795 if ( (supprec && infsuiv) || (infprec && supsuiv) ) 00796 { 00797 if (flag==0) flag=1; else flag=0; 00798 } 00799 } 00800 00801 } 00802 if (flag==1) { im[i][j]= nivGris; 00803 } 00804 conseq=0; 00805 } 00806 precedent=imtmp[i][j]; 00807 } 00808 } 00809 return 1; 00810 } 00811

Generated on Wed Oct 19 09:28:32 2005 for SIMRI3D by doxygen 1.3.7