| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610 |
- /*******************************************************************\
- Fichier : EIMBase.cpp
- Date : 29/04/98
- Version : 1.024
- Auteur : P-J Touboul
- Description : Fonctions de d�tection et mesures de parois
- |*******************************************************************|
- Bugs:
- Il serait plus propre dans la fonction EIM, d'appliquer le masque
- sur le vecteur (proc�dure Mask mise en commentaire).
- Notes:
- |*******************************************************************|
- Historique :
- 29/04/98 1.024 : Modification du sens de la mesure en fonction de la position relative
- des points du segment utilisateur
- M�morisation de la distance de la mesure
- 02/04/98 1.022 : Utilisation d'une valeur minimale permettant de consid�rer qu'il
- y a une variation de densit� (STEP)
- Bug quand il y a avait UN SEUL lissage effectu�
- 11/03/98 1.020 : Nouvel algorithme possible pour la mesure de diam�tre (sym�trie)
- 31/01/98 1.010 : Mesures 'sub-pixels' permettant de gagner jusqu'� un pixel
- en pr�cision (1/2 pixel avant + 1/2 pixel apr�s). Les points
- au milieu des pentes ont donc defs coordonn�es d�cimales
- Correction d'un probl�me sur la d�tection de plateaux
- 22/01/98 1.001 : Correction sur le calcul des points m�dians
- Ajout de la position des points m�dians
- 17/03/97 1.000 : Premi�re version
- \*******************************************************************/
- /*----------------------------------------------------------\
- Includes
- \----------------------------------------------------------*/
- #include "EIMBase.h"
- #include "MeanEstimate.h"
- #include "CEIMResult.h"
- #include "EIMResult.h"
- #include "Ressource.h"
- #include "point.h"
- #include "ToolsMath.h"
- //#include "../Container/ExtendedImage.h"
- #include <limits>
- #include <string.h>
- #include <QImage>
- //#define TEST_FOR_FANTOME
- /*----------------------------------------------------------\
- Defines
- \----------------------------------------------------------*/
- #define STEP 0
- /*----------------------------------------------------------\
- Variables locales
- \----------------------------------------------------------*/
- //static char Version[] = "$VER: " __FILE__ " 1.024 (" __DATE__ ")";
- /*----------------------------------------------------------\
- | Delta |
- \----------------------------------------------------------*/
- char CEIMBase::Delta (unsigned char b1, unsigned char b2)
- {
- int i;
- // En utilisant STEP, on consid�re par exemple que 15/16/17 repr�sentent
- // la m�me valeur et que ce n'est donc pas une croissance
- i = b1 - b2;
- if (i > STEP) return ( 1);
- else if (i < -STEP) return (-1);
- else return ( 0);
- } // end of Delta
- /*----------------------------------------------------------\
- | CEIM::CEIM |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Constructeur de la classe |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | scale : �chelle � utiliser pour les mesures |
- \----------------------------------------------------------*/
- CEIMBase::CEIMBase (void)
- {
- //debugOutput = NULL;
- m_pMeasures = NULL;
- m_bDelta1 = 30; // variation minimale pour la premi�re pente
- m_bDelta2 = 10; // variation minimale entre le sommet des deux pentes // A voir Release
- m_bSeuil1 = 140;
- m_algoDiameter = algoProfile; // algorithme par d�faut
- m_arVariance.clear();
- m_arVarianceAA.clear();
- m_arVarianceII.clear();
- m_arVarianceINT.clear();
- Release(); // apr�s m_pMeasures = NULL;
- m_coeff_a = -1.0;
- m_coeff_b = -1.0;
- m_coeff_c = -1.0;
- m_bDisplay = false;
- m_parallelismeDiametre = false; // Exp�rimental
- m_image = NULL;
- m_versionTomtecAout08 = true;
- } // fin de CEIM
- CEIMBase::~CEIMBase(void)
- {
- Release();
- } // fin de ~CEIM
- void CEIMBase::SetEimAssisted(bool valide)
- {
- m_Assist = valide;
- }
- bool CEIMBase::GetEimAssisted()
- {
- return m_Assist;
- }
- // Calcul automatique de l'EIM
- // Ancienne version : n'est plus utilis�e
- int CEIMBase::CalculEimAutomatique(int mode, bool bActionDiametre, Point *ptClick0, Point *ptClick1, Point *ptLastClick, unsigned char *bClicks, QImage *img,bool *fBackToNone)
- {
- m_image = img;
- return CalculEimAutomatique( mode, bActionDiametre, ptClick0, ptClick1, ptLastClick, bClicks, fBackToNone );
- }
- int CEIMBase::CalculEimAutomatique(int mode, bool bActionDiametre, Point *ptClick0, Point *ptClick1, Point *ptLastClick, unsigned char *bClicks, bool *fBackToNone)
- {
- int retour = 0;
-
- if (m_Assist)
- {
- if (mode == 0)
- {
- Measure(*ptClick0, *ptLastClick, bActionDiametre);
- }
- double dDirection = Direction();
- if (dDirection == 0)
- {
- //CMessage::Warn(MyLoadString(IDS_EIM_FAILED));
- *fBackToNone = false;
- return 0;
- }
- else
- {
- Point CorrectPoint = *ptLastClick;
- CorrectPoint.y = ptClick0->y + ((long) (dDirection*(CorrectPoint.x - ptClick0->x)));
- *ptClick1 = CorrectPoint;
- *bClicks = 1;
- retour = 1; // Pour lancer un Invalidate
-
- if (mode == 1)
- {
- Measure(*ptClick0, CorrectPoint, bActionDiametre);
- }
- *ptLastClick = CorrectPoint;
- }
- }
-
- return retour;
- }
- bool CEIMBase::PointInBuffer(const Point& pt)
- {
- assert( m_image );
- int dx = m_image->width();
- int dy = m_image->height();
- return ( pt.x >= 0 && pt.y >= 0 && pt.x < dx && pt.y < dy );
- }
- unsigned char CEIMBase::GetIntensity(const Point& pt)
- {
- assert( m_image );
- return qGray(m_image->pixel( pt.x, pt.y ));
- }
- /*----------------------------------------------------------\
- | Release |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Lib�re les ressources allou�es pour une mesure |
- \----------------------------------------------------------*/
- void CEIMBase::Release (void)
- {
- m_dblEIMMin =
- m_dblEIMMean =
- m_dblEIMMax =
- m_dblINTMin =
- m_dblINTMean =
- m_dblINTMax =
- m_dblDiaAAMin =
- m_dblDiaAAMean =
- m_dblDiaAAMax =
- m_dblDiaIIMin =
- m_dblDiaIIMean =
- m_dblDiaIIMax =
- m_dblQI =
- m_dblQIMean =
- m_dblIA =
- m_dblEIMdMean =
- m_dblINTdMean =
- m_dblMEDdMean =
- m_dblIAd =
- m_dblVariance =
- m_dblDistance = 0.0;
- m_dwPoints = // nombre de points sur lesquels une mesure a �t� effectu�e
- m_dwValidPoints = // nombre de points sur lesquels le profil a �t� reconnu
- m_uErrorID = 0; // ID de la cha�ne d�crivant l'erreur
- if (m_pMeasures)
- {
- delete [] m_pMeasures;
- m_pMeasures = NULL;
- }
- m_StartPoint.x = -1;
- m_StartPoint.y = -1;
- m_EndPoint.x = -1;
- m_EndPoint.x = -1;
- memset( m_bBuffer, 0, THICKNESS );
- memset( m_cOffsets, 0, THICKNESS );
- } // fin de Release
- /*----------------------------------------------------------\
- | Measure |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Mesure d'une �paisseur de paroi ou d'un diam�tre |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | gfx : image en niveau de gris d'o� lire les |
- | donn�es |
- | pGraphMean : graphe dans lequel ajout� les mesures si |
- | non nul |
- | pt1 : premier point du segment d�terminant la |
- | ligne de la paroi |
- | pt2 : deuxi�me point du segment |
- | fDiameter : mesure d'un diam�re ou d'une paroi |
- |-----------------------------------------------------------|
- | RETOURNE : |
- | VRAI si au moins une mesure a �t� effectu�e |
- \----------------------------------------------------------*/
- bool CEIMBase::Measure(
- QImage *h_image,
- const Point &point1,
- const Point &point2,
- bool fDiameter,
- CEIMResult *m_res)
- {
- m_image = h_image;
- return Measure( point1, point2, fDiameter, m_res );
- }
- bool CEIMBase::Measure (
- const Point &point1,
- const Point &point2,
- bool fDiameter,
- CEIMResult *m_res
- )
- {
- Point point3, point4;
- // En fonction de la position du premier point, on d�termine le c�t� d'analyse
- m_fDiameter = fDiameter;
- Release ();
- if (point1.x > point2.x)
- {
- m_bNearWall = true;
- m_vUser = CVector(point2, point1);
- if (!fDiameter)
- {
- m_StartPoint = point2;
- m_EndPoint = point1;
- }
- }
- else
- {
- m_bNearWall = false;
- m_vUser = CVector(point1, point2); // pour imposer le calcul de gauche � droite pour
- // le diam�tre et la distensibilit� m�me si le trac�
- // se fait de droite � gauche.
- if (!fDiameter)
- {
- m_StartPoint = point1;
- m_EndPoint = point2;
- }
- }
- m_minx_curve = std::numeric_limits< int >::max();
- m_max_curve = 0;
- /*
- if ((m_Assist) && (!fDiameter))
- {
- // CJ 2007 : Allongement auto de la distance � 10 mm
- dpoint pta, ptb, s1, s2, ptc;
- const long x1 = 0;
- pta.x = point1.x;
- pta.y = point1.y;
- ptb.x = point2.x;
- ptb.y = point2.y;
- if (point1.x < point2.x)
- {
- if (InterCercleDroite(pta, 10.0 / g_pCurrentScale->DistanceX(1L), pta, ptb, &s1, &s2))
- {
- ptc = leplusproche(ptb, s1, s2);
- point3.x = (int) pta.x;
- point3.y = (int) pta.y;
- point4.x = (int) ptc.x;
- point4.y = (int) ptc.y;
- }
- #ifndef NEW_EIM
- m_vUser = CVector (point3, point4);
- #else
- if (point3.x <= point4.x)
- {
- m_vUser = CVector (point3, point4);
- m_StartPoint = point3;
- m_EndPoint = point4;
- }
- else
- {
- m_vUser = CVector (point4, point3);
- m_StartPoint = point4;
- m_EndPoint = point3;
- }
-
- if (point4.x > point3.x)
- {
- m_max_curve = point4.x;
- }
- else
- {
- m_max_curve = point3.x;
- }
- if (point3.x < point4.x)
- {
- m_minx_curve = point3.x;
- }
- else
- {
- m_minx_curve = point4.x;
- }
- #endif
- }
- }
- */
- if (m_vUser.Nul ())
- {
- m_uErrorID = IDS_EIM_INVALID;
- return (false);
- }
- else
- {
- // CWaitCursor wait;
- m_dwPoints = m_vUser.Length () + 1;
- m_pMeasures = new CEIMInfo [m_dwPoints];
- memset (m_pMeasures, 0, sizeof (CEIMInfo) * m_dwPoints);
- // pour un algo plut�t bas� sur la proximit� de la droite par
- // rapport � la paroi potentielle la plus proche voir fichier EIM/AvecSeuil.cpp
- // comme le point de d�part de vecteur � toujours une abscisse inf�rieure au point d'arriv�e
- // la direction � donner � Orthogonal est 0. Voir algo de Orthogonal pour comprendre
-
- if (!m_bNearWall)
- {
- m_indexParoi = 0;
- m_Max_Alignement = 8;
- }
- else
- {
- m_indexParoi = 1;
- m_Max_Alignement = 20;
- }
- if (fDiameter)
- {
- Diameter();
- }
- else
- {
- #ifdef NEW_EIM
- if (!m_Assist)
- #else
- // if ((m_Assist) && (!fDiameter))
- {
- }
- // else
- #endif
- {
- m_vUser = CVector (point1, point2);
- }
- Paroi();
- }
- }
- Update (m_res);
- return (Valid ());
- } // fin de Measure
- /*----------------------------------------------------------\
- | ParallelismeEIM |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Fonction de calcul du parall�lisme du trait utilisateur |
- | Par rapport � la paroi
- | Pour le calcul de l'EIM |
- \----------------------------------------------------------*/
- void CEIMBase::ParallelismeEIM()
- {
- long dwPos, dwMin;
- long dwPos2;
- CEIMInfo *pInfo = &m_pMeasures[0];
- dpoint tpoints[MAX_POINTS_EIM_AUTO];
- int tContinueGauche[MAX_POINTS_EIM_AUTO];
- int tContinueDroite[MAX_POINTS_EIM_AUTO];
- int tContinue[MAX_POINTS_EIM_AUTO];
- int tContinue2[MAX_POINTS_EIM_AUTO];
- dpoint pta, ptb, ptc, ptd, pte, ptf, s1, s2;
- double dist_etalon, dist_etalon2, dist;
- int cptValid, cptNonValid;
- dpoint tabPointsValides[128];
- dpoint pts;
- bool bDebut = false;
- for (int i = 0; i < MAX_POINTS_EIM_AUTO; i++)
- {
- tContinueGauche[i] = 0;
- tContinueDroite[i] = 0;
- tContinue[i] = 0;
- tContinue2[i] = 0;
- }
- // 2�me passe : On enl�ve les outliers : En allant de gauche � droite
- dwMin = long (-1);
- pInfo = &m_pMeasures[0];
- cptValid = 0;
- cptNonValid = 0;
- // double dist2, dist3;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (pInfo->m_fValid == true)
- {
- pts.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- pts.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- if ((pts.x != 0) && (pts.y != 0))
- {
- // V�rification de l'alignement
- if (cptValid >= m_Max_Alignement)
- {
- // Estimation droite � partir de tabPointsValides
- double ka, kb;
- RegressionLineaire(m_Max_Alignement, tabPointsValides, &ka, &kb);
- // Calcul de la distance orthogonale entre la droite et pts
- dpoint ptk, ptl, ptr;
- ptk.x = pts.x;
- ptk.y = ka * pts.x + kb;
- ptl.x = pts.x + 10;
- ptl.y = ka * ptl.x + kb;
- dist = distanceOrthPtDroite(pts, ptk, ptl, &ptr);
- if (dist < 3) // Si la distance est < � n pixels
- {
- cptNonValid = 0; // On remet le compteur � 0
- // Ce point est OK, on le garde
- // Remise � jour du tableau des points
- for (int i = 0; i < m_Max_Alignement-1; i++)
- {
- tabPointsValides[i].x = tabPointsValides[i+1].x;
- tabPointsValides[i].y = tabPointsValides[i+1].y;
- }
- tabPointsValides[m_Max_Alignement-1].x = pts.x;
- tabPointsValides[m_Max_Alignement-1].y = pts.y;
- tContinueGauche[dwPos] = 1;
- }
- else
- {
- cptNonValid++; // Nb de points non valides � la suite
- }
- // Si un nombre de points non valides suffisant a �t� d�tect� � la suite
- if (cptNonValid >= m_Max_Alignement - 1)
- {
- // On remet � 0 le tableau des valeurs
- for (int i = 0; i < m_Max_Alignement-1; i++)
- {
- tabPointsValides[i].x = 0;
- tabPointsValides[i].y = 0;
- }
- cptValid = 0; // On redemande un remplissage
- cptNonValid = 0;
- }
- }
- else
- {
- tabPointsValides[0].x = pInfo->m_Paroi[m_indexParoi].m_slope[2].m_ptDraw.x;
- tabPointsValides[0].y = pInfo->m_Paroi[m_indexParoi].m_slope[2].m_ptDraw.y;
- cptValid++;
- }
- }
- }
- pInfo++;
- }
-
- // Puis de droite � gauche
- pInfo = &m_pMeasures[m_dwPoints-1];
- cptValid = 0;
- cptNonValid = 0;
- bDebut = false;
- for (dwPos = m_dwPoints-1; dwPos > 0; dwPos--)
- {
- if (pInfo->m_fValid == true)
- {
- pts.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- pts.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- if ((pts.x != 0) && (pts.y != 0))
- {
- // V�rification de l'alignement
- if (cptValid >= m_Max_Alignement)
- {
- // Estimation droite � partir de tabPointsValides
- double ka, kb;
- RegressionLineaire(m_Max_Alignement, tabPointsValides, &ka, &kb);
- // Calcul de la distance orthogonale entre la droite et pts
- dpoint ptk, ptl, ptr;
- ptk.x = pts.x;
- ptk.y = ka * pts.x + kb;
- ptl.x = pts.x + 10;
- ptl.y = ka * ptl.x + kb;
- dist = distanceOrthPtDroite(pts, ptk, ptl, &ptr);
- if (dist < 3) // Si la distance est < � x pixels
- {
- cptNonValid = 0; // On remet le compteur � 0
- // Ce point est OK, on le garde
- // Remise � jour du tableau des points
- for (int i = 0; i < m_Max_Alignement-1; i++)
- {
- tabPointsValides[i].x = tabPointsValides[i+1].x;
- tabPointsValides[i].y = tabPointsValides[i+1].y;
- }
- tabPointsValides[m_Max_Alignement-1].x = pts.x;
- tabPointsValides[m_Max_Alignement-1].y = pts.y;
- tContinueDroite[dwPos] = 1;
- }
- else
- {
- cptNonValid++; // Nb de points non valides � la suite
- }
- // Si un nombre de points non valides suffisant a �t� d�tect� � la suite
- if (cptNonValid >= m_Max_Alignement - 1)
- {
- // On remet � 0 le tableau des valeurs
- for (int i = 0; i < m_Max_Alignement-1; i++)
- {
- tabPointsValides[i].x = 0;
- tabPointsValides[i].y = 0;
- }
- cptNonValid = 0;
- cptValid = 0; // On redemande un remplissage
- }
- }
- else
- {
- tabPointsValides[cptValid].x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- tabPointsValides[cptValid].y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- cptValid++;
- }
- }
- }
- pInfo--;
- }
- pInfo = &m_pMeasures[0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (pInfo->m_fValid == true)
- {
- if ((tContinueGauche[dwPos] == 1) || (tContinueDroite[dwPos] == 1))
- {
- tContinue[dwPos] = 1;
- }
- }
- tContinue2[dwPos] = tContinue[dwPos];
- pInfo++;
- }
- bool bNonContinue = false;
- int cptNonContinue = 0;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (tContinue2[dwPos] == 1)
- {
- cptNonContinue = 0;
- }
- else if (tContinue2[dwPos] == 0)
- {
- cptNonContinue++;
- bNonContinue = true;
- }
- // 1- On faits rejoindre les segments si l'�cart est faible (sur front montant)
- if ((tContinue2[dwPos] == 1) && bNonContinue)
- {
- bNonContinue = false;
- if (cptNonContinue < 3*m_Max_Alignement)
- {
- // Dans ce cas on peut rejoindre les 2 segments
- for (dwPos2 = dwPos - 3*m_Max_Alignement; dwPos2 < dwPos; dwPos2++)
- {
- if (dwPos2 >= 0)
- {
- tContinue2[dwPos2] = 1;
- }
- }
- }
- }
- }
- int indexSegments = 0;
- bNonContinue = true;
- int maxSegment = 0;
- int longueurSegment = 0;
- int indexMaxSegment = 1;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (tContinue2[dwPos] == 0)
- {
- bNonContinue = true;
- }
- if ((tContinue2[dwPos] == 1) && bNonContinue)
- {
- indexSegments++;
- bNonContinue = false;
- longueurSegment = 0;
- }
- // 2 - On num�rote chacun des segments
- if (tContinue2[dwPos] == 1)
- {
- tContinue2[dwPos] = indexSegments;
- longueurSegment++;
- if (longueurSegment > maxSegment)
- {
- maxSegment = longueurSegment;
- indexMaxSegment = indexSegments;
- }
- }
- }
- // 3 - Si plus de 1 segment on regarde celui qui est le plus grand
- if (indexSegments > 1)
- {
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (tContinue2[dwPos] != indexMaxSegment)
- {
- // 4- On efface les traits continus des segments qui ne sont pas le plus long
- tContinue[dwPos] = 0;
- }
- }
- }
- dwMin = long (-1);
- pInfo = &m_pMeasures[0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- pInfo->m_fValid = (tContinue[dwPos] == 1);
- pInfo++;
- }
- dwMin = long (-1);
- pInfo = &m_pMeasures[0];
- dist_etalon = 0;
- dist_etalon2 = 0;
- m_nbpoints_curve = 0;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (pInfo->m_fValid == true)
- {
- // Au premier point on m�morise la valeur de la distance qui va servir d'�talon pour les autres points
- pta.x = m_vUser[dwPos].x;
- pta.y = m_vUser[dwPos].y;
- ptb.x = pInfo->m_Paroi[0].m_slope[2].m_ptMiddle.x;
- ptb.y = pInfo->m_Paroi[0].m_slope[2].m_ptMiddle.y;
- pte.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- pte.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- ptf.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- ptf.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- if (m_nbpoints_curve == 0)
- {
- dist_etalon = distance(pta, ptb);
- dist_etalon2 = distance(pta, pte);
- tpoints[0].x = m_vUser[dwPos].x;
- tpoints[0].y = m_vUser[dwPos].y;
- m_nbpoints_curve++;
- }
- else
- {
- bool outOfImage;
- outOfImage = false;
- // Intersection entre le cercle centr� sur ptb de rayon dist_etalon, et la droite pta, ptb
- if (InterCercleDroite(ptb, dist_etalon, pta, ptb, &s1, &s2))
- {
- // Renvoie le point le plus proche de pta
- // Qui va �tre le nouveau point
- ptc = leplusproche(pta, s1, s2);
-
- dist = distance(ptc, pta);
- // Contre les bugs aux extr�mit�s des images
- if (dist <= (2 * dist_etalon))
- //if ((ptc.x <= m_rectCadre.GetRight()) && (ptc.x >= m_rectCadre.GetLeft()))
- {
- tpoints[m_nbpoints_curve].x = ptc.x;
- tpoints[m_nbpoints_curve].y = ptc.y;
- }
- else
- {
- outOfImage = true;
- }
- }
- else
- {
- tpoints[m_nbpoints_curve].x = m_vUser[dwPos].x;
- tpoints[m_nbpoints_curve].y = m_vUser[dwPos].y;
- }
- if (!outOfImage)
- {
- m_nbpoints_curve++;
- }
- }
- }
- pInfo++;
- }
- moindres_carres_parabole(m_nbpoints_curve, tpoints, &m_coeff_a, &m_coeff_b, &m_coeff_c);
- CVector vPerp;
- Point point1, point2, point3;
- // On recalcul l'EIM, en utilisant cette fois les perpendiculaires � la courbe obtenue
- dwMin = long (-1);
- int i;
- i = 0;
- pInfo = &m_pMeasures[0];
- bool bDistDeb;
- bDistDeb = false;
- double ka, kb;
- bDebut = false;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (pInfo->m_fValid == true)
- {
- pta.x = tpoints[i].x;
- pta.y = tpoints[i].y;
- // La tangente (d�riv�e) de y = ax2 + b x + c est y = 2ax + b
- // Le coefficient directeur de la perpendiculaire � la tangente est -1/b
- // Pour la perpendiculaire qui passe par pta.x, pta.y, y = ka x + kb
- if (m_coeff_b != 0)
- {
- ka = (double) -1.0 / (2 * m_coeff_a);
- }
- else
- {
- ka = 0.0;
- }
- kb = pta.y - ka * pta.x;
- ptb.y = tpoints[i].y + 2 * dist_etalon;
- if (ka != 0)
- {
- ptb.x = (ptb.y - kb) / ka;
- }
- else
- {
- ptb.x = tpoints[i].x;
- }
- // Intersection entre le cercle centr� sur pta de rayon dist_etalon, et la droite pta, ptb
- bool bInter = InterCercleDroite(pta, 2 * dist_etalon2, pta, ptb, &s1, &s2);
- if (bInter)
- {
- if (m_bNearWall)
- {
- if (s1.y <= s2.y)
- {
- ptc.x = s1.x;
- ptc.y = s1.y;
- ptd.x = s2.x;
- ptd.y = s2.y;
- }
- else
- {
- ptc.x = s2.x;
- ptc.y = s2.y;
- ptd.x = s1.x;
- ptd.y = s1.y;
- }
- }
- else
- {
- if (s1.y > s2.y)
- {
- ptc.x = s1.x;
- ptc.y = s1.y;
- ptd.x = s2.x;
- ptd.y = s2.y;
- }
- else
- {
- ptc.x = s2.x;
- ptc.y = s2.y;
- ptd.x = s1.x;
- ptd.y = s1.y;
- }
- }
- }
- else
- {
- ptc.x = ptb.x;
- ptc.y = ptb.y;
- ptd.x = ptb.x;
- ptd.y = ptb.y;
- }
- point1.x = (int) pta.x;
- point1.y = (int) pta.y;
- point2.x = (int) ptc.x;
- point2.y = (int) ptc.y;
- point3.x = (int) ptd.x;
- point3.y = (int) ptd.y;
- m_pt1perp[i].x = point1.x;
- m_pt1perp[i].y = point1.y;
- m_pt2perp[i].x = point2.x;
- m_pt2perp[i].y = point2.y;
- i++;
- }
-
- pInfo++;
- }
- /* Enlev�
- // Calculs aux extr�mit�s
- // Au d�but
- dpoint pt0, pt1;
- pt0.x = debx;
- // y = ax2 + b x + c
- pt0.y = (m_coeff_a * pt0.x * pt0.x) + (m_coeff_b * pt0.x) + m_coeff_c;
- // La tangente (d�riv�e) de y = ax2 + b x + c est y = 2ax + b
- // Le coefficient directeur de la perpendiculaire � la tangente est -1/b
- double ka, kb;
- // Pour la perpendiculaire qui passe par pta.x, pta.y, y = ka x + kb
- if (m_coeff_b != 0)
- {
- ka = (double) -1.0 / (2 * m_coeff_a);
- }
- else
- {
- ka = 0.0;
- }
- kb = pt0.y - ka * pt0.x;
- double kb2 = m_coeff_b;
- pt1.y = pt0.y + 2 * dist_etalon;
- if (ka != 0)
- {
- pt1.x = (pt1.y - kb) / ka;
- }
- else
- {
- pt1.x = pt0.x;
- }
- // Intersection entre le cercle centr� sur pt0 de rayon dist_etalon, et la droite xd,yd, ptcel
- if (InterCercleDroite(pt0, dist_Debut, pt0, pt1, &s1, &s2))
- {
- dist2 = distance(s1, ptdeb);
- dist3 = distance(s2, ptdeb);
- if (dist2 < dist3)
- {
- m_ptDebut.x = (int) s1.x;
- m_ptDebut.y = (int) s1.y;
- }
- else
- {
- m_ptDebut.x = (int) s2.x;
- m_ptDebut.y = (int) s2.y;
- }
- }
- // A la fin
- pt0.x = finx;
- // y = ax2 + b x + c
- pt0.y = (m_coeff_a * pt0.x * pt0.x) + (m_coeff_b * pt0.x) + m_coeff_c;
- // La tangente (d�riv�e) de y = ax2 + b x + c est y = 2ax + b
- // Le coefficient directeur de la perpendiculaire � la tangente est -1/b
- // Pour la perpendiculaire qui passe par pta.x, pta.y, y = ka x + kb
- if (m_coeff_b != 0)
- {
- ka = (double) -1.0 / (2 * m_coeff_a);
- }
- else
- {
- ka = 0.0;
- }
- kb = pt0.y - ka * pt0.x;
- kb2 = m_coeff_b;
- pt1.y = pt0.y + 2 * dist_etalon;
- if (ka != 0)
- {
- pt1.x = (pt1.y - kb) / ka;
- }
- else
- {
- pt1.x = pt0.x;
- }
- // Intersection entre le cercle centr� sur pt0 de rayon dist_etalon, et la droite xd,yd, ptcel
- if (InterCercleDroite(pt0, dist_Fin, pt0, pt1, &s1, &s2))
- {
- dist2 = distance(s1, ptfin);
- dist3 = distance(s2, ptfin);
- if (dist2 < dist3)
- {
- m_ptFin.x = (int) s1.x;
- m_ptFin.y = (int) s1.y;
- }
- else
- {
- m_ptFin.x = (int) s2.x;
- m_ptFin.y = (int) s2.y;
- }
- }
- */
- }
- /*----------------------------------------------------------\
- | Paroi |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Calcul de l'�paisseur d'une paroi dans une zone donn�e |
- \----------------------------------------------------------*/
- void CEIMBase::Paroi()
- {
- long dwPos, dwMin, dwFirst;
- int debx, finx;
- CEIMInfo *pInfo = &m_pMeasures[0];
- #ifdef NEW_EIM
- double dist_Debut, dist_Fin;
- dpoint pts;
- #endif
- bool bDebut = false;
- dpoint ptdeb, ptfin;
-
- ptdeb.x = ptfin.x = 0;
- ptdeb.y = ptfin.y = 0;
- m_nbpoints_curve = 0;
- m_coeff_a = -1.0;
- m_coeff_b = -1.0;
- m_coeff_c = -1.0;
- assert(!m_fDiameter && m_pMeasures && GfxImageValid());
- dwMin = long (-1);
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- // Ligne perpendiculaire � la paroi sur laquelle effectuer la mesure
- pInfo->m_Paroi[0].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 0);
- if (AddVector(pInfo->m_Paroi[0]))
- {
- ComputeEIM(pInfo);
- // recherche des premi�res position valides, afin de r�duire l'�tendue de l'histogramme
- dwFirst = pInfo->m_Paroi[0].m_slope[0].m_dwPos[0];
- if (dwFirst < dwMin)
- {
- dwMin = dwFirst;
- }
- if (bDebut == false)
- {
- bDebut = true;
- debx = m_vUser[dwPos].x;
- #ifndef NEW_EIM
- ptdeb.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptdeb.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- #endif
- }
- #ifndef NEW_EIM
- ptfin.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptfin.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- #endif
- finx = m_vUser[dwPos].x;
- }
- else
- {
- pInfo->m_fValid = false;
- }
- pInfo->m_diagnostic = m_diag;
- pInfo++;
- }
- #ifdef NEW_EIM
- // Modif CJ2007
- if (m_Assist)
- {
- ParallelismeEIM();
- CVector vPerp;
-
- // On recalcul l'EIM, en utilisant cette fois les perpendiculaires � la courbe obtenue
- dwMin = long (-1);
- int i;
- i = 0;
- pInfo = &m_pMeasures[0];
- bool bDistDeb;
- bDistDeb = false;
- bDebut = false;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- if (pInfo->m_fValid == true)
- {
- if ((m_pt1perp[i].y >= 0) && (m_pt2perp[i].y >= 0) && (m_pt1perp[i].x >= 0) && (m_pt2perp[i].x >= 0)
- && (m_pt1perp[i].y < 576) && (m_pt2perp[i].y < 576) && (m_pt1perp[i].x < 768) && (m_pt2perp[i].x < 768))
- {
- pInfo->m_Paroi[0].m_vMeasure = CVector(m_pt1perp[i], m_pt2perp[i]);
-
- if (AddVector(pInfo->m_Paroi[0]))
- {
- ComputeEIM(pInfo);
- // Recherche des premi�res position valides, afin de r�duire l'�tendue de l'histogramme
- dwFirst = pInfo->m_Paroi[0].m_slope[0].m_dwPos[0];
- if (dwFirst < dwMin)
- {
- dwMin = dwFirst;
- }
- if (bDebut == false)
- {
- bDebut = true;
- ptdeb.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptdeb.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- }
- ptfin.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptfin.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- dpoint ptt, ptr;
- ptt.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptt.y = (m_coeff_a * ptt.x * ptt.x) + (m_coeff_b * ptt.x) + m_coeff_c;
- ptr.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- ptr.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- if (!bDistDeb)
- {
- bDistDeb = true;
- dist_Debut = distance(ptt, ptr);
- }
- dist_Fin = distance(ptt, ptr);
- }
- else
- {
- pInfo->m_fValid = false;
- }
- pts.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- }
- i++;
- }
-
- pInfo++;
- }
- }
- #endif
- if (ptdeb.x < ptfin.x)
- {
- m_ptDebut.x = (long) ptdeb.x;
- m_ptFin.x = (long) ptfin.x;
- }
- else
- {
- m_ptDebut.x = (long) ptfin.x;
- m_ptFin.x = (long) ptdeb.x;
- }
- // Ajustement des vecteurs de mesures et des positions
- pInfo = &m_pMeasures[0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- pInfo->m_Paroi[0].m_slope[0].m_dwPos[0] -= dwMin;
- pInfo->m_Paroi[0].m_slope[0].m_dwPos[1] -= dwMin;
- pInfo->m_Paroi[0].m_slope[0].m_dwMiddle -= dwMin;
- pInfo->m_Paroi[0].m_slope[1].m_dwPos[0] -= dwMin;
- pInfo->m_Paroi[0].m_slope[1].m_dwPos[1] -= dwMin;
- pInfo->m_Paroi[0].m_slope[1].m_dwMiddle -= dwMin;
- pInfo->m_Paroi[0].m_slope[2].m_dwPos[0] -= dwMin;
- pInfo->m_Paroi[0].m_slope[2].m_dwPos[1] -= dwMin;
- pInfo->m_Paroi[0].m_slope[2].m_dwMiddle -= dwMin;
- pInfo->m_Paroi[0].m_vMeasure = CVector(pInfo->m_Paroi[0].m_vMeasure[dwMin], pInfo->m_Paroi[0].m_vMeasure.EndPoint());
- pInfo++;
- }
- } // end of Paroi
- /*-----------------------------------------------------------\
- | ParallelismeDistensibilite |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Fonction de calcul du parall�lisme du trait utilisateur |
- | Par rapport � la paroi |
- | Pour le calcul du diam�tre pour la distensibilit� |
- \----------------------------------------------------------*/
- void CEIMBase::ParallelismeDistensibilite()
- {
- int nbOk;
- long dwPos;
- dpoint pta, ptb, ptc, s1, s2;
- double distMoy, sommeDist;
- dpoint tpoints[MAX_POINTS_EIM_AUTO];
- double ka, kb;
- Point vp1, vp2;
- bool bInter;
- CEIMInfo *pInfo;
- ka = 0;
- kb = 0;
- // 1)- On va estimer la distance du milieu de la veine sur les points valides
- nbOk = 0;
- distMoy = 0;
- sommeDist = 0;
- pInfo = &m_pMeasures [0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- pInfo->m_Paroi[0].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 0);
- // pour l'histogramme, le deuxi�me vecteur est requis m�me si la mesure a �chou�
- pInfo->m_Paroi[1].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 1);
- if (AddVector(pInfo->m_Paroi [0])
- && ((m_algoDiameter == algoProfile) ?
- AddVector(pInfo->m_Paroi [1]) : // recherche d'un profil sur la paroi sup�rieure
- FindOpposite(pInfo->m_Paroi[0], pInfo->m_Paroi[1]) // recherche sur la paroi sup�rieure du sym�trique de la paroi inf�rieure
- )
- )
- {
- ComputeEIM(pInfo);
- distMoy = (pInfo->m_dblDia / 2.0);
- sommeDist += distMoy;
- nbOk++;
- }
- pInfo++;
- }
- if (nbOk > 0)
- {
- distMoy = sommeDist / nbOk;
- // 2)- On va d�terminer les points au centre
- pInfo = &m_pMeasures [0];
- m_nbpoints_curve = 0;
- nbOk = 0;
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- pInfo->m_Paroi[0].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 0);
- // On regarde que la paroi du bas pour le parall�lisme
- if (AddVector(pInfo->m_Paroi [0]))
- {
- ComputeEIM(pInfo);
- // Au premier point on m�morise la valeur de la distance qui va servir d'�talon pour les autres points
- pta.x = m_vUser[dwPos].x;
- pta.y = m_vUser[dwPos].y;
- ptb.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- ptb.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
-
- // Intersection cercle centr� sur ptb
- bInter = InterCercleDroite(ptb, distMoy, pta, ptb, &s1, &s2);
- // On prend celui qui est le plus pr�s de pta
- ptc = leplusproche(pta, s1, s2);
- // On stocke le point trouv� pour faire l'approximation
- tpoints[nbOk].x = ptc.x;
- tpoints[nbOk].y = ptc.y;
- nbOk++;
- }
- pInfo++;
- }
- if (nbOk > 4) // Plusieurs points sinon �rron�s
- {
- // Alors on approxime les points par une droite
- RegressionLineaire(nbOk, tpoints, &ka, &kb);
- // On met � jour m_vUser en fonction de la droite approxim�e : il va �tre utilis� par la suite
- vp1.x = m_vUser[0].x;
- vp1.y = (int) ((double) ka * vp1.x + kb);
- vp2.x = m_vUser[dwPos].x;
- vp2.y = (int) ((double) ka * vp2.x + kb);
- // On d�termine les nouvelles valeurs de m_vUser
- // Et c'est celui l� qui va �tre utilis� dans la fonction de base
- m_vUser = CVector (vp1, vp2);
- m_StartPoint.x = vp1.x;
- m_StartPoint.y = vp1.y;
- m_EndPoint.x = vp2.x;
- m_EndPoint.y = vp2.y;
- }
- else
- {
- m_StartPoint.x = m_vUser[0].x;
- m_StartPoint.y = m_vUser[0].y;
- m_EndPoint.x = m_vUser[1].x;
- m_EndPoint.y = m_vUser[1].y;
- }
- // Les calculs de base vont se faire avec le nouvel m_vUser calcul�
- }
- }
- /*----------------------------------------------------------\
- | Diameter |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Mesure du diam�tre d'un vaisseau |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | pScale : �chelle � utiliser pour les mesures |
- | gfx : image en niveau de gris d'o� lire les donn�es |
- | pt1 : premier point du segment d�terminant la ligne |
- | de la paroi. |
- | pt2 : deuxi�me point du segment |
- \----------------------------------------------------------*/
- void CEIMBase::Diameter()
- {
- CEIMInfo *pInfo;
- long dwMin [2], dwPos, dwFirst;
-
- assert (m_fDiameter && m_pMeasures && GfxImageValid());
- if (m_parallelismeDiametre)
- {
- ParallelismeDistensibilite();
- }
- dwMin[0] = long(-1);
- dwMin[1] = long(-1);
- bool bDistDeb, bDebut;
- bDistDeb = false;
- bDebut = false;
- pInfo = &m_pMeasures[0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- pInfo->m_Paroi[0].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 0);
- // Pour l'histogramme, le deuxi�me vecteur est requis m�me si la mesure a �chou�
- pInfo->m_Paroi[1].m_vMeasure = m_vUser.Orthogonal(m_vUser[dwPos], 1);
- if ( AddVector(pInfo->m_Paroi [0])
- && ( (m_algoDiameter == algoProfile) ?
- AddVector(pInfo->m_Paroi [1]) : // recherche d'un profil sur la paroi sup�rieure
- FindOpposite (pInfo->m_Paroi[0], pInfo->m_Paroi[1]) // recherche sur la paroi sup�rieure du sym�trique de la paroi inf�rieure
- )
- )
- {
- ComputeEIM (pInfo);
- // recherche des premi�res position valides, afin de r�duire l'�tendue de l'histogramme
- for (int j = 0; j < 2; j++)
- {
- dwFirst = pInfo->m_Paroi[j].m_slope[0].m_dwPos[0];
- if (dwFirst < dwMin [j])
- dwMin[j] = dwFirst;
- }
- }
- else
- {
- // recalcul syst�matique, car cette fonction est appel� lors de la modification des seuils
- pInfo->m_fValid = false;
- }
- pInfo++;
- }
- // ajustement des vecteurs de mesures et des positions
- pInfo = &m_pMeasures [0];
- for (dwPos = 0; dwPos < m_dwPoints; dwPos++)
- {
- for (int i = 0; i < 2; i++)
- {
- pInfo->m_Paroi[i].m_slope[0].m_dwPos[0] -= dwMin[i];
- pInfo->m_Paroi[i].m_slope[0].m_dwPos[1] -= dwMin[i];
- pInfo->m_Paroi[i].m_slope[0].m_dwMiddle -= dwMin[i];
- pInfo->m_Paroi[i].m_slope[1].m_dwPos[0] -= dwMin[i];
- pInfo->m_Paroi[i].m_slope[1].m_dwPos[1] -= dwMin[i];
- pInfo->m_Paroi[i].m_slope[1].m_dwMiddle -= dwMin[i];
- pInfo->m_Paroi[i].m_vMeasure = CVector (pInfo->m_Paroi[i].m_vMeasure[dwMin[i]], pInfo->m_Paroi[i].m_vMeasure.EndPoint());
- }
- pInfo++;
- }
- } // end of Diameter
- /*----------------------------------------------------------\
- | CEIM::AddVector |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Calcul de l'�paisseur d'une paroi dans une zone donn�e |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | paroi : CEIMInfo � remplir avec les mesures |
- \----------------------------------------------------------*/
- bool CEIMBase::AddVector(sParoi &paroi)
- {
- long dwPoint, dwLast = THICKNESS - 1; // le dernier point sur lequel effectuer une mesure (au pire)
- // on s'assure que le vecteur ne d�passe pas la zone d'affichage
- // paroi.m_vMeasure.Mask (*m_pGfx); dwLast = min( dwMax, m_vMeasure.Length())
- assert (PointInBuffer (paroi.m_vMeasure [0]));
- // afin de traiter la variation d'intensit� en m�me temps, on r�cup�re le premier
- // point ind�pendamment des autres
- // ASSERT ((paroi.m_vMeasure [0].x != 301) && (paroi.m_vMeasure [0].x != 336));
- m_bBuffer [0] = GetIntensity (paroi.m_vMeasure [0]);
- for (dwPoint = 1; dwPoint <= dwLast; dwPoint++)
- {
- const Point &pt = paroi.m_vMeasure [dwPoint];
- if (PointInBuffer (pt))
- {
- // remplissage de la m�moire tampon
- m_bBuffer [dwPoint] = GetIntensity (pt);
- // calcul de la variation de densit�
- m_cOffsets [dwPoint] = Delta (m_bBuffer [dwPoint], m_bBuffer [dwPoint - 1]);
- }
- else // peu �l�gant, mais efficace
- {
- dwLast = dwPoint - 1; // interrompra �galement la prochaine boucle (de d�tection de profil)
- }
- }
- // On mesure l'E.I.M. sur la ligne extraite
- if (m_versionTomtecAout08)
- {
- // Pour pouvoir afficher les points milieux m�me s'ils sont pas valides
- int res = MeasureLineBuffer (paroi, m_bBuffer, m_cOffsets, dwPoint);
- {
- SetMiddlePoint (paroi.m_slope [0], paroi.m_vMeasure);
- SetMiddlePoint (paroi.m_slope [1], paroi.m_vMeasure);
- // On mesure l'IMT sur la ligne extraite
- SetMiddlePoint (paroi.m_slope [2], paroi.m_vMeasure, true);
-
- if (res)
- {
- return (true);
- }
- }
- }
- else
- {
- if (MeasureLineBuffer (paroi, m_bBuffer, m_cOffsets, dwPoint) > 0)
- {
- SetMiddlePoint (paroi.m_slope [0], paroi.m_vMeasure);
- SetMiddlePoint (paroi.m_slope [1], paroi.m_vMeasure);
- // On mesure l'IMT sur la ligne extraite
- SetMiddlePoint (paroi.m_slope [2], paroi.m_vMeasure, true);
-
- return (true);
- }
- }
- return (false);
- } // end of AddVector
- /*----------------------------------------------------------\
- | FindOpposite |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Recherche le point adventice sym�trique|
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | paroi : CEIMInfo � remplir avec les mesures |
- \----------------------------------------------------------*/
- bool CEIMBase::FindOpposite(sParoi &paroi1, sParoi &paroi0)
- {
- long dwSeek = paroi0.m_slope[0].m_dwIntensity,
- dwMax = GetIntensity(paroi1.m_vMeasure[paroi0.m_slope[1].m_dwPos[1]]),
- dwPoint;
- bool fFound, fInGfx;
- // afin de traiter la variation d'intensit� en m�me temps, on r�cup�re le premier
- // point ind�pendamment des autres
- dwPoint = 0;
- fFound = false;
- fInGfx = true;
- do
- {
- const Point &pt = paroi1.m_vMeasure [dwPoint];
- fInGfx = PointInBuffer (pt);
- if (fInGfx)
- {
- unsigned char bLevel = GetIntensity (pt);
- m_bBuffer [dwPoint] = bLevel;
- if (bLevel < dwSeek)
- dwPoint++;
- else if (bLevel > dwMax)
- // la valeur trouv�e d�passe la valeur du sommet de la pente de la paroi
- // du bas, on consid�re que c'est une erreur
- fInGfx = false;
- else
- {
- long dwPos = dwPoint;
- // il est tr�s peu probable que l'on arrive juste sur le milieu de la pente.
- // on cherche donc les extr�mes.
-
- // recherche du bas de la pente
- while (dwPoint && (m_bBuffer [dwPoint - 1] <= m_bBuffer [dwPoint]))
- dwPoint--;
- paroi1.m_slope [1].m_dwPos [0] = dwPoint;
-
- // recherche du sommet de la pente
- dwPoint = dwPos + 1;
- paroi1.m_slope [1].m_dwPos [1] = 0; // normalement d�j� fait
- while (!paroi1.m_slope [1].m_dwPos [1])
- {
- const Point &pt = paroi1.m_vMeasure [dwPoint];
- if (!PointInBuffer (pt))
- paroi1.m_slope [1].m_dwPos [1] = dwPoint - 1;
- else
- {
- m_bBuffer [dwPoint] = GetIntensity (pt);
- if (m_bBuffer [dwPoint] > m_bBuffer [dwPoint - 1])
- dwPoint++;
- else
- paroi1.m_slope [1].m_dwPos [1] = dwPoint - 1;
- }
- }
- // la 1� pente est ignor�e par cette m�thode, seule la 2� pente est analys�e
- SetMiddlePoint (paroi1.m_slope [1], paroi1.m_vMeasure);
- fFound = true;
- }
- }
- } while (fInGfx && !fFound);
- return (fFound);
- } // end of FindOpposite
- /*----------------------------------------------------------\
- | SetMiddlePoints |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | D�termine la position des deux points encadrants le |
- | milieu d'une des deux pentes. |
- | Les deux points retourn�s peuvent �tre confondus. |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | slope : pente sur laquelle effectuer les mesures |
- | vMeasure : vecteur sur lequel cette pente a �t� d�tect�e |
- \----------------------------------------------------------*/
- void CEIMBase::SetMiddlePoint(
- sSlope &slope,
- CVector &vMeasure,
- bool reverseSlope)
- {
- int iMean;
- long dwPos;
- // on utilise le double du milieu, car 80+21/2=50, pas 50.5 puisque c'est un entier
- //assert (AfxIsValidAddress (&slope, sizeof (slope)));
- // [JAK - 06/09/02] l'assert surgit un peu trop souvent lors de mesure de la distensibilit�
- // if ( reverseSlope )
- // ASSERT (m_bBuffer[slope.m_dwPos[0]] > m_bBuffer [slope.m_dwPos[1]]);//ICI
- // else
- // ASSERT (m_bBuffer[slope.m_dwPos[0]] < m_bBuffer [slope.m_dwPos[1]]);
-
- dwPos = slope.m_dwPos[0];
- iMean = m_bBuffer [dwPos] + m_bBuffer [slope.m_dwPos [1]];
- if (reverseSlope)
- while (m_bBuffer [dwPos] * 2 > iMean) dwPos++;
- else
- while (m_bBuffer [dwPos] * 2 < iMean) dwPos++;
- // La mesure d'EIM est maintenant faite ici, car les intensit�s des points sont
- // n�cessaires pour estimer la position exacte du milieu (en INTENSITE)
- if (m_bBuffer [dwPos] * 2 == iMean)
- {
- // en cas d'�galit�, les deux points sont confondus
- slope.m_ptDraw =
- slope.m_ptMiddle = vMeasure [dwPos];
- slope.m_dblMiddle = 0.0;
- }
- else
- {
- dwPos--;
- slope.m_ptMiddle = vMeasure [dwPos];
- if ( reverseSlope )
- {
- if (iMean - 2 * m_bBuffer [dwPos + 1] < 2 * m_bBuffer [dwPos] - iMean)
- slope.m_ptDraw = slope.m_ptMiddle;
- else
- slope.m_ptDraw = vMeasure [dwPos + 1];
- // [JAK - 3/8/2002] ASSERT (m_bBuffer [dwPos + 1] < m_bBuffer [dwPos]);
- }
- else
- {
- if (2 * m_bBuffer [dwPos + 1] - iMean > iMean - 2 * m_bBuffer [dwPos])
- slope.m_ptDraw = slope.m_ptMiddle;
- else
- slope.m_ptDraw = vMeasure [dwPos + 1];
- //assert (m_bBuffer [dwPos + 1] > m_bBuffer [dwPos]);
- }//
-
- assert (abs (slope.m_ptMiddle.x - vMeasure [dwPos + 1].x) <= 1);
- assert (abs (slope.m_ptMiddle.y - vMeasure [dwPos + 1].y) <= 1);
- slope.m_dblMiddle =
- ( double (iMean - m_bBuffer [dwPos] * 2)
- * CVector (slope.m_ptMiddle, vMeasure [dwPos + 1]).Norm ()
- / (m_bBuffer [dwPos + 1] - m_bBuffer [dwPos]) // bug potentiel : division par zero [JAK - 15/10/2002]
- / 2
- );
- }
- // permet un affichage beaucoup plus rapide de l'histogramme
- slope.m_dwMiddle = dwPos;
- slope.m_dwIntensity = iMean / 2;
- } // fin de SetMiddlePoints
- /*----------------------------------------------------------\
- | CEIM::MeasureLineBuffer |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Mesure de l'E.I.M. � partir d'un buffer d'intensit� et |
- | de variation |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | paroi : Info � d�finir sur la mesure d'EIM |
- | pbIntensity : pointeur sur les intensit�s |
- | pcOffsets : pointeur sur les variations d'intensit� |
- | dwPoints : nombre de points � �tudier |
- |-----------------------------------------------------------|
- | RETOUR : |
- | un bool�en indiquant si le profil a �t� reconnu |
- \----------------------------------------------------------*/
- int CEIMBase::MeasureLineBuffer
- (
- sParoi &paroi,
- unsigned char* pbBuffer,
- char *pcOffsets,
- long dwPoints
- )
- {
- m_diag = 0; // Permet de voir o� l'algorithme s'est arr�t� (afin de l'am�liorer)
- // Valeur n�gative
- if (dwPoints < 3)
- {
- return (0);
- }
- else
- {
- long dwStart, dwPos, dwFirst, dwLast, dwLastChanged;
- bool fChanged;
- /////////////////////////////////
- // lissage de la courbe de densit�
- /////////////////////////////////
- // il ne faut pas corriger les ext�rieurs sinon, � cause du report,
- // tous les points seront corrig�s
- // sur 300 points le lissage dure moins d'une milliseconde
- dwFirst = 2;
- dwLastChanged = dwLast = dwPoints - 2;
- do
- {
- char c, c1, c2, c3;
- fChanged = false;
- // on ne prend pas en compte les variations nulles, autrement dit
- // un 1,1,0,-1,1 ->1,1,0,1(ou 0),1.
- // ainsi les variations de 1 pixel sont ignor�es
- // on conserve donc en m�moire le dernier point significatif (au d�but 0...)
- c1 = pcOffsets [dwFirst - 1];
- for (dwPos = dwFirst; dwPos < dwLast; dwPos++)
- {
- c = pcOffsets [dwPos - 1];
- if (c) // non nul
- c1 = c; // nouvelle variation
- c2 = pcOffsets [dwPos ];
- c3 = pcOffsets [dwPos + 1];
- // on met � jour le pt central � jour si les deux extr�mes varient dans le m�me sens
- // et que le point central varie dans le sens inverse.
- if ((c1 == c3) && (c2 != c1))
- {
- pbBuffer [dwPos ] = (unsigned char )((pbBuffer [dwPos - 1] + pbBuffer [dwPos + 1]) / 2);
- // on est oblig� de recalculer les variations
- pcOffsets [dwPos ] = Delta (m_bBuffer [dwPos ], m_bBuffer [dwPos - 1]);
- pcOffsets [dwPos + 1] = Delta (m_bBuffer [dwPos + 1], m_bBuffer [dwPos ]);
- // ce test n'est pas la pour le FUN !! si l'�cart entre deux intensit� est 1
- // le milieu sera le point de plus faible intensit�, ce qui ne changera rien
- if ((pcOffsets [dwPos] != c2) || (pcOffsets [dwPos + 1] != c3))
- {
- if (!fChanged)
- {
- fChanged = true;
- dwFirst = dwPos;
- }
- // d�s que fChanged est VRAI il faut initialiser dwLastChanged (petit oubli !!)
- dwLastChanged = dwPos; // si on change dwLast, on quitte la boucle!!
- }
- }
- }
- dwLast = dwLastChanged;
- } while (fChanged);
- ////////////////////////////////////
- // recherche du profil de densit� //
- ////////////////////////////////////
- // pour un algo avec gestion de seuils voir fichier EIM/AvecSeuil.cpp
- // a) recherche d'une croissance (3 pixels de suite au moins : 2 variations de m�me sens)
- // � partir du pixel donn�, pour un maximum de points donn�
- // le premier est le plus complexe � trouver.
- #ifdef TEST_FOR_FANTOME
- dwStart = 2;
- #endif
- if ( LookForFirstPoint (dwStart, dwPoints, dwPos, m_bBuffer) )
- {
- m_diag = -1;
- paroi.m_slope [0].m_dwPos [0] = dwPos; // sera modifi� si le delta est insuffisant
- // b) recherche d'une d�croissance (3 pixels de suite au moins : 2 variations de m�me sens)
- bool variation = LookForVariation (dwStart, pcOffsets, dwPoints, enumDown, dwPos);
- #ifdef TEST_FOR_FANTOME
- if ( !variation )
- {
- if ( LookForFirstPoint (dwStart, dwPoints, dwPos, m_bBuffer) )
- {
- variation = LookForVariation (dwStart, pcOffsets, dwPoints, enumDown, dwPos);
- }
- }
- #endif
- if ( variation )
- {
- m_diag = -2;
-
- paroi.m_slope [0].m_dwPos [1] = dwPos;
- paroi.m_slope [2].m_dwPos [0] = dwPos; // Pour INT
- // "g�n�ration" de plateaux. Suppression des petites irr�gularit�s sur des plateaux,
- // afin de d�tecter ais�ment les zones de saturation
- // ce n'est n�cessaire qu'� ce niveau
- for (dwFirst = dwPos; dwFirst < dwPoints - 3; dwFirst++)
- {
- unsigned char b = pbBuffer [dwFirst];
- // il faut �galement mettre � jour pcOffsets, sinon on engendre une incoh�rence
- if ( (b == pbBuffer [dwFirst + 2])
- && (abs (b - pbBuffer [dwFirst + 1]) < 5))
- {
- pbBuffer [dwFirst + 1] = b;
- pcOffsets [dwFirst + 1] = 0;
- }
- else if ( (b == pbBuffer [dwFirst + 3])
- && (abs (b - pbBuffer [dwFirst + 1]) < 5)
- && (abs (b - pbBuffer [dwFirst + 2]) < 5))
- {
- pbBuffer [dwFirst + 1] = b;
- pbBuffer [dwFirst + 2] = b;
- pcOffsets [dwFirst + 1] = 0;
- pcOffsets [dwFirst + 2] = 0;
- }
-
- }
- // c) recherche d'une croissance (3 pixels de suite au moins : 2 variations de m�me sens)
- if (LookForVariation (dwStart, pcOffsets, dwPoints, enumUp, dwPos))
- {
- m_diag = -3;
- if (pbBuffer [paroi.m_slope [0].m_dwPos [1]] <= m_bDelta2 + pbBuffer [dwStart - 1])
- {
- m_diag = -4;
- // Test Ajout test 1 180808
- if ((m_versionTomtecAout08 && ((2 * pbBuffer [dwStart - 1])> m_bSeuil1)) || (!m_versionTomtecAout08))
- {
- // if ((2 * pbBuffer [dwStart - 1])> (2 * pbBuffer [paroi.m_slope [0].m_dwPos [1]]))
- {
- paroi.m_slope[1].m_dwPos[0] = dwPos;
- paroi.m_slope[1].m_dwPos[1] = dwStart - 1;
- paroi.m_slope[2].m_dwPos[1] = dwPos;
- }
- return (1);
- }
- }
- if (m_versionTomtecAout08)
- {
- dwStart += 3;
- // On fait 2 fois de suite la recherche d'une croissance 180808
- // La premi�re croissance peut �tre une erreur
- // d) recherche d'une seconde croissance (3 pixels de suite au moins : 2 variations de m�me sens)
- if (LookForVariation (dwStart, pcOffsets, dwPoints, enumUp, dwPos))
- {
- m_diag = -5;
- if (pbBuffer [paroi.m_slope [0].m_dwPos [1]] <= m_bDelta2 + pbBuffer [dwStart - 1])
- {
- m_diag = -6;
- // Test Ajout test 1 180808
- if ((2 * pbBuffer [dwStart - 1])> m_bSeuil1)
- {
- // if ((2 * pbBuffer [dwStart - 1])> (2 * pbBuffer [paroi.m_slope [0].m_dwPos [1]]))
- {
- paroi.m_slope[1].m_dwPos[0] = dwPos;
- paroi.m_slope[1].m_dwPos[1] = dwStart - 1;
- paroi.m_slope[2].m_dwPos[1] = dwPos;
- }
- return (1);
- }
- }
- }
- }
- /*
- // d) recherche d'une d�croissance (3 pixels de suite au moins : 2 variations de m�me sens)
- // il faut que le maximal de la deuxi�me pente soit plus haut que le maximal de la premi�re
- // (c'est un crit�re tr�s efficace pour �liminer de mauvaise mesures, en g�n�ral lorsque la
- // "1�" paroi qui a �t� d�tect�e n'est pas la bonne)
- if (LookForVariation (dwStart, pcOffsets, dwPoints, enumDown, dwPos))
- {
- // on cherche le d�but du plateau si on est dessus, le dernier point doit �tre la fin
- // d'une croissance STRICTE
- dwFirst = dwPos; // on veut conna�tre la taille du plateau
- while (pbBuffer [dwPos] == pbBuffer [dwPos - 1])
- dwPos--;
- if ( (pbBuffer [paroi.m_dwPos [1]] + m_bDelta2 < pbBuffer [dwPos])
- || ((dwFirst - dwPos >= 2) && (pbBuffer [dwPos] >= 240))
- )
- {
- paroi.m_dwPos[3] = dwPos;
- return (1);
- }
- }
- */
- }
- }
- }
- }
- return (0);
- } // end of Measure
- /*----------------------------------------------------------\
- | LookForFirstPoint |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Recherche du premier point caract�ristique de la paroi |
- | Il m�rite � lui seul une fonction... |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | dwStart : premier point � examine |
- | dwMax : dernier point examinable |
- | dwPos : o� stocker la position trouv�e |
- | pbBuffer : ligne d'intensit� |
- |-----------------------------------------------------------|
- | RETOURNE : |
- | un bool�en indiquant si la variation recherch�e a �t� |
- | trouv�e |
- \----------------------------------------------------------*/
- bool CEIMBase::LookForFirstPoint
- ( long &dwStart,
- long dwMax,
- long &dwPos,
- unsigned char* pbBuffer
- )
- {
- // r�gles de d�tection de la premi�re pente:
- // 1. trois points doivent se se suivre avec une intensit� croissante
- // 2. le dernier des points, doit avoir une intensit� �gal � m_bDelta1 + la moyenne des pr�c�dents
- // 3. au moins trois points cons�cutifs doivent ensuite avoir une intensit� inf�rieur au premier sommet
- //
- // l'intensit� du premier point sert de rep�re
- unsigned char bFirst = pbBuffer [1]; // intensit� du premier point
- unsigned char* pb;
- #ifndef TEST_FOR_FANTOME
- dwStart = 2; // on commence � 2 pour avoir acc�s � -1 et -2
- #endif
- pb = &pbBuffer [dwStart];
- while ( (dwStart < dwMax) &&
- ( ( ( pb [ 0] - bFirst ) < m_bDelta1) // tant que le point courant n'est pas assez lumineux, on continue
- || ( pb [-2] >= pb [-1] ) ) )
- {
- pb++, dwStart++;
- }
- if (dwStart >= dwMax)
- {
- return (false);
- }
- else
- {
- dwPos = dwStart - 1;
- // on incr�mente dwStart jusqu'� une d�croissance STRICTE double
- // une simple d�croissance est une irr�gularit� � ignorer
- while ((dwStart < dwMax) && ((pb [1] >= pb [0]) || (pb [2] >= pb [0])))
- {
- pb++, dwStart++;
- }
- dwStart++; // il faut que l'on pointe sur le d�but de la d�croissance
-
- if (dwStart >= dwMax)
- {
- return (false);
- }
- else
- {
- pb = &pbBuffer [dwPos];
- // on cherche le premier point � m_bDelta1 du sommet
- // on est certain de trouver un point (au pire dwStart)
- // bFirst = BYTE (pbBuffer [dwStart - 1] - m_bDelta1); // dwStart pointe juste apr�s le sommet
- // while (bFirst < pb [0]) // comparaison STRICTE
- // pb--, dwPos--;
- // on continue tant qu'il y a une d�croissance STRICTE (on autorise UNE irr�gularit� m�me apr�s lissage)
- // sinon si que du noir, on arrive au d�but du segment!!
- // le test sur m_bDelta1 emp�che fr�quemment la d�tection r�elle du d�but de la pente
- while (dwPos && ((pb[0] > pb[-1]) || ((dwPos > 1) && (pb[0] > pb[-2]))))
- {
- pb--, dwPos--;
- }
- return (true);
- }
- }
- } // fin de LookForFirstPoint
- /*----------------------------------------------------------\
- | CEIM::LookForVariation |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Recherche dans le buffer une variation de densit� dans le|
- | sens donn�, et d�place le pointeur tant que cette |
- | variation est maintenue |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | dwStart : premier point � examine |
- | pcOffsets : tableau de variation de densit�s |
- | dwMax : dernier point examinable |
- | dir : sens de variation recherch� |
- | dwPos : o� stocker la position trouv�e |
- |-----------------------------------------------------------|
- | RETOURNE : |
- | un bool�en indiquant si la variation recherch�e a �t� |
- | trouv�e |
- \----------------------------------------------------------*/
- bool CEIMBase::LookForVariation (long &dwStart, char *pcOffsets, long dwMax, enumDirection dir, long &dwPos)
- {
- char c1, c2;
- assert (dwStart); // le tableau de variation d�bute � 1
- while (dwStart < dwMax)
- {
- c1 = pcOffsets [dwStart];
- c2 = pcOffsets [dwStart + 1];
- if (c1 && (c1 == c2)) // il faut une variation (c1 != 0) <=> (c2 != 0)
- {
- if (dir == enumUp)
- {
- if (c1 < 0)
- {
- return (false); // Sens inverse de celui recherch�
- }
- else
- {
- dwPos = dwStart - 1;
- dwStart++;
- do
- {
- dwStart++;
- // } while ((dwStart < dwMax) && (pcOffsets [dwStart] >= 0));
- } while ((dwStart < dwMax) && (pcOffsets [dwStart] > 0));
- return (true);
- }
- }
- else
- {
- if (c1 > 0)
- {
- return (false); // croissance, au lieu de d�croissance
- }
- else
- {
- dwPos = dwStart - 1;
- dwStart++;
- do
- {
- dwStart++;
- } while ((dwStart < dwMax) && (pcOffsets [dwStart] <= 0));
- return (true);
- }
- }
- }
- dwStart++;
- }
- return (false);
- } // fin de LookForVariation
- /*----------------------------------------------------------\
- | Update |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Mesures des parois reconnues et statistiques |
- |-----------------------------------------------------------|
- | RETOURNE : |
- | VRAI si au moins un profil a �t� reconnu |
- \----------------------------------------------------------*/
- bool CEIMBase::Update (CEIMResult *m_res)
- {
- // ATTENTION, il se peut qu'aucun profil n'ait �t� d�tect�
- // [JAK - 24/6/2002] no histogram window
- //initialisation
- GraphMeanInit();
- m_arVariance.clear();
- m_arVarianceAA.clear();
- m_arVarianceII.clear();
- m_arVarianceINT.clear();
- m_dwValidPoints = 0;
- m_dblDistance = 0.0;
- m_dblEIMMin =
- m_dblEIMMean =
- m_dblEIMMax =
- m_dblINTMin =
- m_dblINTMean =
- m_dblINTMax =
- m_dblEIMdMean =
- m_dblINTdMean =
- m_dblMEDdMean =
- m_dblIAd =
- m_dblDiaAAMin =
- m_dblDiaAAMean =
- m_dblDiaAAMax =
- m_dblDiaIIMin =
- m_dblDiaIIMean =
- m_dblDiaIIMax = 0.0;
-
- if (m_pMeasures == NULL)
- return (false);
- else
- {
- CEIMInfo *pInfo = &m_pMeasures [0];
- long dw;
- double dblMeanEIM, // valeur moyenne de l'EIM lors de la 1� phase
- dblMeanINT,
- dblMeanEIMd,
- dblMeanINTd,
- dblMeanMEDd,
- dblGapEIM,
- dblMeanQI,
- dblMeanDia, // valeur moyenne du diam�tre lors de la 1� phase
- dblGapDia,
- dblMeanDist, // distance moyenne du 1� milieu au trait utilisateur
- dblStdDist,
- dblGapDist,
- dblII; // diam�tre intima/intima
- // dblGapQI;
- // la premi�re �tape consiste:
- // - � calculer la valeur de l'EIM � partir des points d�tect�s
- // - � calculer la moyenne des mesures afin d'�liminer ensuite
- // celles qui s'�cartent trop de cette valeur moyenne.
- dblGapEIM = 0;
- dblGapDist = 0;
- dblGapDia = 0;
- dblII = 0;
- dblMeanEIM = 0;
- dblMeanINT = 0;
- dblMeanEIMd = 0;
- dblMeanINTd = 0;
- dblMeanMEDd = 0;
- dblMeanDia = 0;
- dblMeanDist = 0;
- dblStdDist = 0.0;
- dblMeanQI = 0.0;
-
- for (dw = 0; dw < m_dwPoints; dw++)
- {
- if (pInfo->m_fValid) // le profil a �t� rep�r�
- {
- dblMeanEIM += pInfo->m_dblEIM;
- dblMeanINT += pInfo->m_dblINT;//PJT
- dblMeanEIMd += pInfo->m_dblEIMd;
- dblMeanINTd += pInfo->m_dblINTd;
- dblMeanMEDd += pInfo->m_dblMEDd;
- dblMeanDia += pInfo->m_dblDia;
- dblMeanDist += pInfo->m_dblDist;
- dblStdDist += pInfo->m_dblDist * pInfo->m_dblDist;
- dblMeanQI += pInfo->m_dblQI;
- m_dwValidPoints++; // requis pour obtenir la moyenne
- }
- pInfo++;
- }
- if (m_dwValidPoints == 0)
- {
- m_uErrorID = IDS_EIM_FAILED;//BUG ICI //[JAK - 09/09/02]
- return (false); // aucune mesure valide
- }
- else
- {
- try// [JAK - 5/7/2002]
- {
- // calcul des moyennes
- dblMeanEIM /= m_dwValidPoints;
- dblMeanDia /= m_dwValidPoints;
- dblMeanDist /= m_dwValidPoints;
- dblStdDist /= m_dwValidPoints;
- dblMeanINT /= m_dwValidPoints;//PJT
- dblMeanEIMd /= m_dwValidPoints;
- dblMeanINTd /= m_dwValidPoints;
- dblMeanMEDd /= m_dwValidPoints;
- dblMeanQI /= m_dwValidPoints;
-
- // l'�cart autoris� est �gal � 25% de la moyenne 23/02/99 Touboul
- // l'�cart autoris� est �gal � 50% de la moyenne 06/05/99 Touboul
- // l'�cart autoris� est �gal � 35% de la moyenne 19/07/99 Touboul
- // l'�cart autoris� est �gal � 10% de la moyenne 19/07/05 Touboul
- if (m_versionTomtecAout08)
- {
- dblGapEIM = dblMeanEIM *.25;//.35 20/10/05 PJT // 0.2 180808
- dblGapDia = dblMeanDia *.02;//.04 20/10/05 PJT
- dblGapDist = dblMeanDist *.15;//.25 20/10/05 PJT // 0.2 180808
- }
- else
- {
- dblGapEIM = dblMeanEIM *.20;
- dblGapDia = dblMeanDia *.02;
- dblGapDist = dblMeanDist *.20;
- }
-
- // dblGapDist = sqrt(dblStdDist - dblMeanDist * dblMeanDist);// 20/12/06 FP
- pInfo = &m_pMeasures[0];
- // exclusion de tous les points hors normes
- for (dw = 0; dw < m_dwPoints; dw++)
- {
- if ( pInfo->m_fValid
- // on exclut tous les point qui s'�cartent trop de la moyenne
- && ( (fabs (pInfo->m_dblEIM - dblMeanEIM ) > dblGapEIM) // EIM incoh�rent
- || (fabs (pInfo->m_dblDist - dblMeanDist) > dblGapDist) // ou distance � l'axe incoh�rente
- || (m_fDiameter && (fabs (pInfo->m_dblDia - dblMeanDia) > dblGapDia)) // ou diam�tre incoh�rent
- || (fabs (pInfo->m_dblQI)> 0.3) // IQ < 50% Touboul
- )
- )
- {
- pInfo->m_fThrownOut = true; // par d�faut � FALSE gr�ce au memset (on laisse valide pour affichage palette)
- pInfo->m_fValid = false;
- m_dwValidPoints--;
- }
- pInfo++;
- }
- // il se peut que TOUS les points soient � + de 20% de la moyenne
- // (par exemple deux lignes tr�s �loign�es)
- if (m_dwValidPoints == 0)
- {
- m_uErrorID = IDS_EIM_FAILED;
- return (false); // aucune mesure valide
- }
- else
- {
- if (m_fDiameter) // Calcul de la moyenne des diam�tres trouv�s
- {
- std::vector<double> arrayAA, arrayII;//il s'agit en faite d'une duplication de m_arVarianceAA et m_arVarianceII
- double dblMeanAA = 0.0;
- double dblMeanII = 0.0;
- double dblVarianceAA = 0.0;
- double dblVarianceII = 0.0;
-
- // recherche du premier profil valide
- pInfo = &m_pMeasures [0];
- for (dw = 0; !pInfo->m_fValid; dw++)
- {
- pInfo++;
- }
- // on est certain qu'un pInfo valide va �tre trouv�
- //----- resultat d'un calcul de diametre [JAK - 13/1/2003]
- m_dblDiaAAMin = m_dblDiaAAMean = m_dblDiaAAMax = pInfo->m_dblDia;
- m_dblDiaIIMin = m_dblDiaIIMean = m_dblDiaIIMax = pInfo->m_dblDia - 2 * pInfo->m_dblEIM;
-
- arrayII.push_back(g_pCurrentScale->Distance(m_dblDiaIIMean));
- arrayAA.push_back(g_pCurrentScale->Distance(m_dblDiaAAMean));
- GraphMeanAddMeasure(true, pInfo->m_dblDia);
-
- m_arVarianceAA.push_back (g_pCurrentScale->Distance (pInfo->m_dblDia));
- m_arVarianceII.push_back (g_pCurrentScale->Distance (pInfo->m_dblDia- 2 * pInfo->m_dblEIM));
- dblMeanAA = g_pCurrentScale->Distance (pInfo->m_dblDia);
- dblMeanII = g_pCurrentScale->Distance (pInfo->m_dblDia - 2 * pInfo->m_dblEIM);
-
- dw++,pInfo++;
-
- while (dw < m_dwPoints)
- {
- if (pInfo->m_fValid)
- {
- m_dblDiaAAMean += pInfo->m_dblDia;
- if (pInfo->m_dblDia < m_dblDiaAAMin) m_dblDiaAAMin = pInfo->m_dblDia;
- if (pInfo->m_dblDia > m_dblDiaAAMax) m_dblDiaAAMax = pInfo->m_dblDia;
- dblII = pInfo->m_dblDia - 2 * pInfo->m_dblEIM;
-
- m_dblDiaIIMean += dblII;
- if (dblII < m_dblDiaIIMin) m_dblDiaIIMin = dblII;
- if (dblII > m_dblDiaIIMax) m_dblDiaIIMax = dblII;
-
- // [JAK - 24/6/2002] no histogram window
- GraphMeanAddMeasure (true, pInfo->m_dblDia);
- arrayAA.push_back(g_pCurrentScale->Distance(pInfo->m_dblDia));
- arrayII.push_back(g_pCurrentScale->Distance(dblII));
- m_arVarianceAA.push_back (g_pCurrentScale->Distance (pInfo->m_dblDia));
- m_arVarianceII.push_back (g_pCurrentScale->Distance (dblII));
-
- dblMeanAA += g_pCurrentScale->Distance (pInfo->m_dblDia);
- dblMeanII += g_pCurrentScale->Distance (dblII);
- }
- dw++;
- pInfo++;
- }
- /* if (m_vUser.Length () < QI_MIN)
- {
- CString msg; msg.Format(MyLoadString(IDS_EIM_QI_0), QI_MIN);
- CMessage::Info (msg);
- m_dblQI = 0.;
- }
- else*/
- m_dblQI = double (m_dwValidPoints) / m_dwPoints;
-
- // calcul de la variance
- dblMeanAA /= (double)m_arVarianceAA.size ();
- dblMeanII /= (double)m_arVarianceII.size ();
- dblVarianceAA = 0.0;
- dblVarianceII = 0.0;
- for (unsigned int i = 0; i < m_arVarianceAA.size (); i++)
- {
- dblVarianceAA += (m_arVarianceAA [i] - dblMeanAA) * (m_arVarianceAA [i] - dblMeanAA);
- dblVarianceII += (m_arVarianceII [i] - dblMeanII) * (m_arVarianceII [i] - dblMeanII);
- }
-
- dblVarianceAA /= (double)m_arVarianceAA.size ();
- dblVarianceII /= (double)m_arVarianceII.size ();
- m_dblDistance = m_vUser.Norm (g_pCurrentScale);
-
- m_dblDiaAAMean /= (double)m_dwValidPoints;
- m_dblDiaIIMean /= (double)m_dwValidPoints;
- m_dblDiaAAMin = g_pCurrentScale->Distance (m_dblDiaAAMin);
- m_dblDiaAAMean = g_pCurrentScale->Distance (m_dblDiaAAMean);
- m_dblDiaAAMax = g_pCurrentScale->Distance (m_dblDiaAAMax);
- m_dblDiaIIMin = g_pCurrentScale->Distance (m_dblDiaIIMin);
- m_dblDiaIIMean = g_pCurrentScale->Distance (m_dblDiaIIMean);
- m_dblDiaIIMax = g_pCurrentScale->Distance (m_dblDiaIIMax);
- assert(arrayAA.size() == (size_t)m_dwValidPoints);
- assert(arrayII.size() == (size_t)m_dwValidPoints);
- // double diam = CMeanEstimate::GetMeanEstimate(&arrayAA);
- // m_dblDiaAAMean = (CMeanEstimate::IsANumber(diam)? diam : -1);
- m_dblDiaAAMean = CMeanEstimate::GetMeanEstimate(&arrayAA);
- m_dblDiaIIMean = CMeanEstimate::GetMeanEstimate(&arrayII);
- m_dblVarianceAA = dblVarianceAA;
- m_dblVarianceII = dblVarianceII;
- PrintDiameter();
- if (!CMeanEstimate::IsANumber(m_dblDiaAAMean))
- { //if is is infinite because of the estimate
- return false;
- }
- }
- else // de l'EIM
- {
- double dblMean = 0.0, dblMeanINT = 0.0;
- // double dblMeanEIMd = 0.0, dblMeanINTd = 0.0, dblMeanMEDd = 0.0;
- double dblVariance = 0.0, dblVarianceINT = 0.0;
- imt::Point invalidPoint, tmpPt;
- invalidPoint.x = -1;
- invalidPoint.y = -1;
-
- if ( m_res )
- {
- m_res->result->numberOfPoints = m_dwPoints;
- m_res->allocate_vectors( m_dwPoints );
- }
-
- // recherche du premier profil valide
- pInfo = &m_pMeasures [0];
- for (dw = 0; !pInfo->m_fValid; dw++)
- {
- if ( m_res )
- {
- m_res->result->vect_adventitia[dw] = invalidPoint;
- m_res->result->vect_media[dw] = invalidPoint;
- m_res->result->vect_intima[dw] = invalidPoint;
- }
- pInfo++;
- }
- // on est certain qu'un pInfo valide va �tre trouv�
- m_dblEIMMin = m_dblEIMMean = m_dblEIMMax = pInfo->m_dblEIM;
- m_dblINTMin = m_dblINTMean = m_dblINTMax = pInfo->m_dblINT;
- m_dblEIMdMean = pInfo->m_dblEIMd;
- m_dblINTdMean = pInfo->m_dblINTd;
- m_dblMEDdMean = pInfo->m_dblMEDd;
-
- // [JAK - 24/6/2002] no histogram window
- GraphMeanAddMeasure (true, pInfo->m_dblEIM);
- m_arVariance.push_back (g_pCurrentScale->Distance (pInfo->m_dblEIM));
- m_arVarianceINT.push_back (g_pCurrentScale->Distance (pInfo->m_dblINT));
- dblMean = g_pCurrentScale->Distance (pInfo->m_dblEIM);
- dblMeanINT = g_pCurrentScale->Distance (pInfo->m_dblINT);
-
- if ( m_res )
- {
- tmpPt.x = pInfo->m_Paroi[0].m_slope[1].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[1].m_ptDraw.y;
- m_res->result->vect_adventitia[dw] = tmpPt;
- tmpPt.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- m_res->result->vect_media[dw] = tmpPt;
- tmpPt.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- m_res->result->vect_intima[dw] = tmpPt;
- }
-
- dw++,pInfo++;
-
- while (dw < m_dwPoints)
- {
- if (pInfo->m_fValid)
- {
- m_dblEIMMean += pInfo->m_dblEIM;
- if (pInfo->m_dblEIM < m_dblEIMMin) m_dblEIMMin = pInfo->m_dblEIM;
- if (pInfo->m_dblEIM > m_dblEIMMax) m_dblEIMMax = pInfo->m_dblEIM;
-
- m_dblINTMean += pInfo->m_dblINT;
- if (pInfo->m_dblINT < m_dblINTMin) m_dblINTMin = pInfo->m_dblINT;
- if (pInfo->m_dblINT > m_dblINTMax) m_dblINTMax = pInfo->m_dblINT;
-
- m_dblEIMdMean += pInfo->m_dblEIMd;
- m_dblINTdMean += pInfo->m_dblINTd;
- m_dblMEDdMean += pInfo->m_dblMEDd;
-
- // [JAK - 24/6/2002] no histogram window
- GraphMeanAddMeasure (true, pInfo->m_dblEIM);
- m_arVariance.push_back (g_pCurrentScale->Distance (pInfo->m_dblEIM));
- m_arVarianceINT.push_back (g_pCurrentScale->Distance (pInfo->m_dblINT));
- dblMean += g_pCurrentScale->Distance (pInfo->m_dblEIM);
- dblMeanINT += g_pCurrentScale->Distance (pInfo->m_dblINT);
-
- if ( m_res )
- {
- tmpPt.x = pInfo->m_Paroi[0].m_slope[1].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[1].m_ptDraw.y;
- m_res->result->vect_adventitia[dw] = tmpPt;
- tmpPt.x = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[2].m_ptDraw.y;
- m_res->result->vect_media[dw] = tmpPt;
- tmpPt.x = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x;
- tmpPt.y = pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y;
- m_res->result->vect_intima[dw] = tmpPt;
- }
- }
- else
- {
- if ( m_res )
- {
- m_res->result->vect_adventitia[dw] = invalidPoint;
- m_res->result->vect_media[dw] = invalidPoint;
- m_res->result->vect_intima[dw] = invalidPoint;
- }
- }
- dw++;
- pInfo++;
- }
- if (m_vUser.Length () < QI_MIN)
- {
- PrintErrorQIMin();
- m_dblQI = 0.;
- }
- else
- {
- m_dblQI = double (m_dwValidPoints) / m_dwPoints;
- }
-
- // calcul de la variance
- dblMean /= (double)m_arVariance.size ();
- dblVariance = 0.0;
- dblMeanINT /= (double)m_arVarianceINT.size ();
- dblVarianceINT = 0.0;
- unsigned int i;
- for (i = 0; i < m_arVariance.size (); i++)
- dblVariance += (m_arVariance [i] - dblMean) * (m_arVariance [i] - dblMean);
- dblVariance /= (double)m_arVariance.size ();
- for (i = 0; i < m_arVarianceINT.size (); i++)
- dblVarianceINT += (m_arVarianceINT [i] - dblMeanINT) *
- (m_arVarianceINT [i] - dblMeanINT);
- dblVarianceINT /= (double)m_arVarianceINT.size ();
- m_dblDistance = m_vUser.Norm (g_pCurrentScale);
- // calcul des valeurs moyennes et mise � l'�chelle des normes
- m_dblEIMMean /= (double)m_dwValidPoints;
- m_dblEIMMin = g_pCurrentScale->Distance (m_dblEIMMin);
- m_dblEIMMean = g_pCurrentScale->Distance (m_dblEIMMean);
- m_dblEIMMax = g_pCurrentScale->Distance (m_dblEIMMax);
- m_dblINTMean /= (double)m_dwValidPoints;
- m_dblINTMin = g_pCurrentScale->Distance (m_dblINTMin);
- m_dblINTMean = g_pCurrentScale->Distance (m_dblINTMean);
- m_dblINTMax = g_pCurrentScale->Distance (m_dblINTMax);
- m_dblIA = m_dblINTMean / m_dblEIMMean;
-
- m_dblEIMdMean /= (double)m_dwValidPoints;
- m_dblINTdMean /= (double)m_dwValidPoints;
- m_dblMEDdMean /= (double)m_dwValidPoints;
- m_dblIAd = m_dblINTdMean / m_dblEIMdMean;
-
- //#ifdef VERSION_SHOW_VARIANCE // [JAK - 17/6/2002]
- m_dblVariance = dblVariance;
- //#endif
-
- // [JAK - 4/7/2002] IDS_EIM_RESULT4 = \tE .I.M.\nI.Q.: \t%.2f\nMaximale : \t%.3f mm\nMoyenne : \t%.3f mm\nEcart Type : \t%.3f mm\nMesures Valides :\td%
- PrintResult();
-
- if ( m_res )
- {
- m_res->result->imt_max = m_dblEIMMax;
- m_res->result->imt_mean = m_dblEIMMean;
- m_res->result->imt_standardDeviation = sqrt (dblVariance);
- m_res->result->intima_mean = m_dblINTMean;
- m_res->result->media_mean = m_dblEIMMean - m_dblINTMean;
- m_res->result->qualityIndex = m_dblQI;
- }
- }
- return (true);
- }
- }catch(...){ // [JAK - 5/7/2002]
- assert(0);
- // not very clean to catch any exception, but it is at least efficient
- //TODO change the "catch(...)" for something more precise like "catch(Float Divide by Zero)"
- m_uErrorID = IDS_EIM_FAILED;
- return (false); // aucune mesure valide
- }
- }
- }
- } // end of Update
- /*----------------------------------------------------------\
- | ComputeEIM |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | calcule l'�paisseur EIM et la distance au vecteur trac� |
- | par l'utilisateur � l'aide points d�tect�s |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- | pInfo : une info sur un segment de paroi |
- \----------------------------------------------------------*/
- void CEIMBase::ComputeEIM (CEIMInfo *pInfo)
- {
- pInfo->m_fValid = true;
- // en approximation, m_ptMiddle [0] suffit largement pour la distance, qui n'intervient
- // dans la mesure que pour �carter les points trop �loign�s de la moyenne
- pInfo->m_dblDist = CVector (pInfo->m_Paroi [0].m_slope [0].m_ptMiddle, pInfo->m_Paroi [0].m_vMeasure [0]).Norm ();
- pInfo->m_dblEIM = CVector (pInfo->m_Paroi [0].m_slope [0].m_ptMiddle, pInfo->m_Paroi [0].m_slope [1].m_ptMiddle).Norm ()
- - pInfo->m_Paroi [0].m_slope [0].m_dblMiddle
- + pInfo->m_Paroi [0].m_slope [1].m_dblMiddle;
- pInfo->m_dblINT = CVector (pInfo->m_Paroi [0].m_slope [0].m_ptMiddle, pInfo->m_Paroi [0].m_slope [2].m_ptMiddle).Norm ()
- - pInfo->m_Paroi [0].m_slope [0].m_dblMiddle
- + pInfo->m_Paroi [0].m_slope [2].m_dblMiddle;
- // dans le cas de la paroi, on additionne les deux �carts, car la paroi du bas est mesur�
- // dans le sens oppos� � la paroi du haut
- if (m_fDiameter)
- {
- pInfo->m_dblDia = CVector (pInfo->m_Paroi [0].m_slope [1].m_ptMiddle, pInfo->m_Paroi [1].m_slope [1].m_ptMiddle).Norm ()
- + pInfo->m_Paroi [0].m_slope [1].m_dblMiddle
- + pInfo->m_Paroi [1].m_slope [1].m_dblMiddle;
- }
- else // Calcul des moyennes des intensites entre les differents points
- {
- pInfo->m_dblEIMd = pInfo->m_dblINTd = pInfo->m_dblMEDd = 0.0;
- long dw, nb=0, nbTot=0;
- for ( dw=pInfo->m_Paroi[0].m_slope[0].m_dwMiddle; dw<pInfo->m_Paroi[0].m_slope[2].m_dwMiddle; dw++ )
- {
- nb++;
- nbTot++;
- pInfo->m_dblEIMd += m_bBuffer[dw];
- pInfo->m_dblINTd += m_bBuffer[dw];
- }
- if (nb != 0 ) // Contre la division par 0
- {
- pInfo->m_dblINTd /= (double) nb;
- }
- else
- {
- pInfo->m_dblINTd = 0;
- }
- nb = 0;
- for ( dw=pInfo->m_Paroi[0].m_slope[2].m_dwMiddle; dw<pInfo->m_Paroi[0].m_slope[1].m_dwMiddle; dw++ )
- {
- nb++;
- nbTot++;
- pInfo->m_dblEIMd += m_bBuffer[dw];
- pInfo->m_dblMEDd += m_bBuffer[dw];
- }
- if (nb != 0) // Contre la division par 0
- {
- pInfo->m_dblMEDd /= (double) nb;
- }
- else
- {
- pInfo->m_dblMEDd = 0;
- }
- if (nbTot != 0) // Contre la division par 0
- {
- pInfo->m_dblEIMd /= (double) nbTot;
- }
- else
- {
- pInfo->m_dblEIMd = 0;
- }
- }
- } // fin de ComputeEIM
-
- /*----------------------------------------------------------\
- | Direction |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Retourne la direction de la droite approxim�e constitu�e |
- | d'apr�s l'ensemble des points mesur�s! |
- \----------------------------------------------------------*/
- double CEIMBase::Direction()
- {
- double r = 0;
- double x = 0, y = 0;
- Point LastPoint( 0, 0 );
- double Valide = 0;
- double sx, sx2, sy, sy2;
- int nbPoints;
- double xmin, xmax, ymin, ymax;
- double moyx, moyy, stdx, stdy;
- if (m_pMeasures)
- {
- sx = sx2 = sy = sy2 = 0.0;
- nbPoints = 0;
- // Calcul de la somme des x et des y et de la somme des x2 et des y2
- CEIMInfo *pInfo = &m_pMeasures[0];
- for (long dw = 0; dw < m_dwPoints; dw++)
- {
- if (pInfo->m_fValid)
- {
- if (dw)
- {
- x = (pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x - LastPoint.x);
- y = (pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y - LastPoint.y);
- if (x)
- {
- sx += x;
- sx2 += (x * x);
- sy += y;
- sy2 += (y * y);
- nbPoints++;
- }
- }
- LastPoint = pInfo->m_Paroi[0].m_slope[0].m_ptDraw;
- }
- pInfo++;
- }
- // Calcul des moyennes et des �carts types
- if (nbPoints != 0)
- {
- moyx = sx / (double) nbPoints;
- moyy = sy / (double) nbPoints;
- stdx = sqrt( (sx2 / (double) nbPoints) - sx * sx);
- stdy = sqrt( (sy2 / (double) nbPoints) - sy * sy);
- xmin = moyx - 2 * stdx;
- xmax = moyx + 2 * stdx;
-
- ymin = moyy - 2 * stdy;
- ymax = moyy + 2 * stdy;
- }
- pInfo = &m_pMeasures[0];
- for (long dw = 0; dw < m_dwPoints; dw++)
- {
- if (pInfo->m_fValid)
- {
- if (dw)
- {
- x = (pInfo->m_Paroi[0].m_slope[0].m_ptDraw.x - LastPoint.x);
- y = (pInfo->m_Paroi[0].m_slope[0].m_ptDraw.y - LastPoint.y);
- if (x)
- {
- // if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax))
- {
- r += y / x;
- Valide++;
- }
- }
- }
- LastPoint = pInfo->m_Paroi[0].m_slope [0].m_ptDraw;
- }
- pInfo++;
- }
- }
- if (Valide < 20) return 0; // Nombre de points valides insuffisants
- Point PtDirect(100, (int) (100.0 * r / Valide));
- PtDirect.Offset(m_vUser.StartPoint());
- if ( (m_vUser.Angle(PtDirect) > 20) && (m_vUser.Angle(PtDirect) < 160) ) return 0;
- return (r / Valide);
- }
- unsigned int CEIMBase::GetErrorID(void)
- {
- return m_uErrorID;
- }
|