|
|
@@ -1,2610 +0,0 @@
|
|
|
-/*******************************************************************\
|
|
|
- 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;
|
|
|
-}
|