| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992 |
- /**********************************************************************\
- Fichier : Plaque.cpp
- Date : 18/04/98
- Version : 1.100
- Description : classe de calcul & affichage d'une épaisseur de plaque
- |**********************************************************************|
- Bugs:
- Notes:
- |**********************************************************************|
- Historique :
- 18/04/98 1.100 : Optimisation (2x plus rapide)
- Suppression de l'utilisation d'une region pour la mesure,
- la figure est trop complexe est beaucoup de points sont
- oubliés (il suffit de l'afficher dans OnDraw pour s'en rendre
- compte).
- Suppression de m_nPointsDedans, qui au vu de l'algo était le nombre
- de points à l'extérieur de la plaque!!
- Réunion de tous les types de mesure de plaque (NB, RGB, manuel) dans
- cette classe
- 07/02/98 1.000 : Première version
- \*******************************************************************/
- /*------------------------------------------------------------------\
- Includes
- \------------------------------------------------------------------*/
- #include <QImage>
- #include "PlaqueBase.h"
- #include "Ressource.h"
- #include "MeanEstimate.h"
- #include "CPlaqueResult.h"
- #include "PlaqueResult.h"
- #include "ToolsMath.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #define sqr(a) ((a) * (a))
- inline int Distance2D (const Point &pt1, const Point &pt2)
- {
- return int (sqrt((double) sqr(pt1.x - pt2.x) + (double) sqr(pt1.y - pt2.y)));
- }
- CPlaqueBase::CPlaqueBase()
- {
- m_etudie = NULL;
- RAZ();
- m_iTache = 0;
- m_clrVert = 0 | (255 << 16) | (0 << 8);
- m_clrBleue = 0 | (0 << 16) | (255 << 8);
-
- m_debug1 = 1;
- m_debug2 = 2;
- m_debug3 = 3;
- m_debug4 = 4;
- m_debug5 = 5;
- }
- CPlaqueBase::~CPlaqueBase()
- {
- delete[] m_etudie;
- }
- void CPlaqueBase::RAZ()
- {
- m_Etape = etapeRien;
- m_nVecteursTrouves = 0;
- m_nPtLongeantPlaque = 0;
- m_ptInferieur.x = 0;
- m_ptInferieur.y = 0;
- m_pointLimite1.x = 0;
- m_pointLimite1.y = 0;
- m_pointLimite2.x = 0;
- m_pointLimite2.y = 0;
- m_iMax = 0;
- m_IntervallesIntensite[0] = 0;
- m_IntervallesIntensite[1] = 0;
- m_IntervallesIntensite[2] = 0;
- // m_ptList.clear();
- }
- /*----------------------------------------------------------\
- | Mesurer |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | On a saisi les segments. Mesurer l'épaisseur de droites |
- | perpendiculaires, jusqu'au 1° pt vert |
- | précédemment coloré par Threshold (). |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- const short NORTHOMAX = 1000;
- const short NMAXERREURS = 3; // Erreurs avant de déclarer le segment fini
- int CPlaqueBase::Mesurer_3 (int iMax)
- {
- short iVector;
- int retour;
-
- m_nSommeLongueurs = 0;
- m_nMesures = 0;
- m_nLongueurMax = 0;
- m_nVecteursTrouves = 0;
- m_nMesuresTotal = 0;
- // m_ptList.clear();
-
- // Seuillage par propagation
- retour = Threshold(iMax);
- // Mesurer les limites de la plaque
- for (iVector = 0; iVector < (m_nPtLongeantPlaque-1); iVector++)
- {
- retour = Mesurer_3_1Segment(m_tPtLongeantPlaque [iVector], m_tPtLongeantPlaque [iVector+1]);
- }
-
- // Et sa surface, son intensité
- retour = CalculerSurfaceEtIntensitePlaque (false);
- return retour;
- }
-
- //***** Mesurer 1 des segments définis / utilisateur
- int CPlaqueBase::Mesurer_3_1Segment (const Point &pt1, const Point &pt2)
- {
- CVector vectSegment(pt1.x, pt1.y, pt2.x, pt2.y);
- CVector vectOrtho;
- Point ptAVerifier;
- long iSegment, iLong;
- bool fFound; // Du segment à mesurer
- int nLongueurSegment;
- int retour;
- retour = 0;
- GraphMeanInit();
- Point pt( pt1.x, pt1.y );
- // Parcourir le segment et, tous les NINTERVALLE, calculer l'épaisseur
- vectOrtho = vectSegment.Orthogonal (pt, m_nSensTrigo); // 0 = sens inverse trigo
- // la vérification de l'appartenance du point à la région de traitement ralentit certainement
- // mais je ne trace apparemment pas les droites de la même manière que Windows et certains
- // points des droites des extrémités n'appartiennent pas à la région
- for (iSegment = 0; iSegment < vectSegment.Norm (); iSegment++)
- {
- vectOrtho.MoveTo(vectSegment [iSegment]);
- m_nMesuresTotal ++;
- // on effectue une mesure seulement lorsque la plaque touche la paroi
- // autrement dit, le premier point du vecteur orthogonal ne doit pas être vert
- ptAVerifier.x = vectOrtho[1].x;
- ptAVerifier.y = vectOrtho[1].y;
- // seules les extrémités des segments devraient poser des problèmes d'appartenance
- if ( m_rgnATraiter.PtInRegion(&ptAVerifier)
- && PointInBufferResult(ptAVerifier)
- && (GetPixelResult(ptAVerifier.x, ptAVerifier.y) != m_clrVert) // [LAU - 13/1/2006]
- )
- {
- fFound = false;
- // on cherche la fin de la plaque (<=> premier point vert rencontré)
- // on s'arrête dès que le point ne fait plus partie de la région de traitement
- for (iLong = 2;(!fFound )&& (iLong < NORTHOMAX) && m_rgnATraiter.PtInRegion (&ptAVerifier); iLong++)
- {
- ptAVerifier.x = vectOrtho [iLong].x;
- ptAVerifier.y = vectOrtho [iLong].y;
-
- if ( PointInBufferResult(ptAVerifier)
- && (GetPixelResult(ptAVerifier.x, ptAVerifier.y) == m_clrVert)
- )
- {
- fFound = true;
- // On a une longueur
- nLongueurSegment = iLong - 1;
- m_nSommeLongueurs += nLongueurSegment;
- m_nMesures ++;
- if ((unsigned int) nLongueurSegment > (unsigned int) m_nLongueurMax)
- m_nLongueurMax = nLongueurSegment;
- if (nLongueurSegment)
- GraphMeanAddMeasure(true, nLongueurSegment);
- m_tbPtsTrouvesFin [m_nVecteursTrouves] = vectOrtho [iLong];
- // Ajouter le segment à ceux à afficher
- /* Point pt;
- pt.x = vectOrtho[iLong].x;
- pt.y = vectOrtho[iLong].y;
- m_ptList.push_back( pt );
- */
- if ((m_nVecteursTrouves + 1) < NBVECTEURSMAX)
- {
- m_nVecteursTrouves++;
- }
- }
- }
- }
- }
- return retour;
- }
- /*----------------------------------------------------------\
- | CalculerSensVecteurs |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Calcule de quel côté est le pt minimum par rapport aux |
- | segments définis par l'utilisateur -> m_nSensTrigo |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- void CPlaqueBase::CalculerSensVecteurs()
- {
- CVector vecteur1erSegment (m_tPtLongeantPlaque [0].x, m_tPtLongeantPlaque [0].y,
- m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].x, m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].y);
- if (vecteur1erSegment.m_fHorizontal == true)
- {
- // Vecteur horizontal : au dessus ou en dessous ?
- if (m_tPtLongeantPlaque [0].y < m_ptInferieur.y)
- {
- // En dessous
- if (m_tPtLongeantPlaque [0].x > m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].x)
- {
- m_nSensTrigo = 1;
- }
- else
- {
- m_nSensTrigo = 0;
- }
- }
- else
- {
- // Au dessus
- if (m_tPtLongeantPlaque [0].x > m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].x)
- {
- m_nSensTrigo = 0;
- }
- else
- {
- m_nSensTrigo = 1;
- }
- }
- }
- else
- {
- // Vecteur vertical : à gauche ou à droite ?
- if (m_tPtLongeantPlaque [0].x < m_ptInferieur.x)
- {
- // à droite
- if (m_tPtLongeantPlaque [0].y > m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].y)
- {
- m_nSensTrigo = 0;
- }
- else
- {
- m_nSensTrigo = 1;
- }
- }
- else
- {
- // à gauche
- if (m_tPtLongeantPlaque[0].y > m_tPtLongeantPlaque[m_nPtLongeantPlaque-1].y)
- {
- m_nSensTrigo = 1;
- }
- else
- {
- m_nSensTrigo = 0;
- }
- }
- }
- }
- /*----------------------------------------------------------\
- | SetRegion |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Crée une région polygonale, composée des segments |
- | indiqués par l'utilisateur, de 2 segments sur les côtés, |
- | orthogonaux aux 1° et dernier segments utilisateur, |
- | et de taille suffisante pour que le m_ptInferieur |
- | soit dedans. |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- bool CPlaqueBase::SetRegion
- ( const CVector &vFirst,
- const CVector &vLast,
- int iLength )
- {
- CVector vOrtho;
- Point pt( m_tPtLongeantPlaque[m_nPtLongeantPlaque-1].x, m_tPtLongeantPlaque[m_nPtLongeantPlaque-1].y );
- vOrtho = vLast.Orthogonal (pt, m_nSensTrigo); // 0 = sens inverse trigo
- m_pointLimite1.x = vOrtho[iLength].x;
- m_pointLimite1.x = vOrtho[iLength].x;
- m_pointLimite1.y = vOrtho[iLength].y;
- m_tPtLongeantPlaque[m_nPtLongeantPlaque] = m_pointLimite1;
- pt = Point( m_tPtLongeantPlaque [0].x, m_tPtLongeantPlaque [0].y );
- vOrtho = vFirst.Orthogonal (pt, m_nSensTrigo); // 0 = sens inverse trigo
- m_pointLimite2.x = vOrtho[iLength].x;
- m_pointLimite2.y = vOrtho[iLength].y;
- m_tPtLongeantPlaque[m_nPtLongeantPlaque+1] = m_pointLimite2;
-
- // Créer le polygone
- m_rgnATraiter.DeleteObject ();
- /*
- m_debug1 = m_nPtLongeantPlaque;
- m_debug2 = m_pointLimite1.x;
- m_debug3 = m_pointLimite1.y;
- m_debug4 = m_pointLimite2.x;
- m_debug5 = m_pointLimite2.y;
- */
- return (m_rgnATraiter.CreatePolygonRgn (m_tPtLongeantPlaque, m_nPtLongeantPlaque + 2));
- } // fin de SetRegion
- int CPlaqueBase::ParametrerRegionATraiter ()
- {
- int retour;
- retour = 0;
-
- assert(m_nPtLongeantPlaque >= 2);
- // Vecteur entre le 1° et le dernier pt utilisateur
- CVector vGlobal (m_tPtLongeantPlaque [0].x, m_tPtLongeantPlaque [0].y,
- m_tPtLongeantPlaque [m_nPtLongeantPlaque - 1].x, m_tPtLongeantPlaque [m_nPtLongeantPlaque - 1].y),
- // Dernier vecteur tracé (peut être égal à vGlobal)
- vFirst (m_tPtLongeantPlaque[0].x, m_tPtLongeantPlaque[0].y,
- m_tPtLongeantPlaque[1].x, m_tPtLongeantPlaque[1].y),
- // Dernier vecteur tracé (peut être égal à vFirst)
- vLast (m_tPtLongeantPlaque[m_nPtLongeantPlaque - 2].x, m_tPtLongeantPlaque[m_nPtLongeantPlaque - 2].y,
- m_tPtLongeantPlaque[m_nPtLongeantPlaque - 1].x, m_tPtLongeantPlaque[m_nPtLongeantPlaque - 1].y);
-
- Point ptProjected;
- int nLongueurPlaque, nDistanceAPtInferieur;
- bool fResult;
- CalculerSensVecteurs ();
- // Longueur de la plaque indiquée par l'utilisateur
- nLongueurPlaque = int(vGlobal.Norm());
-
- // Limiter la longueur des segments de côté
- Point pti( m_ptInferieur.x, m_ptInferieur.y );
- ptProjected.x = vGlobal.Projected (pti).x;
- ptProjected.y = vGlobal.Projected (pti).y;
- nDistanceAPtInferieur = int (CVector (ptProjected.x, ptProjected.y, m_ptInferieur.x,m_ptInferieur.y).Norm () + 5);
- if (nDistanceAPtInferieur > nLongueurPlaque)
- nLongueurPlaque = nDistanceAPtInferieur;
- // pour optimiser, on diminue la taille des droites orthogonales d'encadrement
- // pour que la tache soit à la limite
- nLongueurPlaque++;
- do
- {
- nLongueurPlaque--;
- fResult = SetRegion (vFirst, vLast, nLongueurPlaque);
- } while ((fResult == true) && m_rgnATraiter.PtInRegion (&m_ptInferieur) && (nLongueurPlaque > 1));
- if ((fResult == true) && (nLongueurPlaque > 1))
- {
- nLongueurPlaque++;
- fResult = SetRegion (vFirst, vLast, nLongueurPlaque);
- }
- if (fResult == true)
- {
- retour = 40;
-
- m_debug1 = nLongueurPlaque;
- m_debug2 = ptProjected.x;
- m_debug3 = ptProjected.y;
- m_debug4 = nDistanceAPtInferieur;
- m_debug5 = 2222;
- }
- if ((fResult == false) || (nLongueurPlaque <= 1))
- {
- retour = 41;
- m_Etape = etapeSegments;
- m_nPtLongeantPlaque = 0;
- }
- else if (m_rgnATraiter.PtInRegion(&m_ptInferieur) == false)
- {
- retour = 42;
- m_Etape = etapeTacheSeuil; // Recommencer cette étape
- }
- return retour;
- }
- /*----------------------------------------------------------\
- | TraiterPoint |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Propagation à partir du pt minimal : colorer en vert les |
- | points sous le seuil indiqué |
- | |
- | modifié pour limiter la profondeur de récursion |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- int CPlaqueBase::TraiterPoint (int x, int y)
- {
- unsigned char bCheck[9];
- int i, xx, yy, xMin, yMin, xMax, yMax;
- int retour;
- bool bool0;
- bool bool1;
- bool bc0;
- retour = 0;
- m_debug1++;
- // m_wimg.SaveImgAsRaw();
- // if (m_debug1 == 40700)
- if (((m_debug1 % 2500) == 0) && (m_debug1 != 0))
- {
- m_debug1 = m_debug1;
- }
- assert(PointInBufferResult(x, y) && (m_type != typeUndefined));
- SetPixelResult(x, y);
- xMin = max(0, x - 1);
- xMax = min(x + 1, GetWidth() - 1);
- yMin = max(0, y - 1);
- yMax = min(y + 1, GetHeight() - 1);
-
- i = 0;
- for (xx = xMin; xx <= xMax; xx++)
- {
- for (yy = yMin; yy <= yMax; yy++)
- {
- assert (PointInBufferResult(xx, yy));
- /* bCheck [i] = ((xx != x) || (yy != y))
- && ((m_type == typeRGB) ?
- IsColor (xx, yy) :
- (GetIntensityResult(xx, yy) <= m_iMax)
- )
- && (GetPixelResult(xx, yy) != m_clrVert) // [LAU - 13/1/2006]
- && m_rgnATraiter.PtInRegion0(xx, yy);
- */
- bool0 = ((xx != x) || (yy != y));
- if ((bool0) && (m_type == typeRGB))
- {
- bc0 = IsColor (xx, yy);
- }
- else
- {
- bc0 = (GetIntensityResult(xx, yy) <= m_iMax);
- }
-
- bool1 = (bool0) && (bc0) && (GetPixelResult(xx, yy) != m_clrVert) && m_rgnATraiter.PtInRegion0(xx, yy);
-
- bCheck [i] = bool1 ? 1:0;
- i++;
- }
- }
-
- i = 0;
- for (xx = xMin; xx <= xMax; xx++)
- {
- for (yy = yMin; yy <= yMax; yy++)
- {
- if ((int) bCheck [i++] > 0)
- {
- TraiterPoint(xx, yy);
- }
- }
- }
- return retour;
- }
- int CPlaqueBase::Threshold( int iMax )
- {
- int retour;
-
- // AffectLeadResult();
- // Décompte de la répartition des points
- m_iMax = iMax;
- if (!SuiviContour())
- {
- m_debug1 = 0;
- retour = TraiterPoint(m_ptInferieur.x, m_ptInferieur.y);
- }
- // Fermeture et effacement des petites régions.
- DoClosing();
- DoBlobColoring();
-
- return retour;
- } // fin de Threshold
- /*----------------------------------------------------------\
- | Surface de la plaque |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Crée une région polygonale, composée des segments |
- | indiqués par l'utilisateur, des extrémités trouvées. |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- int CPlaqueBase::CalculerSurfaceEtIntensitePlaque (bool bManuelle)
- {
- int nIntensite;
- Rect rectEnglobant;
- Point pt;
- int retour;
- retour = 0;
- if (bManuelle)
- {
- m_nSensTrigo = 0;
- assert (m_nVecteursTrouves == 0); // Pour être sûr
- }
- // Suppression de l'utilisation d'une region pour la mesure:
- // la figure est trop complexe et beaucoup de points sont oubliés
- // (il suffit de l'afficher dans OnDraw pour s'en rendre compte).
- // seule la région de traitement se monte fiable (peu de points, points éloignés)
- rectEnglobant = m_rgnATraiter.GetRgnBox();
- m_nPointsDansPlaque = 0;
- m_iSommeIntensitesPlaque = 0;
- memset (m_IntervallesIntensite, 0, sizeof (m_IntervallesIntensite));
-
- GraphMeanInit();
- // Calculer la surface & l'intensité & l'Histogramme.
- for (pt.y = rectEnglobant.top; pt.y < rectEnglobant.bottom; pt.y++)
- {
- for (pt.x = rectEnglobant.left; pt.x < rectEnglobant.right; pt.x++)
- {
- if ((GetPixelResult(pt.x, pt.y) != m_clrVert) && (m_rgnATraiter.PtInRegion(&pt)))
- {
- nIntensite = GetIntensityResult(pt); // - m_iTache;
- m_nPointsDansPlaque++;
- GraphMeanAddMeasure(true, nIntensite);
- m_iSommeIntensitesPlaque += nIntensite;
- if (nIntensite < 120)
- m_IntervallesIntensite [0]++;
- else if (nIntensite < 200)
- m_IntervallesIntensite [1]++;
- else
- m_IntervallesIntensite [2]++;
- }
- }
- }
- if (m_iSommeIntensitesPlaque < 0)
- {
- retour = 50;
- }
- if (bManuelle)
- {
- int i1, i2;
- int nPt1 = -1, nPt2 = -1;
- int nDistance = 0, nDistanceMax = 0;
- int iSegment, iOrtho1, iOrtho2;
- // Calculer la longueur de la plaque (les 2 pts les + éloignés)
- for (i1 = 0; i1 < m_nPtLongeantPlaque - 1; i1++)
- for (i2 = i1 + 1; i2 < m_nPtLongeantPlaque; i2++)
- if ((nDistance = Distance2D (m_tPtLongeantPlaque [i1], m_tPtLongeantPlaque [i2]))
- > nDistanceMax)
- {
- nDistanceMax = nDistance;
- nPt1 = i1;
- nPt2 = i2;
- }
- if (!bManuelle) GraphMeanInit();
- m_nLongueurMax = 0;
- m_nSommeLongueurs = 0;
- m_nMesures = 0;
- // Calculer la largeur
- if (nDistanceMax)
- {
- // Vecteur le long de la plaque
- CVector vectLong (m_tPtLongeantPlaque [nPt1].x,m_tPtLongeantPlaque [nPt1].y,
- m_tPtLongeantPlaque [nPt2].x, m_tPtLongeantPlaque [nPt2].y);
- CVector vectOrtho;
- // Pour essai
- if (m_rgnATraiter.PtInRegion0(vectLong [5].x, vectLong [5].y) )
- {
- retour = 52;
- }
- if (m_rgnATraiter.PtInRegion0(vectLong [0].x, vectLong [0].y))
- {
- retour = 52;
- }
- for (iSegment = 0; iSegment < vectLong.Norm () - 1; iSegment ++)
- {
- vectOrtho = vectLong.Orthogonal (vectLong [iSegment], 0);
- for ( iOrtho1 = 0;
- iOrtho1 < vectLong.Norm () && (m_rgnATraiter.PtInRegion0(vectOrtho [iOrtho1].x,vectOrtho [iOrtho1].y));
- iOrtho1 ++);
- for ( iOrtho2 = 0;
- iOrtho2 > -vectLong.Norm () && (m_rgnATraiter.PtInRegion0(vectOrtho [iOrtho2].x,vectOrtho [iOrtho2].y));
- iOrtho2 --);
- if (iOrtho1 - iOrtho2 > ((long) m_nLongueurMax))
- m_nLongueurMax = iOrtho1 - iOrtho2;
- m_nSommeLongueurs += iOrtho1 - iOrtho2;
- if (!bManuelle)
- {
- if (iOrtho1 - iOrtho2)
- GraphMeanAddMeasure(true, iOrtho1 - iOrtho2);
- }
- m_nMesures++;
- }
- }
- }
- return retour;
- }
- int CPlaqueBase::calculPlaque2(QImage *h_image, int nbPts, unsigned char *points)
- {
- unsigned char *dadd;
- unsigned char a, b, c, d;
- Point point;
- int npt;
- int retour;
- m_result = h_image;
- if ( !m_etudie )
- {
- m_etudie = new unsigned long[ GetWidth() * GetHeight() ];
-
- }
- m_wimg.Del();
- m_wimg.Create(TYPE_UCHAR, GetWidth(), GetHeight());
- m_wimg.Fill(0);
- m_type = typeManual;
- retour = 0;
- npt = 0;
-
- dadd = points;
- do
- {
- a = *dadd;
- dadd++;
- b = *dadd;
- dadd++;
- c = *dadd;
- dadd++;
- d = *dadd;
- dadd++;
-
- point.x = d;
- point.x = point.x | (c << 8);
- point.x = point.x | (b << 16);
- point.x = point.x | (a << 24);
- a = *dadd;
- dadd++;
- b = *dadd;
- dadd++;
- c = *dadd;
- dadd++;
- d = *dadd;
- dadd++;
-
- point.y = d;
- point.y = point.y | (c << 8);
- point.y = point.y | (b << 16);
- point.y = point.y | (a << 24);
-
- // if (m_nPtLongeantPlaque < NBPTSLONGEANTMAX)
- {
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = point;
- m_nPtLongeantPlaque++;
- }
- npt++;
- } while (npt < nbPts);
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = m_tPtLongeantPlaque [0];
- m_nPtLongeantPlaque++;
- retour = CalculerPlaqueManuelle();
- return retour;
- }
- /*----------------------------------------------------------\
- | Surface de la plaque |
- |-----------------------------------------------------------|
- | DESCRIPTION : |
- | Crée une région polygonale, composée des segments |
- | indiqués par l'utilisateur, des extrémités trouvées. |
- |-----------------------------------------------------------|
- | PARAMETRES : |
- \----------------------------------------------------------*/
- int CPlaqueBase::CalculerPlaqueManuelle ()
- {
- int retour;
- // AffectLeadResult();
- // Créer le polygone
- m_rgnATraiter.DeleteObject();
-
- if (!m_rgnATraiter.CreatePolygonRgn(m_tPtLongeantPlaque, m_nPtLongeantPlaque))
- {
- retour = 31;
- return retour;
- }
-
- retour = CalculerSurfaceEtIntensitePlaque(true);
- return retour;
- }
- bool CPlaqueBase::IsBorder(int x, int y)
- {
- if (!((m_type == typeRGB) ? !IsColor(x, y) :
- (GetIntensityResult(x, y) > m_iMax)))
- { // On considère qu'il faut être dans la plaque!
- return false;
- }
- // L'aspect static de ces 7 variables est purement dans un but d'économie de mémoire...
- static int Xmin, Xmax, xx, Ymin, Ymax, yy, NbPoints;
- Xmin = max(0, x-1);
- Xmax = min(x+1, GetWidth() - 1);
- Ymin = max(0, y-1);
- Ymax = min(y+1, GetHeight() - 1);
- // On compte le nombre de points en-plaque autour du point étudié
- NbPoints = 0;
- for(xx = Xmin; xx <= Xmax; xx++)
- {
- for(yy = Ymin; yy <= Ymax; yy++)
- {
- if (((xx != x) || (yy != y)) &&
- ((m_type == typeRGB) ? !IsColor(xx, yy) :
- (GetIntensityResult(xx, yy) > m_iMax)))
- {
- NbPoints++;
- }
- }
- }
- // Ce point est considéré comme faisant partie de la frontière s'il possède
- // plus de 3 points en-plaque autour de lui, et s'il n'est pas au milieu de
- // la plaque (id est tout point autour de lui en-plaque!)
- if ((NbPoints < 3) || (NbPoints == (Xmax-Xmin+1)*(Ymax-Ymin+1)-1))
- {
- return false;
- }
- return true;
- }
- bool CPlaqueBase::SuiviContourLocal(int x, int y, double Xd, double Yd, bool Initialise)
- {
- static CVector VectBordFin;
- static int Width;
- static bool* TabPtParcourus = NULL;
- // (TabPtParcourus[x+Width*y] == true) s'il le point (x,y) à été parcourus
- if (Initialise)
- {
- Width = GetWidth();
- delete [] TabPtParcourus;
- TabPtParcourus = new bool[Width * GetHeight()];
- memset(TabPtParcourus, 0, Width * GetHeight());
- VectBordFin = CVector(m_tPtLongeantPlaque[m_nPtLongeantPlaque-1].x,m_tPtLongeantPlaque[m_nPtLongeantPlaque-1].y,
- m_pointLimite1.x,m_pointLimite1.y);
- return true;
- }
- static int xx, yy; // L'aspect static est purement dans un but d'économie de mémoire...
- // On marque ce point comme parcourus
- TabPtParcourus[x+y*Width] = true;
- // On conserve l'ancienne valeur de la couleur pour pouvoir la restaurer
- unsigned long OldPixelColor = GetPixelEtudie(x, y);
- // On dessine en bleu le point étudié (appartenant à priori au contour)
- SetPixelEtudie(x, y, m_clrBleue);
- // On a fini avec succes la mesure si le point étudié touche le 2nd bord jaune!
- Point pt = VectBordFin.Projected(Point(x,y));
- if (Distance2D(Point(pt.x,pt.y) , Point(x,y)) < 2) return true;
- int Xbest, Ybest;
- Xbest = 0;
- Ybest = 0;
-
- // L'aspect static de ces 6 variables est purement dans un but d'économie de mémoire...
- static double Vbest;
- static bool Valide;
- static int M;
- static double XdNew;
- static double YdNew;
- static double PScal;
- int dimension = 1;
- Valide = false; Vbest = 1;
- while (!Valide)
- {
- Vbest = 0.25 * (4 - dimension);
- // On cherche les coordonnées du point ou la "pertinence" est la plus elevé
- for(xx = -dimension; xx <= dimension; xx++)
- {
- for(yy = -dimension; yy <= dimension; yy++)
- {
- // On regarde la pertinence de ce point environnant...
- if ((xx) || (yy))
- {
- // PScal = (Xd *xx + Yd *yy)/sqrt(xx*xx+yy*yy);
- PScal = (Xd *xx + Yd *yy) / sqrt((double) xx * xx + (double) yy * yy); // MAJ2005
- if ((PScal > Vbest) &&
- (m_rgnATraiter.PtInRegion0(x+xx, y+yy)) &&
- (!TabPtParcourus[(x+xx)+(y+yy)*Width]) &&
- (IsBorder(x+xx, y+yy)))
- {
- Vbest = PScal;
- Xbest = xx;
- Ybest = yy;
- }
- }
- }
- }
- if (Vbest != 0.25*(4 - dimension))
- {
- M = max(abs(Xbest), abs(Ybest));
- XdNew = Xbest * M + Xd * 3 * dimension;
- YdNew = Ybest * M + Yd * 3 * dimension;
- PScal = sqrt(XdNew * XdNew + YdNew * YdNew);
- if (SuiviContourLocal(x + Xbest / M, y + Ybest / M, XdNew / PScal, YdNew / PScal))
- {
- Valide = true;
- break;
- }
- else
- {
- Valide = false; // On restaure cette variable static au cas où...
- TabPtParcourus[(x + Xbest) + (y + Ybest) * Width] = true;
- }
- }
- else
- {
- // On agrandi la fenetre de recherche...
- if (dimension < 4) dimension++;
- else break;
- }
- }
- if (!Valide)
- {
- // On remet la couleur initial du point
- SetPixelEtudie(x, y, OldPixelColor);
- return false;
- }
- return true;
- }
- bool CPlaqueBase::SuiviContour()
- {
- // On cherche le début de la plaque le long du 1er bord jaune
- CVector vectSegment(m_pointLimite2.x, m_pointLimite2.y, m_tPtLongeantPlaque[0].x, m_tPtLongeantPlaque[0].y);
- int i = 0;
- // On prend le premier point entrant dans la plaque!
- while(!((m_type == typeRGB) ?
- !IsColor(vectSegment[i].x, vectSegment[i].y) :
- (GetIntensityResult(vectSegment[i].x, vectSegment[i].y) > m_iMax)))
- {
- i++;
- if (!PointInBufferResult(vectSegment[i].x, vectSegment[i].y)) return false;
- }
- double Xd, Yd, d; // Direction initiale de recherche de contour...
- Xd = m_tPtLongeantPlaque[1].x - m_tPtLongeantPlaque[0].x;
- Yd = m_tPtLongeantPlaque[1].y - m_tPtLongeantPlaque[0].y;
- d = sqrt(Xd * Xd + Yd * Yd);
- Xd = Xd/d;
- Yd = Yd/d;
- int Compteur = 0;
- bool MesureValide = false;
- while ((!MesureValide) && (Compteur++ < 5)) // On fait 5 essais maximum...
- {
- CopyResultDansEtudie();
-
- // On espère avoir une frontière de la plaque valide en ce point...
- SuiviContourLocal(0, 0, 0, 0, true); // Initialisation de la fonction!
- MesureValide = SuiviContourLocal(vectSegment[i].x, vectSegment[i].y, Xd, Yd);
- if (!MesureValide)
- {
- // La première mesure n'est pas valide...
- // On cherche le premier point sortant de la plaque précedemment détectée!
- while ((m_type == typeRGB) ?
- !IsColor(vectSegment[i].x, vectSegment[i].y) :
- (GetIntensityResult(vectSegment[i].x, vectSegment[i].y) > m_iMax))
- {
- i++;
- if (!PointInBufferResult(vectSegment[i].x, vectSegment[i].y)) return false;
- }
- // On cherche le premier point entrant dans la plaque!
- while(!((m_type == typeRGB) ?
- !IsColor(vectSegment[i].x, vectSegment[i].y) :
- (GetIntensityResult(vectSegment[i].x, vectSegment[i].y) > m_iMax)))
- {
- i++;
- if (!PointInBufferResult(vectSegment[i].x, vectSegment[i].y)) return false;
- }
- }
- }
- if (!MesureValide) return false;
- #ifdef _DEBUG
- // On affiche le résultat de l'algo de repérage du contour plaque.
- // m_pLeadResult->Copy(m_LeadEtudie);
- #endif // _DEBUG
- // Remplissage de la partie hors-plaque en vert
- SuiviContourRemplis(m_ptInferieur.x, m_ptInferieur.y);
- return true;
- }
- void CPlaqueBase::SuiviContourRemplis(int x, int y)
- {
- assert(PointInBufferResult(x, y) && (m_type != typeUndefined));
- assert(GetPixelEtudie(x, y) != m_clrBleue);
- assert(GetPixelResult(x, y) != m_clrVert);
- int xx, Xmin, Xmax, yy, Ymin, Ymax;
- // On dessine en vert le point hors-plaque étudié
- SetPixelResult(x, y);
- Xmin = max(0, x-2);
- Xmax = min(x+2, GetWidth() - 1);
- Ymin = max(0, y-2);
- Ymax = min(y+2, GetHeight() - 1);
- // On compte le nombre de points frontière autour du point étudié
- double NbPoints = 0;
- for(xx = Xmin; xx <= Xmax; xx++)
- {
- for(yy = Ymin; yy <= Ymax; yy++)
- {
- if (((xx != x) || (yy != y)) &&
- (GetPixelEtudie(xx, yy) == m_clrBleue))
- {
- NbPoints++;
- }
- }
- }
- // Ce point est à la fin de l'arbre de parcours si il possède 2 points ou plus
- // appartenant à la frontières à coté de lui
- if (NbPoints > 0) return;
- Xmin = max(0, x-1);
- Xmax = min(x+1, GetWidth() - 1);
- Ymin = max(0, y-1);
- Ymax = min(y+1, GetHeight() - 1);
- for (xx = Xmin; xx <= Xmax; xx++)
- {
- for (yy = Ymin; yy <= Ymax; yy++)
- {
- if (((xx != x) || (yy != y)) &&
- (m_rgnATraiter.PtInRegion0(xx, yy)) &&
- (GetPixelEtudie(xx, yy) != m_clrBleue) &&
- (GetPixelResult(xx, yy) != m_clrVert))
- { // Le point (xx, yy) est donc hors-plaque et non traité
- SuiviContourRemplis(xx, yy);
- }
- }
- }
- }
- // [LAU - 2/5/2006] Calcule la somme des longeurs entre les points enregistrés longeant la plaque
- double CPlaqueBase::Get_SommeLongueurs()
- {
- double dist = 0;
- if (m_Etape == etapeRien)
- {
- return (int)dist;
- }
- for (int i = 0; i < m_nPtLongeantPlaque-1; i++)
- {
- dist += CVector (m_tPtLongeantPlaque[i].x, m_tPtLongeantPlaque[i].y, m_tPtLongeantPlaque[i+1].x, m_tPtLongeantPlaque[i+1].y).Norm (g_pCurrentScale);
- }
- return (int) dist;
- }
- // Algorithme de coloriage de blobs sur l'image d'entrée
- // Objectif : enlever les petites régions dans l'image seuillée
- bool CPlaqueBase::DoBlobColoring()
- {
- int x, y, i, indblob, nblob, realblob, ng;
- long taille;
- img lwimg, lwimg1;
- int wdimh, wdimv;
- blob m_tblob[MAXBLOB];
- Rect rectEnglobant;
- rectEnglobant = m_rgnATraiter.GetRgnBox();
- wdimh = GetWidth();
- wdimv = GetHeight();
- lwimg.Create(TYPE_UCHAR, wdimh, wdimv);
- lwimg1.Create(TYPE_INT, wdimh, wdimv); // On prend des ints
- lwimg.Fill(0);
- indblob = 0;
- nblob = 0;
- // Générer l'image binaire qui va aller à l'algo. du blob coloring
- // lwimg
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- bool fGreen;
- fGreen = (GetPixelResult(x, y) == m_clrVert);
- if (!fGreen)
- {
- lwimg.SetValue(x, y, 1);
- }
- }
- }
- // Résultat : les blobs sont dans wimg1
- nblob = lwimg.BlobColoring(m_tblob, &lwimg1);
- // Elimination des petits blobs.
- realblob = nblob;
- for (i = 1; i <= nblob; i++)
- {
- taille = lwimg1.GetBlobSize(i);
- if ((taille < (wdimh * wdimv) - 1) && (taille <= 50))
- {
- lwimg1.RemplaceCouleur(i, MAXBLOB+1); // Sur int
- }
- }
- // Dans lwimg1, les pixels à la valeur MAXBLOB+1, sont ceux des régions à supprimer
- // Mise à jour de lwimg, puis transfert dans l'image d'origine
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- ng = lwimg1.GetValue(x, y);
- if (ng == (MAXBLOB + 1))
- {
- SetPixelResult(x, y);
- }
- }
- }
- if (lwimg.init == 1) lwimg.Del();
- if (lwimg1.init == 1) lwimg1.Del();
- return true;
- }
- // Algorithme de fermeture
- bool CPlaqueBase::DoClosing()
- {
- int x, y, ng;
- img lwimg, lwimg1;
- int wdimh, wdimv;
- Rect rectEnglobant;
- rectEnglobant = m_rgnATraiter.GetRgnBox();
- wdimh = GetWidth();
- wdimv = GetHeight();
- lwimg.Create(TYPE_USHORT, wdimh, wdimv);
- lwimg1.Create(TYPE_USHORT, wdimh, wdimv); // On prend des ints
- lwimg.Fill(0);
- // Générer l'image binaire qui va aller à l'algo. du blob coloring
- // lwimg
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- if (GetPixelResult(x, y) == m_clrVert)
- {
- lwimg.SetValue(x, y, 1);
- }
- }
- }
- lwimg.BinaryClosing(&lwimg1);
- // Dans lwimg1, les pixels à la valeur MAXBLOB+1, sont ceux des régions à supprimer
- // Mise à jour de lwimg, puis transfert dans l'image d'origine
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- ng = lwimg1.GetValue(x, y);
- if (ng == 1)
- {
- SetPixelResult(x, y);
- }
- }
- }
- if (lwimg.init == 1) lwimg.Del();
- if (lwimg1.init == 1) lwimg1.Del();
-
- return true;
- }
- bool CPlaqueBase::PointInBufferResult(const int& x, const int& y)
- {
- Point pt(x, y);
- // pt.x = x;
- // pt.y = y;
- return PointInBufferResult(pt);
- }
- bool CPlaqueBase::PointInBufferResult(const Point& pt)
- {
- assert( m_result );
- int dx = GetWidth();
- int dy = GetHeight();
- return ( (pt.x >= 0) && (pt.y >= 0) && (pt.x < dx) && (pt.y < dy) );
- }
-
- bool CPlaqueBase::IsColor(int x, int y)
- {
- unsigned char bRed;
- unsigned char bGreen;
- unsigned char bBlue;
- int iRed;
- int iGreen;
- int iBlue;
- // AffectLeadResult();
- QRgb rgb = m_result->pixel( x, y );
- bRed = qRed(rgb);
- bGreen = qGreen(rgb);
- bBlue = qBlue(rgb);
- iRed = (int) bRed;
- iGreen = (int) bGreen;
- iBlue = (int) bBlue;
- // un niveau de gris implique bRed = bGreen = bBlue
- // étant donné que l'image a été numérisé on autorise un delta de 10 entre chaque couleur
- // ex : 190 197 185 est gris, 190 201 190 est en couleur
- return ( (abs (iRed - iGreen) > 30)
- || (abs (iRed - iBlue ) > 30)
- || (abs (iGreen - iBlue ) > 30)
- );
- }
- int CPlaqueBase::GetIntensityResult(const int& x, const int& y)
- {
- Point pt;
- pt.x = x;
- pt.y = y;
- return GetIntensityResult(pt);
- }
- int CPlaqueBase::GetIntensityResult(const Point& pt)
- {
- assert( m_result );
- return qGray(m_result->pixel( pt.x, pt.y ));
- /*
- value = (char) m_result->GetPixel( pt.x, pt.y );
-
- col = (unsigned char)(value & 0xff);
-
- return col;
- */
- /*
- #if defined( WIN32 ) && !defined( IMT_DLL ) && !defined( PLAQUE_DLL )
- return GetRValue( m_result->GetPixel( pt.x, pt.y ) );
- #else
- return *m_result->GetPixel( pt.x, pt.y );
- #endif
- */
- }
- unsigned int CPlaqueBase::GetErrorID(void)
- {
- return m_uErrorID;
- }
- /*int CPlaqueBase::TestFantome(QImage *h_image, CPlaqueResult *)
- {
- int i, x, y, nbPts;
- unsigned char *points, *dadd;
- int *input;
- Point pts[12];
- int retour;
- m_result = h_image;
- // m_result.Create(768, 576, 24);
- // m_result.CopyFrom2(h_image);
- //CopieResultSvg();
- nbPts = 6;
- retour = 0;
- points = (unsigned char *) malloc( nbPts * sizeof(unsigned char *) );
- input = (int *) malloc( 4 * sizeof(int) );
-
- x = 372;
- y = 177;
- pts[0].x = 267;
- pts[0].y = 218;
- pts[1].x = 300;
- pts[1].y = 227;
- pts[2].x = 364;
- pts[2].y = 232;
- pts[3].x = 446;
- pts[3].y = 238;
- pts[4].x = 509;
- pts[4].y = 238;
- pts[5].x = 561;
- pts[5].y = 234;
- dadd = points;
- for (i = 0; i < nbPts; i++)
- {
- input[0] = ((pts[i].x & 0xFF000000) >> 24);
- input[1] = ((pts[i].x & 0x00FF0000) >> 16);
- input[2] = ((pts[i].x & 0x0000FF00) >> 8);
- input[3] = ((pts[i].x & 0x000000FF));
- *dadd = input[0];
- dadd++;
- *dadd = input[1];
- dadd++;
- *dadd = input[2];
- dadd++;
- *dadd = input[3];
- dadd++;
- input[0] = ((pts[i].y & 0xFF000000) >> 24);
- input[1] = ((pts[i].y & 0x00FF0000) >> 16);
- input[2] = ((pts[i].y & 0x0000FF00) >> 8);
- input[3] = ((pts[i].y & 0x000000FF));
- *dadd = input[0];
- dadd++;
- *dadd = input[1];
- dadd++;
- *dadd = input[2];
- dadd++;
- *dadd = input[3];
- dadd++;
- }
-
- retour = calculPlaque(h_image, x, y, nbPts, points); //, 60, 120
- // m_res->allocate_vectors(m_nPtLongeantPlaque);
- return retour;
- }*/
- int CPlaqueBase::calculPlaque(QImage *h_image, int x, int y, int nbPts, const QList<Point>& pts/*, int seuil1, int seuil2*/)
- {
- Point point;
- int npt;
- int retour;
- //unsigned char *dadd;
- retour = 0;
- unsigned char a, b, c, d;
-
- m_result = h_image;
- // m_result.Create(768, 576, 24 );
- // m_result.CopyFrom2(h_image);
- m_Etape = etapeRien;
-
- // C'est le premier octet qui est pris : le rouge.
- m_debug1 = (int) GetIntensityResult(100, 125);
- m_debug2 = (int) GetIntensityResult(200, 170);
- m_debug3 = (int) GetIntensityResult(300, 460);
- m_debug4 = (int) m_result->width();
- m_debug5 = (int) 1;
-
- //retour = 1999;
- // return retour;
-
- // Création de m_etudie
- if ( m_Etape == etapeRien )
- {
- if ( !m_etudie )
- {
- m_etudie = new unsigned long[ GetWidth() * GetHeight() ];
-
- }
- /* if ( m_etudie )
- {
- m_etudie->Create( GetWidth(), GetHeight(), 24 );
- }
- */
- // 1er Point
- m_Etape = etapeSegments;
- m_wimg.Del();
- m_wimg.Create(TYPE_UCHAR, GetWidth(), GetHeight());
- m_wimg.Fill(0);
- }
-
- retour = 0;
- //dadd = points;
-
- if (m_Etape == etapeSegments)
- {
- npt = 0;
- do
- {
-
- /*a = *dadd;
- dadd++;
- b = *dadd;
- dadd++;
- c = *dadd;
- dadd++;
- d = *dadd;
- dadd++;
-
- point.x = d;
- point.x = point.x | (c << 8);
- point.x = point.x | (b << 16);
- point.x = point.x | (a << 24);
- a = *dadd;
- dadd++;
- b = *dadd;
- dadd++;
- c = *dadd;
- dadd++;
- d = *dadd;
- dadd++;
-
- point.y = d;
- point.y = point.y | (c << 8);
- point.y = point.y | (b << 16);
- point.y = point.y | (a << 24);*/
- point = pts[npt];
-
- if (m_nPtLongeantPlaque < NBPTSLONGEANTMAX)
- {
- if ( m_nPtLongeantPlaque
- && ( (CVector (point.x, point.y, m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].x,m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].y).Norm () <= 5)
- || ((m_type == typeManual) && (CVector (point.x, point.y, m_tPtLongeantPlaque [0].x, m_tPtLongeantPlaque [0].y).Norm () <= 5))
- )
- )
- {
- // si la distance entre deux points est inférieure à 5 pixels, on considère que
- // c'est la fin de la paroi
- if (m_type == typeManual)
- {
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = m_tPtLongeantPlaque [0];
- m_nPtLongeantPlaque++;
- retour = CalculerPlaqueManuelle();
- break;
- }
- m_Etape = etapeTacheSeuil;
- }
- else
- {
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = point;
- m_nPtLongeantPlaque++;
- }
- }
- npt++;
-
- } while (npt < nbPts);
- m_Etape = etapeTacheSeuil; // Ajouter voir interface
- }
-
- if (m_Etape == etapeTacheSeuil)
- {
- // Pt indiquant la limite inférieure
- m_ptInferieur.x = x;
- m_ptInferieur.y = y;
- // Calculer la région dans laquelle on coloriera
- retour = ParametrerRegionATraiter ();
-
- if (retour == 40)
- {
- retour = 20;
- if ( TestCouleur() )
- {
- m_type = typeRGB;
- }
- else
- {
- m_type = typeBW;
- retour = 23;
- }
- // Afficher le bitmap LeadResult seulement si la région est OK
- // est PAS en Release, afin de dissimuler, un peu, la méthode de détection
- m_Etape = etapeReglage;
- // s'il y a une phase de réglage (il n'y en a pas pour la plaque couleur)
- if (m_type == typeRGB)
- {
- m_debug1 = 100;
- retour = Mesurer_3(0); // mesure immédiate
- // retour = m_nVecteursTrouves;
- }
- else
- {
- m_debug1 = 200;
- m_iTache = GetIntensityTache (m_ptInferieur, 7);
- // Calculer le seuil inferieur
- Mesurer_3(m_iTache + 10);
- }
- // AnalysePlaque(seuil1, seuil2);
- }
- }
-
- return retour;
- }
- int CPlaqueBase::OnLButtonUp(QImage *h_image, int x, int y)
- {
- m_result = h_image;
- // m_result.Create(768, 576, 24 );
- // m_result.CopyFrom2(h_image);
- // Création de m_etudie
- if (m_Etape == etapeRien)
- {
- if ( !m_etudie )
- {
- m_etudie = new unsigned long[ GetWidth() * GetHeight() ];
- }
- /* m_etudie = new ExtendedImage;
- if ( m_etudie )
- {
- m_etudie->Create( GetWidth(), GetHeight(), 24 );
- }
- */
- }
-
- return OnLButtonUp(x, y);
- }
-
- int CPlaqueBase::OnLButtonUp(int x, int y)
- {
- Point point;
- point.x = x;
- point.y = y;
- return OnLButtonUp(point);
- }
- int CPlaqueBase::OnLButtonUp(Point& point)
- {
- int retour;
- int x, y;
- x = point.x;
- y = point.y;
- retour = 0;
- if (m_Etape == etapeRien)
- {
- // 1er Point
- m_Etape = etapeSegments;
- m_wimg.Del();
- m_wimg.Create(TYPE_UCHAR, GetWidth(), GetHeight());
- m_wimg.Fill(0);
- }
-
- if (m_Etape == etapeSegments)
- {
- retour = 9;
- if (m_nPtLongeantPlaque < NBPTSLONGEANTMAX)
- {
- if ( m_nPtLongeantPlaque
- && ( (CVector (point.x, point.y, m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].x,m_tPtLongeantPlaque [m_nPtLongeantPlaque-1].y).Norm () <= 5)
- || ((m_type == typeManual) && (CVector (point.x, point.y, m_tPtLongeantPlaque [0].x, m_tPtLongeantPlaque [0].y).Norm () <= 5))
- )
- )
- {
- // si la distance entre deux points est inférieure à 5 pixels, on considère que
- // c'est la fin de la paroi
- if (m_type == typeManual)
- {
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = m_tPtLongeantPlaque [0];
- m_nPtLongeantPlaque++;
- retour = CalculerPlaqueManuelle();
- // return (retour);
- }
- m_Etape = etapeTacheSeuil;
- // retour = 10;
- // return (retour);
- }
- retour = 11;
- m_tPtLongeantPlaque [m_nPtLongeantPlaque] = point;
- m_nPtLongeantPlaque++;
- }
- }
- else if (m_Etape == etapeTacheSeuil)
- {
- // Pt indiquant la limite inférieure
- m_ptInferieur = point;
- // Calculer la région dans laquelle on coloriera
- retour = ParametrerRegionATraiter ();
- if (retour == 40)
- {
- retour = 20;
- if ( TestCouleur() )
- {
- m_type = typeRGB;
- }
- else
- {
- m_type = typeBW;
- retour = 23;
- }
- //? cursor.Clip (m_pView, NULL); // Cesser le clipping
- // Afficher le bitmap LeadResult seulement si la région est OK
- // est PAS en Release, afin de dissimuler, un peu, la méthode de détection
- m_Etape = etapeReglage;
- // s'il y a une phase de réglage (il n'y en a pas pour la plaque couleur)
- if (m_type == typeRGB)
- {
- Mesurer_3(0); // mesure immédiate
- retour = 22;
- }
- else
- {
- m_iTache = GetIntensityTache (m_ptInferieur, 7);
- // Calculer le seuil inferieur
- Mesurer_3(m_iTache + 10);
- retour = 21;
- }
- }
- }
- else if (m_Etape == etapeReglage)
- {
- retour = 30;
- }
-
- return retour; // Tous les clics ne sont pas faits
- }
- unsigned char CPlaqueBase::GetIntensityTache(Point& ptCentre, int nRayonTache)
- {
- int nIntensiteTache = 0;
- // Quelle est l'intensité monochrome de la tache autour de ce pt ?
- for (int iX = min (GetWidth()-1, max (0, ptCentre.x - nRayonTache));
- iX <= min (GetWidth()-1, ptCentre.x + nRayonTache); iX++)
- {
- for (int iY = min (GetHeight()-1, max (0, ptCentre.y - nRayonTache));
- iY <= min (GetHeight()-1, ptCentre.y + nRayonTache); iY++)
- {
- nIntensiteTache += GetIntensityResult(iX, iY);
- }
- }
- return (nIntensiteTache / ((nRayonTache * 2 + 1) * (nRayonTache * 2 + 1)));
- }
- double CPlaqueBase::Mean()
- {
- return (m_nMesures ? g_pCurrentScale->DistanceX (double (m_nSommeLongueurs) / m_nMesures) : 0.);
- }
- double CPlaqueBase::Max()
- {
- return (g_pCurrentScale->DistanceX ((long)m_nLongueurMax));
- }
- unsigned char CPlaqueBase::Density()
- {
- int res;
- if (m_nPointsDansPlaque != 0)
- {
- res = max(m_iSommeIntensitesPlaque, 0) / m_nPointsDansPlaque;
- }
- else
- {
- res = 0;
- }
- return ((unsigned char) res);
- }
- // Surface != DistanceX (m_nPointsDansPlaque) !!
- double CPlaqueBase::Surface()
- {
- double dblSide = sqrt ((double) m_nPointsDansPlaque);
- return (g_pCurrentScale->Surface (dblSide, dblSide));
- }
- bool CPlaqueBase::TestCouleur()
- {
- bool isCouleur = false;
- Rect rc;
- int x, y;
- rc = m_rgnATraiter.GetRgnBox();
- m_debug2 = rc.left;
- m_debug3 = rc.left;
- m_debug4 = rc.top;
- m_debug5 = rc.bottom;
- for (x = rc.left; ((x < rc.right) && (isCouleur == false)); x++)
- {
- for (y = rc.top; ((y < rc.bottom) && (isCouleur == false)); y++)
- {
- if ( m_rgnATraiter.PtInRegion0( x, y ) )
- {
- isCouleur = IsColor(x, y);
- if (isCouleur == true)
- {
- x = x;
- y = y;
- isCouleur = IsColor(x, y);
- }
- }
- }
- }
- return isCouleur;
- }
- unsigned long CPlaqueBase::GetPixelResult(const int& x, const int& y)
- {
- Point pt;
- pt.x = x;
- pt.y = y;
- return GetPixelResult(pt);
- }
- unsigned long CPlaqueBase::GetPixelResult(const Point& pt)
- {
- unsigned long color;
- color = 0;
- if (m_wimg.GetValue(pt.x, pt.y) == 1)
- {
- color = m_clrVert;
- }
-
- // m_wimg.SaveImgAsRaw();
- return color;
- /*
- assert( m_result );
- #if defined( WIN32 ) && !defined( PLAQUE_DLL )
- return m_result->GetPixel( pt.x, pt.y );
- #else
- return *m_result->GetPixel( pt.x, pt.y );
- #endif
- */
- }
- unsigned long CPlaqueBase::GetPixelEtudie(const int& x, const int& y)
- {
- Point pt;
- pt.x = x;
- pt.y = y;
- return GetPixelEtudie(pt);
- }
- unsigned long CPlaqueBase::GetPixelEtudie(const Point& pt)
- {
- assert( m_etudie );
- //#if defined( WIN32 ) && !defined( IMT_DLL ) && !defined( PLAQUE_DLL )
- // return m_etudie->GetPixel( pt.x, pt.y );
- //#else
- //return *m_etudie->GetPixel( pt.x, pt.y );
- return m_etudie[ pt.x + GetWidth() * pt.y ];
- //#endif
- }
-
- void CPlaqueBase::SetPixelResult(int x, int y)
- {
- m_wimg.SetValue(x, y, 1);
- // m_wimg.SaveImgAsRaw();
- }
- void CPlaqueBase::SetPixelEtudie(Point& pt, unsigned long vColor)
- {
- int x, y;
- x = pt.x;
- y = pt.y;
-
- // m_etudie->SetPixel(vColor, x, y);
- m_etudie[ x + GetWidth() * y ] = vColor;
- }
- void CPlaqueBase::SetPixelEtudie(int x, int y, unsigned long vColor)
- {
- // m_etudie->SetPixel(vColor, x, y);
- m_etudie[ x + GetWidth() * y ] = vColor;
- }
- int CPlaqueBase::GetWidth()
- {
- return m_result->width();
- }
- int CPlaqueBase::GetHeight()
- {
- return m_result->height();
- }
- // Copie de m_result dans m_etudie
- void CPlaqueBase::CopyResultDansEtudie()
- {
- // m_etudie->Copy2(GetWidth(), GetHeight(), m_result);
- if ( !m_etudie )
- {
- m_etudie = new unsigned long[ GetWidth() * GetHeight() ];
- }
- int w, h;
- int width = GetWidth();
- int height = GetHeight();
- unsigned long* ptr = m_etudie;
- for ( h = 0; h < height; h++ )
- {
- for ( w = 0; w < width; w++ )
- {
- *ptr++ = GetPixelResult( w, h );
- }
- }
- }
- /*void CPlaqueBase::CopieResultSvg()
- {
- int width = m_result->GetWidth();
- int height = m_result->GetHeight();
- m_result2.Create(width, height, 24 );
- m_result2.CopyFrom2(m_result);
- // m_result.SaveImgAsRaw();
- }*/
- /*void CPlaqueBase::AffectLeadResult()
- {
- m_result->CopyFrom2(&m_result2);
- }*/
- void CPlaqueBase::AnalysePlaque(int seuil1, int seuil2)
- {
- int i, x, y;
- // double dng;
- // int gray;
- int ngLumiere, ngAdventitia;
- // Si la lumière est en Doppler couleur
- if (IsColor(m_ptInferieur.x, m_ptInferieur.y))
- {
- ngLumiere = 0;
- }
- else
- {
- ngLumiere = GetIntensityResult(m_ptInferieur.x, m_ptInferieur.y);
- }
- ngAdventitia = 0;
- for (i = 0; i < m_nPtLongeantPlaque; i++)
- {
- ngAdventitia += GetIntensityResult(m_tPtLongeantPlaque[i].x, m_tPtLongeantPlaque[i].y);
- }
- ngAdventitia = 255;
- Rect rectEnglobant;
- rectEnglobant = m_rgnATraiter.GetRgnBox();
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- bool fGreen;
-
- fGreen = (GetPixelResult(x, y) == m_clrVert);
-
- if ( m_rgnATraiter.PtInRegion0( x, y ) && (!fGreen))
- {
- m_wimg.SetValue(x, y, 2);
-
- // On récupére le niveau de gris de l'image originale
- /* gray = GetIntensityResult(x, y);
- dng = ((double) (gray - ngLumiere) * 195.0 ) / (double) ngAdventitia;
- if (dng < 0) dng = 0;
- if (dng > 195.0) dng = 195.0;
-
- if (dng <= seuil1)
- {
- m_wimg.SetValue(x, y, 2);
- }
- else if ((dng > seuil1) && (dng <= seuil2))
- {
- m_wimg.SetValue(x, y, 3);
- m_nbPixelsB++;
- }
- else if (dng > seuil2)
- {
- m_wimg.SetValue(x, y, 4);
- m_nbPixelsV++;
- }
- */ }
- }
- }
- // CalculScoreRepartition();
- }
- /*
- void CPlaqueBase::CalculScoreRepartition()
- {
- int nbConnexesR, nbConnexesB, nbConnexesV;
- int nbConnections, x, y, i, offset[8];
- // Tableau des Offsets
- // 4 0 5
- // 3 1
- // 7 2 6
- offset[0] = - m_imgPlaque.dimh;
- offset[1] = 1;
- offset[2] = m_imgPlaque.dimh;
- offset[3] = - 1;
- offset[4] = - 1 - m_imgPlaque.dimh;
- offset[5] = 1 - m_imgPlaque.dimh;
- offset[6] = 1 + m_imgPlaque.dimh;
- offset[7] = - 1 + m_imgPlaque.dimh;
- m_scoreRepartitionR = 0;
- m_scoreRepartitionB = 0;
- m_scoreRepartitionV = 0;
- m_scoreRepartition = 0;
- // Scrutation du rectangle englobant de la plaque
- nbConnexesR = 0;
- nbConnexesB = 0;
- nbConnexesV = 0;
- nbConnections = 0;
- for (x = rectEnglobant.left; x < rectEnglobant.right; x++)
- {
- for (y = rectEnglobant.top; y < rectEnglobant.bottom; y++)
- {
- bool fGreen;
-
- fGreen = (GetPixelResult(x, y) == m_clrVert);
-
- if ( m_rgnATraiter.PtInRegion0( x, y ) && (!fGreen))
- {
- for (i = 0; i < m_connexite; i++)
- {
- dadd3 = dadd1 + offset[i];
- if (*dadd3 == 1) // L'autre pixel appartient également à la plaque
- {
- dadd4 = dadd2 + offset[i];
-
- nbConnections++;
- // Si les 2 couleurs des pixels sont dans la même zone
- if ((*dadd2 <= m_SeuilCouleur1) && (*dadd4 <= m_SeuilCouleur1))
- {
- // Les 2 sont dans le seuil du bas
- nbConnexesR++;
- }
- else if ((*dadd2 > m_SeuilCouleur1) && (*dadd4 > m_SeuilCouleur1) && (*dadd2 <= m_SeuilCouleur2) && (*dadd4 <= m_SeuilCouleur2))
- {
- // Les 2 sont dans le seuil du milieu
- nbConnexesB++;
- }
- else if ((*dadd2 > m_SeuilCouleur2) && (*dadd4 > m_SeuilCouleur2))
- {
- // Les 2 sont dans le seuil du haut
- nbConnexesV++;
- }
- }
- }
- }
- }
- }
- // Score = 0 : tous les pixels sont de la même couleur
- // Score = 100% : Aucun pixel connexe
- if (nbConnections != 0)
- {
- m_scoreRepartitionR = 100.0 - (((double) nbConnexesR / (double) nbConnections) * 100.0);
- m_scoreRepartitionB = 100.0 - (((double) nbConnexesB / (double) nbConnections) * 100.0);
- m_scoreRepartitionV = 100.0 - (((double) nbConnexesV / (double) nbConnections) * 100.0);
- }
- // Score répartition globale
- m_scoreRepartition = ((m_scoreRepartitionR + m_scoreRepartitionB + m_scoreRepartitionV) / 3.0);
- }
- */
-
|