Skip to content

Commit

Permalink
Merge branch 'mpd'
Browse files Browse the repository at this point in the history
  • Loading branch information
deseilligny committed Mar 26, 2024
2 parents f6315d9 + 387bc8e commit eccc7b5
Show file tree
Hide file tree
Showing 29 changed files with 1,427 additions and 127 deletions.
1 change: 1 addition & 0 deletions MMVII/include/MMVII_DeclareAllCmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ extern cSpecMMVII_Appli TheSpecTestSensor;
extern cSpecMMVII_Appli TheSpecParametrizeSensor;
extern cSpecMMVII_Appli TheSpec_TutoSerial;
extern cSpecMMVII_Appli TheSpec_TutoFormalDeriv;
extern cSpecMMVII_Appli TheSpecAppliExtractLine;
};

#endif // _MMVII_DeclareAllCmd_H_
195 changes: 195 additions & 0 deletions MMVII/include/MMVII_ExtractLines.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
#ifndef _MMVII_EXTRACT_LINES_H_
#define _MMVII_EXTRACT_LINES_H_
#include "MMVII_Image2D.h"


namespace MMVII
{

class cHoughTransform;
template <class Type> class cImGradWithN;
template <class Type> class cExtractLines;


class cHoughPS : public cMemCheck
{
public :
typedef cSegment2DCompiled<tREAL8> tSeg;

cHoughPS(const cHoughTransform *,const cPt2dr & aPS,tREAL8 aCumul,const cPt2dr & aP1,const cPt2dr & aP2);
/// Angular distance for line anti parallel
tREAL8 DistAnglAntiPar(const cHoughPS& aPS2) const;
tREAL8 DY(const cHoughPS&) const;
tREAL8 Dist(const cHoughPS&,const tREAL8 &aFactTeta=1.0) const;

const cPt2dr & TetaRho() const; ///< Accessor
const tREAL8 & Teta() const; ///< Accessor
const tREAL8 & Rho() const; ///< Accessor
const tSeg & Seg() const ; ///< Accessor
cHoughPS * Matched() const; ///< Accessor
const tREAL8 & Cumul() const; ///< Accessor

cPt2dr IndTetaRho() const; ///< Teta/Rho in hough accum dynamic

void Test(const cHoughPS & ) const;

bool Match(const cHoughPS &,bool IsDark,tREAL8 aMaxTeta,tREAL8 aDMin,tREAL8 aDMax) const;

static void SetMatch(std::vector<cHoughPS*>& mVPS,bool IsLight,tREAL8 aMaxTeta,tREAL8 aDMin,tREAL8 aDMax);


private :
void InitMatch();
void UpdateMatch(cHoughPS *,tREAL8 aDist);

const cHoughTransform * mHT;
cPt2dr mTetaRho;
tREAL8 mCumul;
tSeg mSegE;
cHoughPS * mMatched;
tREAL8 mDistM;
};


/** cHoughTransform
for a line L (rho=R,teta=T) with , vector orthog to (cos T,sin T) :
the equation is :
(x,y) in L <=> x cos(T) + y Sin(T) = R
For now we consider oriented line, typically when the point on a line comes from gradient,
in this case we have :
T in [0,2Pi] R in [-RMax,+RMax]
*/
class cHoughTransform
{
public :
cHoughTransform
(
const cPt2dr & aSzIn, // Sz of the space
const cPt2dr & aMulTetaRho, // Multiplicator of Rho & Teta
const tREAL8 & aSigmTeta, // Incertitude on gradient direction
cPerspCamIntrCalib * aCalib = nullptr // possible internal calib for distorsion correction
);

/// Add a point with a given direction
void AccumulatePtAndDir(const cPt2dr & aPt,tREAL8 aTeta0,tREAL8 aWeight);
cIm2D<tREAL4> Accum() const; ///< Accessor

tREAL8 AvgS2() const; ///< Avg of square, possibly use to measure "compactness"
// tREAL8 Max() const; ///< Max of val, possibly use to measure "compactness"


/// Extract the local maxima retur point/line in hough space + value of max
std::vector<cPt3dr> ExtractLocalMax
(
size_t aNbMax, // bound to number of max-loc
tREAL8 aDist, // min distance between maxima
tREAL8 aThrAvg, // threshold on Average, select if Accum > aThrAvg * Avg
tREAL8 aThrMax // threshold on Max, select if Accum > Max * Avg
) const;

/// max the conversion houg-point -> euclidian line + rho teta
cHoughPS * PtToLine(const cPt3dr &) const;

const tREAL8 & RhoMax() const; ///< Accessor
/// return the angle teta, of a given index/position in hough accumulator
inline tREAL8 RInd2Teta(tREAL8 aIndTeta) const {return aIndTeta *mFactI2T;}
/// idem, return teta for "integer" index
inline tREAL8 Ind2Teta(int aK) const {return RInd2Teta(aK);}
/// for a given teta, return the index (RInd2Teta o Teta2RInd = Identity)
inline tREAL8 Teta2RInd(const tREAL8 & aTeta) const {return aTeta /mFactI2T;}

/// return the rho of a given index/position in hough accumulator
inline tREAL8 RInd2Rho(const tREAL8 & aRInd) const { return (aRInd-1.0) / mMulRho - mRhoMax; }
/// return the index of a given rho (Rho2RInd o RInd2Rho = Identity)
inline tREAL8 Rho2RInd(const tREAL8 & aRho) const {return 1.0+ (aRho+mRhoMax) * mMulRho;}

tREAL8 GetValueBlob(cPt2di aP,int aMaxNeigh) const;
private :

// inline tREAL8 R2Teta(tREAL8 aIndTeta) const {return aIndTeta *mFactI2T;}

cPt2dr mMiddle; ///< Middle point, use a origin of Rho
tREAL8 mRhoMax; ///< Max of distance to middle point
tREAL8 mMulTeta; ///< Teta multiplier, if =1 , 1 pix teta ~ 1 pix init (in worst case)
tREAL8 mMulRho; ///< Rho multiplier , if =1, 1 pix-rho ~ 1 pix init
tREAL8 mSigmTeta; ///< incertitude on teta
cPerspCamIntrCalib* mCalib; ///< Potential calibration for distorsion
int mNbTeta; ///< Number of Teta for hough-accum
tREAL8 mFactI2T ; ///< Ratio Teta-Radian / Teta-Index
int mNbRho; ///< Number of Rho for hough-accum

cIm1D<tREAL8> mTabSin; ///< Tabulation of sinus for a given index of teta
cDataIm1D<tREAL8>& mDTabSin; ///< Data Image of "mTabSin"
cIm1D<tREAL8> mTabCos; ///< Tabulation of co-sinus for a given index of teta
cDataIm1D<tREAL8>& mDTabCos; ///< Data Image of "mTabCos"
cIm2D<tREAL4> mAccum; ///< Accumulator of Hough
cDataIm2D<tREAL4>& mDAccum; ///< Data Image of "mAccum"
};

/** Class for storing Grad + its norm
*/
template <class Type> class cImGradWithN : public cImGrad<Type>
{
public :
/// Constructor using size
cImGradWithN(const cPt2di & aSz);
/// Constructor using image & Alpha-Deriche parameters
cImGradWithN(const cDataIm2D<Type> & aImIn,Type aAlphaDeriche);



/// Is it a local-maxima in the direction of the gradient
bool IsMaxLocDirGrad(const cPt2di& aPix,const std::vector<cPt2di> &,tREAL8 aRatioXY = 1.0) const;
/// Allocat the neighbourhood use for computing local-maxima
static std::vector<cPt2di> NeighborsForMaxLoc(tREAL8 aRay);
cIm2D<Type> NormG() {return mNormG;} ///< Accessor
cPt2dr RefinePos(const cPt2dr &) const; ///< Refine a sub-pixelar position of the contour
private :
cPt2dr OneRefinePos(const cPt2dr &) const; ///< One iteration of refinement

cIm2D<Type> mNormG; ///< Image of norm of gradient
cDataIm2D<Type>& mDataNG; ///< Data Image of "mNormG"
};
/// Compute the deriche + its norm
template<class Type> void ComputeDericheAndNorm(cImGradWithN<Type> & aResGrad,const cDataIm2D<Type> & aImIn,double aAlpha) ;


/** Class for extracting line using gradient & hough transform*/

template <class Type> class cExtractLines
{
public :
typedef cIm2D<Type> tIm;
typedef cDataIm2D<Type> tDIm;

cExtractLines(tIm anIm); ///< constructor , memorize image
~cExtractLines();

/// initialize the gradient
void SetDericheGradAndMasq(tREAL8 aAlphaDerich,tREAL8 aRayMaxLoc,int aBorder,bool Show=false);
/// Initialize the hough transform
void SetHough(const cPt2dr & aMulTetaRho,tREAL8 aSigmTeta,cPerspCamIntrCalib *,bool AffineMax,bool Show=false);

/// Generate an image for visualizing the contour,
cRGBImage MakeImageMaxLoc(tREAL8 aAlphaTransparency);

cHoughTransform & Hough(); ///< Accessor
cImGradWithN<Type> & Grad(); ///< Acessor
private :
cPt2di mSz; ///< Size of the image
tIm mIm; ///< Memorize the image
cIm2D<tU_INT1> mImMasqCont; ///< Masq of point selected as contour
int mNbPtsCont; ///< Number of point detected as contour

cImGradWithN<Type> * mGrad; ///< Structure allocated for computing gradient
cHoughTransform * mHough; ///< Structure allocatedf or computing hough
cPerspCamIntrCalib * mCalib; ///< (Optional) calibration for distorsion correction
};

};
#endif // _MMVII_EXTRACT_LINES_H_
//
9 changes: 9 additions & 0 deletions MMVII/include/MMVII_Geom2D.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ template <class T> inline cPtxd<T,2> ToPolar(const cPtxd<T,2> & aP1) ///< Fro
AssertNonNul(aP1);
return cPtxd<T,2>(std::hypot(aP1.x(),aP1.y()),std::atan2(aP1.y(),aP1.x()));
}
template <class T> inline T Teta(const cPtxd<T,2> & aP1) ///< From x,y to To rho,teta
{
AssertNonNul(aP1);
return std::atan2(aP1.y(),aP1.x());
}

