Prgram TiepTri: Faire triangulation, correlation par mesh. Fichier XML input: class cXml_TriAngulationImMaster class cXml_Triangle3DForTieP Structure XML input: Chaque Img Master => 1 fichier XML Dans fichier XML: Name Img Master Name Img 2nd (plusieur) Point 3D sommet 1 du Tri Point 3D sommet 2 du Tri Point 3D sommet 3 du Tri Index du img 2nd pour correlation (index correspondant avec list Creer cAppliTieTri: Creer img Master: cImMasterTieTri Parcourir list img 2nd Creer img 2nd: cImSecTieTri Creer list voisin extrema mVoisExtr (TT_DIST_EXTREMA = 3pxl, pour decider si 1 point est 1 extrema local) Creer list voisin homologue mVoisHom (TT_DIST_RECH_HOM = 12pxl, rayon de chercher point homologue dans img 2nd) Creer interpolation pour corellation dense mInterpol (pour l'instant, Sinus) Appel method DoAllTri de cAppliTieTri: Parcourir tout les triangle, dans chaque triangle: Appel method DoOneTri: Load triangle region in im master: Detect pts d'interet Parcourir list img 2nd Load triangle region in im 2nd. Parcourir list point d'interet dans img master Parcourir list img 2nd: Correlation par RechHomPtsInteretBilin Filtrage spatial result de correlation tout les pt d'interet Recherche homologue dense avec RechHomPtsDense ======================================================================= RechHomPtsInteretBilin: Recuperer list de voisinage de recherche homologue Parcourir la list de voisinage homologue Pour chaque point, correlation par TT_RechMaxCorrelLocale (szW=3, step=2, szMax=6) If result correl > TT_SEUIL_CORREL_1PIXSUR2 && pt correl nam trong masque img 2nd Raffiner correlation par TT_RechMaxCorrelLocale (szW=6, step=1, szMax=6) ======================================================================== Ajout 13/12/2016: Les critere supplementaire pour choisir point d'interet robust sont heberger dans cPtOfCorrel. (->) Il sagit critère de contrast et critère auto-corrélation +++++====+++++ Analyse fonction cImTieTri::MakeInterestPoint +++++====+++++ (1) Critere extrema (*) Fonction cImTieTri::IsExtrema (*) Examiner un point donné avec des voisin autour si 'est un point extrema (max/min) local (*) Les list de voisins autour sont creer au moment de creer cAppliTieTri, avec rayon = TT_DIST_EXTREMA = 3 pxl (*) Voir si valeur de tout les pts autour sont < ou > valeur de pt central (*) Fonction CmpValAndDec pour comparer val de 2 point (-) Entrer value de PtCentral & PtVoisin => -1 si PtCentral < PtVoisin, 1 si l'inverse -1 si (?????) À examiner en plus - pas encore comprendre programme (2) Critere FAST Implementation: class cFastCriterCompute && fonction FastQuality (dans cPtOfCorrel.h) Critere basé sur fast detecteur : examiner les point autour pour choisir les pts plus contrasté. TT_DIST_FAST = 4 : constant de former un cercle de voisinage pour critere FAST. Radius de cette cerle = 4 pixels 2 critère à valider: (a) TT_PropFastStd = 0.75 => examiner si 75% de points voisins ont valeurs inférieur/superieur de point candidat un écart de TT_SeuilFastStd=5 (*) Se faire par method KthValProp dans FastQuality : (.) aVVals -> Les valeurs des points voisin (.) aV0 -> valeur de point candidat (.) aVPerc = TT_SeuilFastStd = 5 -> seuil de différent d'intensité entre pt candidat et pt autour (.) double aVPerc = KthValProp(aVVals,aPropStd); -> tri valeur dans aVVals, puis prendre élement à position aPropStd (75%) (.) double aResStd = (aV0 -aVPerc) ; -> si val(pt candidat) > val(aVPerc) -> val(pt_candidat) > 75% valeurs des points autours (b) TT_PropFastConsec = 0.6 => examiner si 60% de points voisins consecutives ont valeurs inférieur/superieur de point candidat un écart de TT_SeuilFastCons=3 (*) cFastReduceAssoc : une method numerique pour vite examiner un certain nombre de point consecutive autour image ==> Pas encore comprendre (3) Critere auto-corell (a) Implementation: class cCutAutoCorrelDir && cAutoCorrelDir && fonction AutoCorrel (dans cPtOfCorrel.h) (b) Examiner les imagette autour de l'imagette de pts d'interet. (c) cAutoCorrelDir est class parent de cCutAutoCorrelDir. Il est creer quand cCutAutoCorrelDir est creer (dans le constructor) (d) Pour chaque cImTieTri, on creer un cCutAutoCorrelDir avec: Image => donne le Type Point noyeau (0,0) => avec Rho pour creer list voisin à examiner Rho = TT_SZ_AUTO_COR/2 => taille radius pour examiner autour SzW = TT_SZ_AUTO_COR => taille fenetre corellation (=3) (e) Pour 1 point d'interet à examiner : Il y a 3 seuile : aRejetInt = TT_SEUIL_CutAutoCorrel_INT (0.65 - seuille acceptation rapide par correlation entier pxl) aRejetReel = TT_SEUIL_CutAutoCorrel_REEL (0.75 - seuille acceptation rapide par correlation reel pxl) aSeuilAccept = TT_SEUIL_AutoCorrel ( 0.85 - Seuil d'elimination par auto-correlation) Executer ICorrelOneOffset avec tout les imagette voisin pour chercher la maximal de correlation aCorrMax ICorrelOneOffset est la fonction calcul valeur correlation entre 2 imagette (noyeau && voisin) Si aCorrMax > aSeuilAccept => valid Si aCorrMax < aRejetInt => in-valid Si aCorrMax se situe entre les 2 seuile => examiner la direction avec DoItOneStep en 2 étape. La direction est l'angle theta de la voisin maximal DoItOneStep est la fonction pour chercher max corellation en fonction d'angle (theta +- offset). (Etape 1) : DoItOneStep avec offsset = 0.5/Rho, chercher la maximal de correl aRes1 Si aRes1 > aSeuilAccept => valid Si aRes1 < aRejetReel => in-valid Si aRes1 se situe entre les 2 seuile => (Etape 2) (Etape 2) : DoItOneStep avec offsset = 0.2/Rho, chercher la maximal de correl aRes2 Si aRes2 > aCorrMax => valid Si aRes2 < aCorrMax => in-valid (4) Filtrage spatial Implementation: 1 morceaux de code à la fin de cImTieTri::MakeInterestPoint Les point d'interet apres choisi par les 3 critere avant sont stocker dans list * aListPI Chaque pts d'interet est sauvgarde sous avec : Pt2di mPt => coordoneé eTypeTieTri mType => eTTTNoLabel = 0, eTTTMax = 1, eTTTMin = 2 (type pt d'interet, decider par IsExtrema) double mFastQual => aFastQual.x + 2 * aFastQual.y (poids sur FAST consecutive (2)(b) plus que FAST Std (2)(a)) bool mSelected => si le pts est selecte ou rejet (decider apres Filtrage spatial) => convertir ce std::list à std::vector aVI avant de filtrage (parce que vecteur peut facile trier,...), et puis reconvertir en list Ce filtrage n'est appliqué que sur Image Master Le rayon pour eliminer les pts autour 1 pts : aSeuilD2 = (TT_DefSeuilDensiteResul/TT_RatioFastFiltrSpatial).^2 TT_DefSeuilDensiteResul = 50 pxl TT_RatioFastFiltrSpatial = 4 +++++====+++++ Analyse partie correlation dans TiepTri +++++====+++++ Dans 1 Triangle: (DoOneTri) (**--**) =========== Pour chaque point d'interet dans img triangle d'image master ============== (**--**) : (*) Tout d'abord, recherche tout les point d'interet dans img2nd qui se situe dans un rayon de mAppli.DistRechHom() = TT_DIST_RECH_HOM = 12pxl (.) Ca fait par le check de point aP0+aVH[aKH] avec ( aVH=mAppli.VoisHom() -> Tout les homologues dans un rayon donné TT_DIST_RECH_HOM), aP0 est le point d'interet d'image master (1) mImSecLoaded[aKIm]->RechHomPtsInteretBilin(*itI,mNivInterac); (.) *itI : point intéret selection dans image master (.) Prendre les point de même label (minimal-maximal) sur 1 rayon de () pxl dans img 2nd (2) Correlation local (pour chaque couple de point) master - secondaire cResulRechCorrel aCRCLoc = TT_RechMaxCorrelLocale ( mMaster->mTImInit, aP0, => pt d'interet img Master mTImReech, aPV, => pt d'interet img 2nd TT_DemiFenetreCorrel/2, 2, aSzRech ); (.) aSzW = TT_DemiFenetreCorrel/2 = 3 (.) aStep = 2 (.) aSzRech = TT_DemiFenetreCorrel = 6 (a) Correlation 1PIX/2 (.) Appel dedans: cTT_MaxLocCorrelBasique anOpt( eTMCInt, aIm1,Pt2dr(aP1),aIm2,Pt2dr(aP2), aSzW, => 3 aStep, => 2 0.9); => aStepRechCorrel anOpt.optim_step_fixed(Pt2dr(0,0),aSzRechMax); (->) Je fait correlation en 2 pixel sur 1 pour former imagette 7x7, avec l'avancement de 0.9 pxl par chaque fois de correlation, avec taille region de recherche = 13x13 (->) Result correlation :aCRCLoc.mCorrel (b) Correlation 1PIX/1 (entière) Executer si Correlation 1PIX/2 valid : (.) aCRCLoc.mCorrel > TT_SEUIL_CORREL_1PIXSUR2 = 0.7 (.) distance entre pt trouve par correl 1PIX/2 et pt init aPV < 1.5 aCRCLoc = TT_RechMaxCorrelLocale( mMaster->mTImInit, aP0, mTImReech, aCRCLoc.mPt, TT_DemiFenetreCorrel, =6 = aSzW 1, = aStep aSzRech =6 ); (.) Appel dedans : cTT_MaxLocCorrelBasique anOpt( eTMCInt, aIm1,Pt2dr(aP1),aIm2,Pt2dr(aP2), aSzW, = 6 aStep, = 1 0.9 = aStepRechCorrel ); anOpt.optim_step_fixed(Pt2dr(0,0),aSzRechMax); (->) Je fait correlation en 1 pixel (aStep) sur 1 pour former imagette 13x13 (aSzW), avec l'avancement de 0.9 pxl par chaque fois de correlation, avec taille region de recherche = 13x13 (->) Result correlation :aCRCLoc.mCorrel (->) Mis a jour result aCRCMax.Merge si distance entre pt trouve par correl aCRCLoc.mPt et pt init aPV < 1.5 (c) Apres tout les couple (pt master)-(les points 2nd de meme label sur un rayon) sont examiner Fait Correlation sub-pixel, interpol bilin basique (.) Si il n'y a pas de point qui pass Correlation 1PIX/2 => point d'interet dans master non valid (.) Si il a trouver le point plus grand par Correlation 1PIX/1 cResulRechCorrel aRes =TT_RechMaxCorrelMultiScaleBilin ( mMaster->mTImInit, Pt2dr(aP0), => pt d'interet img Master mTImReech, Pt2dr(aCRCMax.mPt),=> result correl entier aSzWE = 6 (SzW end , param entree du commande) ); (.) Appel dedans : cTT_MaxLocCorrelBasique anOpt( eTMCBilinStep1, => mode update optim réel aIm1,aP1,aIm2,aP2, aSzW, => aSzWE = 6 1, => aStep (prendre 1 pixel par chaque) 0.01 => aStepRechCorrel ); anOpt.optim(); (.) Appel dedans : m2Sol.Update(TT_CorrelBilin(mIm1,Pt2di(mP1),mIm2,mP2+Pt2dr(aDx,aDy),mSzW)); (->) Coeur du method est une optimisation void Optim2DParam::optim(Pt2dr aPInit) Optim2DParam::Optim2DParam (->) Je fait une correlation par fenetre 13x13, step de prendre pixel 1, step de balayer jusqu'au 0.01 (**--**) ============== Apres on a fait avec tout les pts d'interet dans 1 triangle -> Filtrage spatial dans 1 triangle ================== (**--**) : (*) FiltrageSpatialRMIRC(mDistFiltr); (*) À analyser après (**--**) ============== Recherche point homologue dense ============== (**--**) : cResulRechCorrel cImSecTieTri::RechHomPtsDense( const Pt2di & aP0, => Point Master const cResulRechCorrel & aPIn => Point correl avec Master (Result correl initial) ) (*) Si Interpol (IntDM) for Dense Match = -1 (param entree du command) => Juste rendre coordonne correlation à coordonne de img secondaire par affine : mAffMas2Sec(aPIn.mPt) => Cela est resultat final (*) Si Interpol (IntDM) for Dense Match != -1 && Do refinement on initial images, instead of resampled = 1 (param entree) => Prendre transformation affine Mas2Sec au aAffPred, sinon aAffPred=Affine::Id() => Si Do Refine = 0 => prendre directement image reechantilonnage (calcul dans loadtri, par gerR - interpolation sinC) / =1 => prendre image secondaire original (aImSec) (*) LSQC => variable mNivLSQM. Test LSQ = Least Square Matching => Defini aPrecInit (aStep0 dans cTT_MaxLocCorrelDS1R - method correlation du RechHomPtsDense). => Step initial ? = 1/4 si LSQC>=0 (1=>Affine Geom, Flag 2=>Affin Radiom); =1/8 si LSQC=-1 (None (Def)) => Step final aPrecCible (aStepEnd dans cTT_MaxLocCorrelDS1R); =1/16 si LSQC>=0; =1/128 si LSQC=-1 (None (Def)) (*) Appel programme: cResulRechCorrel aRes2 = TT_MaxLocCorrelDS1R ( mAppli.Interpol(), => type d'interpolation &aAffPred, => transformation affine Mas2Sec ou Id() mMaster->mTImInit, => Img master Pt2dr(aP0), => Point Master aImSec, => img 2nd origin (Do Refine = 1) / image 2nd reechantilonnage dans géo de 1er aAffPred(aPIn.mPt), => Point correl avec point Master aSzWE, // SzW => SzW Final - param entree du commande aNbByPix, => Number of point inside one pixel - param entree command aPrecInit, => aStep0 = 1/4 (avec LSQC) ou 1/8 (correl normal) aPrecCible => aStepEnd = 1/16 (avec LSQC) ou 1/128 (correl normal) ); (.) Utilise class cTT_MaxLocCorrelDS1R => cTT_MaxLocCorrelDS1R anOptim( anInterpol, => cInterpolateurIm2D interpolateur utilisé aMap, => cElMap2D : un map de passer 1 point dans img1->img2 : transformation affine Mas2Sec ou Id() aIm1, => image Master aPC1, => Point Master aIm2, => img 2nd aPC2, => Point correl avec point Master aSzW, => SzW Final - param entree du commande aNbByPix, => Number of point inside one pixel - param entree command aStep0, => aStep0 = 1/4 (avec LSQC) ou 1/8 (correl normal) aStepEnd => aStepEnd = 1/16 (avec LSQC) ou 1/128 (correl normal) ); +++++====+++++ Des class et fonction servir dans correlation dans TiepTri +++++====+++++ (1) Class cTT_MaxLocCorrelDS1R : public Optim2DParam (*) Recherche point homol dense. Ca va "zoomer" imagette (imagette de point aPC1 du aIm1) de taille aSzW à taille aSzW*aNbByPix par une interpolation donné cTT_MaxLocCorrelDS1R anOptim( anInterpol, => cInterpolateurIm2D interpolateur utilisé aMap, => cElMap2D : un map de passer 1 point dans img1->img2 : transformation affine Mas2Sec ou Id() aIm1, => image Master aPC1, => Point Master aIm2, => img 2nd aPC2, => Point correl avec point Master aSzW, => SzW Final - param entree du commande aNbByPix, => Number of point inside one pixel - pour zommer imagette - param entree command aStep0, => aStep0 = 1/4 (avec LSQC) ou 1/8 (correl normal) aStepEnd => aStepEnd = 1/16 (avec LSQC) ou 1/128 (correl normal) ); (*) Method pour calcul correlation: REAL Op2DParam_ComputeScore(REAL aDx,REAL aDy) ; (.) aDx *= mStep0; => mStep0 = aStep0 = 1/8 (correl normal) aDy *= mStep0; (.) Pour chaque valeur d'intensité imagette 1 "zommer" dans mVals1, prendre coordonné correspondance dans [aP2 (vecteur mVois2) + (aDx, aDy)] (.) Ca veut dire faire correlation entre imagette 1 "zommer" et imagette 2 "zommer" décalé un distance (aDx, aDy) (*) OkIm1() - method retourner false si l'interpolateur ne peu pas prendre valeur d'un coordonné dans imagette 1. (*) Creer method optim dans constructor : Optim2DParam ( aStepEnd/aStep0 , DefScoreOpt() ,1e-5, true), => Une optim param2D avec des pas = aStepEnd/aStep0. (*) Une vecteur stocker les valeur d'interpoler de chaque pixel aP1 dans imagette 1 "zoomer" std::vector mVals1; (.) Il y a un boucle dans constructor du cTT_MaxLocCorrelDS1R pour calculer la valeur de chaque pixel dans imagette 1 "zoomer" par une interpolateur donné. (.) Seulement une method sample de parcourir tout les pixel (de pas 1/aNbByPix) Pt2dr aVois(aKx/double(aNbByPix),aKy/double(aNbByPix)); //aKx,aKy sont les compteurs de x,y pour parcourir l'imagette Pt2dr aP1 = aPC1 + aVois; mVals1.push_back(anInterpol->GetVal(aData1,aP1)); // prendre valeur par interpolation, stocker dans vecteur mVals1 (*) Pour chaque aP1 dans imagette 1 calculer (valeur d'intensite d'interpolation), on calcul la coordonne pixel correspondance aP2 aussi, stocker dans vector mVois2 std::vector mVois2; (.) Calcul grace à coordonné aP1 et le fonction aMap (un map passer aP1->aP2) (.) Cette fonction de map peut etre: (->) une affine Mas2Sec si on veut faire un raffinement à partir d'image initial (on recalcul valeur d'intensité pixel à partir d'image 2 original et interpolateur donné) (->) une affine Id() si on veut faire calcul valeur d'intensité pixel à partir d'image 2 réechantilonage (fait par method LoadTri()) mDecInit = aPC2 - (*aMap)(aPC1); //Un decalage initial Pt2dr aP2 = (*aMap)(aP1) + mDecInit; //Coordonne aP2 correspondance avec aP1 mVois2.push_back(aP2); //stocker aP2. mPInf2 = Inf(mPInf2,aP2); //chercher point aP2 minimal (en bas à droit) mPSup2 = Sup(mPSup2,aP2); //chercher point aP2 maximal (en haut à gauche) (2) class cTT_MaxLocCorrelBasique : public Optim2DParam (.) De class Optim2DParam Optim2DParam::Optim2DParam ( REAL step_lim, REAL def_out, REAL epsilon, bool Maxim, REAL lambda, bool optim_p1, bool optim_p2 ) (.) cTT_MaxLocCorrelBasique ( eTypeModeCorrel aMode, => comment update valeur pour prochain etape d'optim (entière/réel) const tTImTiepTri & aIm1, Pt2dr aP1, const tTImTiepTri & aIm2, Pt2dr aP2, const int aSzW, => taille fenetre recherche const int aStep, => step de prendre valeur du pixel pour former imagette de correlation double aStepRechCorrel => step de balayer dans la fenetre recherche ) (.) 2 mode d'optim : (.) eTMCInt => optim en recherche entière (->) Appel TT_CorrelBasique m2Sol.Update(TT_CorrelBasique(mIm1,Pt2di(mP1),mIm2,Pt2di(mP2)+Pt2di(round_ni(aDx),round_ni(aDy)),mSzW,mStep)); return m2Sol.Score4Opt(); (.) eTMCBilinStep1 => optim en recherche (REAL aDx,REAL aDy) (->) Appel TT_CorrelBilins m2Sol.Update(TT_CorrelBilin(mIm1,Pt2di(mP1),mIm2,mP2+Pt2dr(aDx,aDy),mSzW)); return m2Sol.Score4Opt(); (3) class Optim2DParam void Optim2DParam::optim(Pt2dr aPInit) void Optim2DParam::optim_step_fixed(int aNbMaxStep) +++++====+++++ Dans src/geom2d/triangle_comp.cpp +++++====+++++ (1) Raster triangle triangle_comp.cpp Class cSegEntierHor => une segment horizontal class cElTriangleComp Quand creer un triangle, il regard si il est dans bon sens par calcul sign de triangle, et re-order si il n'est pas equation droit pour l'intersection (y-y0)/(x-x0) = (y1-y0)/(x1-x0) => parcourir y, calcul x Parcourir en ligne (y) et chercher l'interval de chaque ligne Il fault voir parcour dans quelle sens Les segments sont S01 S20 S12 (*) Class SegComp(P1, P2) => une ligne droite, (.) method .p0() et .p1() stocker 2 point P1, P2 (.) calcul _tangente, _normale, .... (.) peut creer ligne à partir de rho, theta ... (*) Class cElTriangleComp(P1, P2, P3) => un triangle (.) Quand creer un triangle, il regard si il est dans bon sens par calcul sign de triangle, et re-order si il n'est pas (.) Il creer 3 SegComp <=> 3 ligne droit de 3 cote du triangle (*) Class cSegEntierHor (.) Juste pour stocker une segmentation rasterized (une point debut mP0 et nombre pixel en direction horizontal .mNb) (***) === Program RasterTriangle === (***) (*) Chercher Ymax Ymin Xmax Xmin de triangle (*) Ligne horizontal parcourir (de Ymin -> Ymax) (*) Pour chaque ligne : (.) Chercher interval de X valab (entre 2 cote de la triangle) -- fonction ModifInterv (..) (***) === ModifInterv === (***) (*) Prendre (int aY, const SegComp & aSeg) -- aY : la ligne, aSeg : 1 cote de triangle (*) +++++====+++++ Dans ./include/im_tpl/cPtOfCorrel.h+++++====+++++ (*) Critere type fast pour selectionner les points favorables à la correl (*) class cFastCriterCompute (.) Determiner la configuration de FAST utilisé (combien de point autour, ...) (.) Calcul nombre de tout les points mNbPts dans un Flux de points entreé aFlux. (.) Sort les coordonné de point de aFlux par un aCmp (cCmpPtOnAngle), puis stocker les coordonné trié dans mVPt (.) Declarer un optim de vite calcul certain point autour ? cFastReducAssoc mFRA; mFRA ( OpMax, => Optimiser Maximal 0, => x_min mNbPts, => x_max mMaxSz-mNbPts, => dx0 mMaxSz => dx1 ) (*) Fonction examiner qualité contrast d'un point: template Pt2dr FastQuality ( TIm anIm, => image entree Pt2di aP, => Point à examiner cFastCriterCompute & aCrit, => configuration de FAST (class cFastCriterCompute) bool IsMax, => ce sont un point maximal/minimal Pt2dr aProp => proportion ) { std::vector aVVals; const std::vector & aVPt = aCrit.VPt(); //coordonne de flux de points voisin int aNbPts = aVPt.size(); typename TIm::tValueElem aDef = IsMax ? //Set valeur default El_CTypeTraits::MaxValue(): El_CTypeTraits::MinValue(); double aSign = IsMax ? 1.0 : -1.0; //Max =1, Min=-1 for (int aK=0 ; aK aFOut(aNbPts); // vector taille = aNbPts = Nb pts de tout les voisin autour double aPropStd = aProp.x; // TT_PropFastStd (0.75) double aVPerc = KthValProp(aVVals,aPropStd); // prendre valeur 75% ème dans aVVals trié double aResStd = (aV0 -aVPerc) ; // vois si ce valeur écart de valeur central 1 seuil = TT_SeuilFastStd = 5 // Definition contignu double aPropC = aProp.y; // TT_PropFastConsec (0.6) int aNbC = round_up(aPropC * aNbPts); // Nb de points voisin à examiner int aNbMin = aNbC / 2; // aCrit.FRA().Compute(-aNbMin,aNbC-aNbMin,eCFR_Per); // Ca faitttt quoiiiiiiii ???? void Compute(int aDx0,int aDx1,eComplFRA aModeC) typename TIm::tValueElem aVMin = aCrit.FRA().Out(0); for (int aK=1 ; aK