template <class T> inline cPtxd<T,2> ToPolar(const cPtxd<T,2> & aP1,T aDefTeta) ///< With Def value 4 teta
{
return IsNotNull(aP1) ? ToPolar(aP1) : cPtxd<T,2>(0,aDefTeta);
Expand All @@ -70,6 +76,9 @@ template <class Type> inline cPtxd<Type,2> PSymXY (const cPtxd<Type,2> & aP)
/// matrix of linear function q -> q * aP
template <class Type> cDenseMatrix<Type> MatOfMul (const cPtxd<Type,2> & aP);

/** This specialization is specific to dim 2, as the normal to a vector is
* specific to d2
*/
template <class Type> class cSegment2DCompiled : public cSegmentCompiled<Type,2>
{
public :
Expand Down
16 changes: 14 additions & 2 deletions MMVII/include/MMVII_Linear2DFiltering.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,18 @@ template <class Type> class cGaussianPyramid : public cMemCheck
template <class Type> class cImGrad
{
public :
cIm2D<Type> mGx;
cIm2D<Type> mGy;
cIm2D<Type> mGx;
cDataIm2D<Type>* mDGx;
cIm2D<Type> mGy;
cDataIm2D<Type>* mDGy;

const Type & Gx(const cPt2di & aPix) const {return mDGx->GetV(aPix);}
const Type & Gy(const cPt2di & aPix) const {return mDGy->GetV(aPix);}
cPtxd<Type,2> Grad(const cPt2di & aPix) const {return cPtxd<Type,2>(Gx(aPix),Gy(aPix));}

Type GxBL(const cPt2dr & aPix) const {return mDGx->GetVBL(aPix);}
Type GyBL(const cPt2dr & aPix) const {return mDGy->GetVBL(aPix);}
cPtxd<Type,2> GradBL(const cPt2dr & aPix) const {return cPtxd<Type,2>(GxBL(aPix),GyBL(aPix));}
/// memorize
cImGrad(const cIm2D<Type> & aGx,const cIm2D<Type> & aGy) ;
/// Use size to allocate
Expand All @@ -373,6 +383,8 @@ template <class Type> class cImGrad
};

template<class Type> cImGrad<Type> Deriche(const cDataIm2D<Type> &aImIn,double aAlpha);
template<class Type> void ComputeDeriche(cImGrad<Type> & aResGrad,const cDataIm2D<Type> & aImIn,double aAlpha);



};
Expand Down
3 changes: 3 additions & 0 deletions MMVII/include/MMVII_PCSens.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ class cPerspCamIntrCalib : public cObj2DelAtEnd,
dont see what can be done ... */
tPtOut Undist(const tPtOut &) const;

/** Inverse function of Undist ... */
tPtOut Redist(const tPtOut &) const;



// ================== Accessors & Modifiers ===================
Expand Down
4 changes: 4 additions & 0 deletions MMVII/include/MMVII_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ enum class eTA2007
FileImage, ///< File containing an image
FileCloud, ///< File containing a cloud file (ply ?)
File3DRegion, ///< File containing a 3D region
FileTagged, ///< File containing a "xml" or "json" extension
FileTxt, ///< Text file, no extension specified
FileAny, ///< Any file, no more specificiation can be given
FolderAny, ///< Any folder, no more specificiation can be given
MPatFile, ///< Major PaternIm => "" or "0" in sem for set1, "1" or other for set2
FFI, ///< File Filter Interval
Orient, ///< Orientation
Expand Down
29 changes: 29 additions & 0 deletions MMVII/include/MMVII_util_tpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,34 @@ template <class Type> cSelector<Type> Str2Interv(const std::string & aStr);
/* */
/* ============================================= */

template <class Type> class cTransformator
{
public :
virtual Type Transfo(const Type &) const = 0;
};

template <class Type> class cIdTransformator : public cTransformator<Type>
{
public :
Type Transfo(const Type &) const override;
};

/** Transformation by pattern of regular expression */
class cPatternTransfo : public cTransformator<std::string>
{
public :
cPatternTransfo(const std::string & aPat,const std::string & aSubst);
/// Can be 2 vect or empty
cPatternTransfo(const std::vector<std::string> & aPat);

std::string Transfo(const std::string &) const override;
private :
std::string mPat;
std::string mSubst;
};




/// Bench some sets functionnalities
void BenchSet(const std::string & aDir);
Expand Down Expand Up @@ -125,6 +153,7 @@ template <class Type> class cExtSet : public cSelector<Type>
bool Suppress(const Type &) ;
void clear() ;
int size() const ;
void Filter(const cSelector<Type> &,const cTransformator<Type>&);
void Filter(const cSelector<Type> &);

virtual void PutInVect(std::vector<const Type *> &,bool Sorted) const ; ///< Some type requires iteration
Expand Down
3 changes: 3 additions & 0 deletions MMVII/include/V1VII.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ std::string V1NameMasqOfIm(const std::string & aName);

// Call V1 Fast kth value extraction
double KthVal(std::vector<double> &, double aProportion);
// Idem but indicate a number and not a proportion
double IKthVal(std::vector<double> & aV, int aK);


// Call V1 for roots of polynomials
template <class Type> std::vector<Type> V1RealRoots(const std::vector<Type> & aVCoef, Type aTol,int aNbMaxIter);
Expand Down
1 change: 1 addition & 0 deletions MMVII/include/cMMVII_Appli.h
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,7 @@ class cMMVII_Appli : public cMMVII_Ap_NameManip,
bool mRMSWasUsed; ///< Indicate if MultiCall was used

std::string mIntervFilterMS[NbMaxMainSets]; ///< Filterings interval
std::vector<std::string> mTransfoFFI[NbMaxMainSets]; ///< Pattern of transformation for FFI

// Variable for setting num of mm version for output
int mNumOutPut; ///< specified by user
Expand Down
Loading

0 comments on commit eccc7b5

Please sign in to comment.