1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369 |
- /*M///////////////////////////////////////////////////////////////////////////////////////
- //
- // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
- //
- // By downloading, copying, installing or using the software you agree to this license.
- // If you do not agree to this license, do not download, install,
- // copy or use the software.
- //
- //
- // License Agreement
- // For Open Source Computer Vision Library
- //
- // Copyright (C) 2014, Biagio Montesano, all rights reserved.
- // Third party copyrights are property of their respective owners.
- //
- // Redistribution and use in source and binary forms, with or without modification,
- // are permitted provided that the following conditions are met:
- //
- // * Redistribution's of source code must retain the above copyright notice,
- // this list of conditions and the following disclaimer.
- //
- // * Redistribution's in binary form must reproduce the above copyright notice,
- // this list of conditions and the following disclaimer in the documentation
- // and/or other materials provided with the distribution.
- //
- // * The name of the copyright holders may not be used to endorse or promote products
- // derived from this software without specific prior written permission.
- //
- // This software is provided by the copyright holders and contributors "as is" and
- // any express or implied warranties, including, but not limited to, the implied
- // warranties of merchantability and fitness for a particular purpose are disclaimed.
- // In no event shall the Intel Corporation or contributors be liable for any direct,
- // indirect, incidental, special, exemplary, or consequential damages
- // (including, but not limited to, procurement of substitute goods or services;
- // loss of use, data, or profits; or business interruption) however caused
- // and on any theory of liability, whether in contract, strict liability,
- // or tort (including negligence or otherwise) arising in any way out of
- // the use of this software, even if advised of the possibility of such damage.
- //
- //M*/
- #ifndef __OPENCV_DESCRIPTOR_HPP__
- #define __OPENCV_DESCRIPTOR_HPP__
- #include <map>
- #include <vector>
- #include <list>
- #if defined _MSC_VER && _MSC_VER <= 1700
- #include <stdint.h>
- #else
- #include <inttypes.h>
- #endif
- #include <stdio.h>
- #include <iostream>
- #include "opencv2/core/utility.hpp"
- #include <opencv2/imgproc.hpp>
- #include "opencv2/core.hpp"
- /* define data types */
- typedef uint64_t UINT64;
- typedef uint32_t UINT32;
- typedef uint16_t UINT16;
- typedef uint8_t UINT8;
- /* define constants */
- #define UINT64_1 ((UINT64)0x01)
- #define UINT32_1 ((UINT32)0x01)
- namespace cv
- {
- namespace line_descriptor
- {
- //! @addtogroup line_descriptor
- //! @{
- /** @brief A class to represent a line
- As aformentioned, it is been necessary to design a class that fully stores the information needed to
- characterize completely a line and plot it on image it was extracted from, when required.
- *KeyLine* class has been created for such goal; it is mainly inspired to Feature2d's KeyPoint class,
- since KeyLine shares some of *KeyPoint*'s fields, even if a part of them assumes a different
- meaning, when speaking about lines. In particular:
- - the *class_id* field is used to gather lines extracted from different octaves which refer to
- same line inside original image (such lines and the one they represent in original image share
- the same *class_id* value)
- - the *angle* field represents line's slope with respect to (positive) X axis
- - the *pt* field represents line's midpoint
- - the *response* field is computed as the ratio between the line's length and maximum between
- image's width and height
- - the *size* field is the area of the smallest rectangle containing line
- Apart from fields inspired to KeyPoint class, KeyLines stores information about extremes of line in
- original image and in octave it was extracted from, about line's length and number of pixels it
- covers.
- */
- struct CV_EXPORTS KeyLine
- {
- public:
- /** orientation of the line */
- float angle;
- /** object ID, that can be used to cluster keylines by the line they represent */
- int class_id;
- /** octave (pyramid layer), from which the keyline has been extracted */
- int octave;
- /** coordinates of the middlepoint */
- Point2f pt;
- /** the response, by which the strongest keylines have been selected.
- It's represented by the ratio between line's length and maximum between
- image's width and height */
- float response;
- /** minimum area containing line */
- float size;
- /** lines's extremes in original image */
- float startPointX;
- float startPointY;
- float endPointX;
- float endPointY;
- /** line's extremes in image it was extracted from */
- float sPointInOctaveX;
- float sPointInOctaveY;
- float ePointInOctaveX;
- float ePointInOctaveY;
- /** the length of line */
- float lineLength;
- /** number of pixels covered by the line */
- int numOfPixels;
- /** Returns the start point of the line in the original image */
- Point2f getStartPoint() const
- {
- return Point2f(startPointX, startPointY);
- }
- /** Returns the end point of the line in the original image */
- Point2f getEndPoint() const
- {
- return Point2f(endPointX, endPointY);
- }
- /** Returns the start point of the line in the octave it was extracted from */
- Point2f getStartPointInOctave() const
- {
- return Point2f(sPointInOctaveX, sPointInOctaveY);
- }
- /** Returns the end point of the line in the octave it was extracted from */
- Point2f getEndPointInOctave() const
- {
- return Point2f(ePointInOctaveX, ePointInOctaveY);
- }
- /** constructor */
- KeyLine()
- {
- }
- };
- /** @brief Class implements both functionalities for detection of lines and computation of their
- binary descriptor.
- Class' interface is mainly based on the ones of classical detectors and extractors, such as
- Feature2d's @ref features2d_main and @ref features2d_match. Retrieved information about lines is
- stored in line_descriptor::KeyLine objects.
- */
- class CV_EXPORTS BinaryDescriptor : public Algorithm
- {
- public:
- /** @brief List of BinaryDescriptor parameters:
- */
- struct CV_EXPORTS Params
- {
- /*CV_WRAP*/
- Params();
- /** the number of image octaves (default = 1) */
- int numOfOctave_;
- /** the width of band; (default: 7) */
- int widthOfBand_;
- /** image's reduction ratio in construction of Gaussian pyramids */
- int reductionRatio;
- int ksize_;
- /** read parameters from a FileNode object and store them (struct function) */
- void read( const FileNode& fn );
- /** store parameters to a FileStorage object (struct function) */
- void write( FileStorage& fs ) const;
- };
- /** @brief Constructor
- @param parameters configuration parameters BinaryDescriptor::Params
- If no argument is provided, constructor sets default values (see comments in the code snippet in
- previous section). Default values are strongly reccomended.
- */
- BinaryDescriptor( const BinaryDescriptor::Params ¶meters = BinaryDescriptor::Params() );
- /** @brief Create a BinaryDescriptor object with default parameters (or with the ones provided)
- and return a smart pointer to it
- */
- static Ptr<BinaryDescriptor> createBinaryDescriptor();
- static Ptr<BinaryDescriptor> createBinaryDescriptor( Params parameters );
- /** destructor */
- ~BinaryDescriptor();
- /** @brief Get current number of octaves
- */
- int getNumOfOctaves();/*CV_WRAP*/
- /** @brief Set number of octaves
- @param octaves number of octaves
- */
- void setNumOfOctaves( int octaves );/*CV_WRAP*/
- /** @brief Get current width of bands
- */
- int getWidthOfBand();/*CV_WRAP*/
- /** @brief Set width of bands
- @param width width of bands
- */
- void setWidthOfBand( int width );/*CV_WRAP*/
- /** @brief Get current reduction ratio (used in Gaussian pyramids)
- */
- int getReductionRatio();/*CV_WRAP*/
- /** @brief Set reduction ratio (used in Gaussian pyramids)
- @param rRatio reduction ratio
- */
- void setReductionRatio( int rRatio );
- /** @brief Read parameters from a FileNode object and store them
- @param fn source FileNode file
- */
- virtual void read( const cv::FileNode& fn );
- /** @brief Store parameters to a FileStorage object
- @param fs output FileStorage file
- */
- virtual void write( cv::FileStorage& fs ) const;
- /** @brief Requires line detection
- @param image input image
- @param keypoints vector that will store extracted lines for one or more images
- @param mask mask matrix to detect only KeyLines of interest
- */
- void detect( const Mat& image, CV_OUT std::vector<KeyLine>& keypoints, const Mat& mask = Mat() );
- /** @overload
- @param images input images
- @param keylines set of vectors that will store extracted lines for one or more images
- @param masks vector of mask matrices to detect only KeyLines of interest from each input image
- */
- void detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, const std::vector<Mat>& masks =
- std::vector<Mat>() ) const;
- /** @brief Requires descriptors computation
- @param image input image
- @param keylines vector containing lines for which descriptors must be computed
- @param descriptors
- @param returnFloatDescr flag (when set to true, original non-binary descriptors are returned)
- */
- void compute( const Mat& image, CV_OUT CV_IN_OUT std::vector<KeyLine>& keylines, CV_OUT Mat& descriptors, bool returnFloatDescr = false ) const;
- /** @overload
- @param images input images
- @param keylines set of vectors containing lines for which descriptors must be computed
- @param descriptors
- @param returnFloatDescr flag (when set to true, original non-binary descriptors are returned)
- */
- void compute( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, std::vector<Mat>& descriptors, bool returnFloatDescr =
- false ) const;
- /** @brief Return descriptor size
- */
- int descriptorSize() const;
- /** @brief Return data type
- */
- int descriptorType() const;
- /** returns norm mode */
- /*CV_WRAP*/
- int defaultNorm() const;
- /** @brief Define operator '()' to perform detection of KeyLines and computation of descriptors in a row.
- @param image input image
- @param mask mask matrix to select which lines in KeyLines must be accepted among the ones
- extracted (used when *keylines* is not empty)
- @param keylines vector that contains input lines (when filled, the detection part will be skipped
- and input lines will be passed as input to the algorithm computing descriptors)
- @param descriptors matrix that will store final descriptors
- @param useProvidedKeyLines flag (when set to true, detection phase will be skipped and only
- computation of descriptors will be executed, using lines provided in *keylines*)
- @param returnFloatDescr flag (when set to true, original non-binary descriptors are returned)
- */
- virtual void operator()( InputArray image, InputArray mask, CV_OUT std::vector<KeyLine>& keylines, OutputArray descriptors,
- bool useProvidedKeyLines = false, bool returnFloatDescr = false ) const;
- protected:
- /** implementation of line detection */
- virtual void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, const Mat& mask = Mat() ) const;
- /** implementation of descriptors' computation */
- virtual void computeImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, Mat& descriptors, bool returnFloatDescr,
- bool useDetectionData ) const;
- private:
- /** struct to represent lines extracted from an octave */
- struct OctaveLine
- {
- unsigned int octaveCount; //the octave which this line is detected
- unsigned int lineIDInOctave; //the line ID in that octave image
- unsigned int lineIDInScaleLineVec; //the line ID in Scale line vector
- float lineLength; //the length of line in original image scale
- };
- // A 2D line (normal equation parameters).
- struct SingleLine
- {
- //note: rho and theta are based on coordinate origin, i.e. the top-left corner of image
- double rho; //unit: pixel length
- double theta; //unit: rad
- double linePointX; // = rho * cos(theta);
- double linePointY; // = rho * sin(theta);
- //for EndPoints, the coordinate origin is the top-left corner of image.
- double startPointX;
- double startPointY;
- double endPointX;
- double endPointY;
- //direction of a line, the angle between positive line direction (dark side is in the left) and positive X axis.
- double direction;
- //mean gradient magnitude
- double gradientMagnitude;
- //mean gray value of pixels in dark side of line
- double darkSideGrayValue;
- //mean gray value of pixels in light side of line
- double lightSideGrayValue;
- //the length of line
- double lineLength;
- //the width of line;
- double width;
- //number of pixels
- int numOfPixels;
- //the decriptor of line
- std::vector<double> descriptor;
- };
- // Specifies a vector of lines.
- typedef std::vector<SingleLine> Lines_list;
- struct OctaveSingleLine
- {
- /*endPoints, the coordinate origin is the top-left corner of the original image.
- *startPointX = sPointInOctaveX * (factor)^octaveCount; */
- float startPointX;
- float startPointY;
- float endPointX;
- float endPointY;
- //endPoints, the coordinate origin is the top-left corner of the octave image.
- float sPointInOctaveX;
- float sPointInOctaveY;
- float ePointInOctaveX;
- float ePointInOctaveY;
- //direction of a line, the angle between positive line direction (dark side is in the left) and positive X axis.
- float direction;
- //the summation of gradient magnitudes of pixels on lines
- float salience;
- //the length of line
- float lineLength;
- //number of pixels
- unsigned int numOfPixels;
- //the octave which this line is detected
- unsigned int octaveCount;
- //the decriptor of line
- std::vector<float> descriptor;
- OctaveSingleLine() : startPointX(0), startPointY(0), endPointX(0), endPointY(0),
- sPointInOctaveX(0), sPointInOctaveY(0), ePointInOctaveX(0), ePointInOctaveY(0),
- direction(0), salience(0), lineLength(0), numOfPixels(0), octaveCount(0),
- descriptor(std::vector<float>())
- {}
- };
- struct Pixel
- {
- unsigned int x; //X coordinate
- unsigned int y; //Y coordinate
- };
- struct EdgeChains
- {
- std::vector<unsigned int> xCors; //all the x coordinates of edge points
- std::vector<unsigned int> yCors; //all the y coordinates of edge points
- std::vector<unsigned int> sId; //the start index of each edge in the coordinate arrays
- unsigned int numOfEdges; //the number of edges whose length are larger than minLineLen; numOfEdges < sId.size;
- };
- struct LineChains
- {
- std::vector<unsigned int> xCors; //all the x coordinates of line points
- std::vector<unsigned int> yCors; //all the y coordinates of line points
- std::vector<unsigned int> sId; //the start index of each line in the coordinate arrays
- unsigned int numOfLines; //the number of lines whose length are larger than minLineLen; numOfLines < sId.size;
- };
- typedef std::list<Pixel> PixelChain; //each edge is a pixel chain
- struct EDLineParam
- {
- int ksize;
- float sigma;
- float gradientThreshold;
- float anchorThreshold;
- int scanIntervals;
- int minLineLen;
- double lineFitErrThreshold;
- };
- #define RELATIVE_ERROR_FACTOR 100.0
- #define MLN10 2.30258509299404568402
- #define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x))
- /** This class is used to detect lines from input image.
- * First, edges are extracted from input image following the method presented in Cihan Topal and
- * Cuneyt Akinlar's paper:"Edge Drawing: A Heuristic Approach to Robust Real-Time Edge Detection", 2010.
- * Then, lines are extracted from the edge image following the method presented in Cuneyt Akinlar and
- * Cihan Topal's paper:"EDLines: A real-time line segment detector with a false detection control", 2011
- * PS: The linking step of edge detection has a little bit difference with the Edge drawing algorithm
- * described in the paper. The edge chain doesn't stop when the pixel direction is changed.
- */
- class EDLineDetector
- {
- public:
- EDLineDetector();
- EDLineDetector( EDLineParam param );
- ~EDLineDetector();
- /*extract edges from image
- *image: In, gray image;
- *edges: Out, store the edges, each edge is a pixel chain
- *return -1: error happen
- */
- int EdgeDrawing( cv::Mat &image, EdgeChains &edgeChains );
- /*extract lines from image
- *image: In, gray image;
- *lines: Out, store the extracted lines,
- *return -1: error happen
- */
- int EDline( cv::Mat &image, LineChains &lines );
- /** extract line from image, and store them */
- int EDline( cv::Mat &image );
- cv::Mat dxImg_; //store the dxImg;
- cv::Mat dyImg_; //store the dyImg;
- cv::Mat gImgWO_; //store the gradient image without threshold;
- LineChains lines_; //store the detected line chains;
- //store the line Equation coefficients, vec3=[w1,w2,w3] for line w1*x + w2*y + w3=0;
- std::vector<std::vector<double> > lineEquations_;
- //store the line endpoints, [x1,y1,x2,y3]
- std::vector<std::vector<float> > lineEndpoints_;
- //store the line direction
- std::vector<float> lineDirection_;
- //store the line salience, which is the summation of gradients of pixels on line
- std::vector<float> lineSalience_;
- // image sizes
- unsigned int imageWidth;
- unsigned int imageHeight;
- /*The threshold of line fit error;
- *If lineFitErr is large than this threshold, then
- *the pixel chain is not accepted as a single line segment.*/
- double lineFitErrThreshold_;
- /*the threshold of pixel gradient magnitude.
- *Only those pixel whose gradient magnitude are larger than this threshold will be
- *taken as possible edge points. Default value is 36*/
- short gradienThreshold_;
- /*If the pixel's gradient value is bigger than both of its neighbors by a
- *certain threshold (ANCHOR_THRESHOLD), the pixel is marked to be an anchor.
- *Default value is 8*/
- unsigned char anchorThreshold_;
- /*anchor testing can be performed at different scan intervals, i.e.,
- *every row/column, every second row/column etc.
- *Default value is 2*/
- unsigned int scanIntervals_;
- int minLineLen_; //minimal acceptable line length
- private:
- void InitEDLine_();
- /*For an input edge chain, find the best fit line, the default chain length is minLineLen_
- *xCors: In, pointer to the X coordinates of pixel chain;
- *yCors: In, pointer to the Y coordinates of pixel chain;
- *offsetS:In, start index of this chain in vector;
- *lineEquation: Out, [a,b] which are the coefficient of lines y=ax+b(horizontal) or x=ay+b(vertical);
- *return: line fit error; -1:error happens;
- */
- double LeastSquaresLineFit_( unsigned int *xCors, unsigned int *yCors, unsigned int offsetS, std::vector<double> &lineEquation );
- /*For an input pixel chain, find the best fit line. Only do the update based on new points.
- *For A*x=v, Least square estimation of x = Inv(A^T * A) * (A^T * v);
- *If some new observations are added, i.e, [A; A'] * x = [v; v'],
- *then x' = Inv(A^T * A + (A')^T * A') * (A^T * v + (A')^T * v');
- *xCors: In, pointer to the X coordinates of pixel chain;
- *yCors: In, pointer to the Y coordinates of pixel chain;
- *offsetS:In, start index of this chain in vector;
- *newOffsetS: In, start index of extended part;
- *offsetE:In, end index of this chain in vector;
- *lineEquation: Out, [a,b] which are the coefficient of lines y=ax+b(horizontal) or x=ay+b(vertical);
- *return: line fit error; -1:error happens;
- */
- double LeastSquaresLineFit_( unsigned int *xCors, unsigned int *yCors, unsigned int offsetS, unsigned int newOffsetS, unsigned int offsetE,
- std::vector<double> &lineEquation );
- /** Validate line based on the Helmholtz principle, which basically states that
- * for a structure to be perceptually meaningful, the expectation of this structure
- * by chance must be very low.
- */
- bool LineValidation_( unsigned int *xCors, unsigned int *yCors, unsigned int offsetS, unsigned int offsetE, std::vector<double> &lineEquation,
- float &direction );
- bool bValidate_; //flag to decide whether line will be validated
- int ksize_; //the size of Gaussian kernel: ksize X ksize, default value is 5.
- float sigma_; //the sigma of Gaussian kernal, default value is 1.0.
- /*For example, there two edges in the image:
- *edge1 = [(7,4), (8,5), (9,6),| (10,7)|, (11, 8), (12,9)] and
- *edge2 = [(14,9), (15,10), (16,11), (17,12),| (18, 13)|, (19,14)] ; then we store them as following:
- *pFirstPartEdgeX_ = [10, 11, 12, 18, 19];//store the first part of each edge[from middle to end]
- *pFirstPartEdgeY_ = [7, 8, 9, 13, 14];
- *pFirstPartEdgeS_ = [0,3,5];// the index of start point of first part of each edge
- *pSecondPartEdgeX_ = [10, 9, 8, 7, 18, 17, 16, 15, 14];//store the second part of each edge[from middle to front]
- *pSecondPartEdgeY_ = [7, 6, 5, 4, 13, 12, 11, 10, 9];//anchor points(10, 7) and (18, 13) are stored again
- *pSecondPartEdgeS_ = [0, 4, 9];// the index of start point of second part of each edge
- *This type of storage order is because of the order of edge detection process.
- *For each edge, start from one anchor point, first go right, then go left or first go down, then go up*/
- //store the X coordinates of the first part of the pixels for chains
- unsigned int *pFirstPartEdgeX_;
- //store the Y coordinates of the first part of the pixels for chains
- unsigned int *pFirstPartEdgeY_;
- //store the start index of every edge chain in the first part arrays
- unsigned int *pFirstPartEdgeS_;
- //store the X coordinates of the second part of the pixels for chains
- unsigned int *pSecondPartEdgeX_;
- //store the Y coordinates of the second part of the pixels for chains
- unsigned int *pSecondPartEdgeY_;
- //store the start index of every edge chain in the second part arrays
- unsigned int *pSecondPartEdgeS_;
- //store the X coordinates of anchors
- unsigned int *pAnchorX_;
- //store the Y coordinates of anchors
- unsigned int *pAnchorY_;
- //edges
- cv::Mat edgeImage_;
- cv::Mat gImg_; //store the gradient image;
- cv::Mat dirImg_; //store the direction image
- double logNT_;
- cv::Mat_<float> ATA; //the previous matrix of A^T * A;
- cv::Mat_<float> ATV; //the previous vector of A^T * V;
- cv::Mat_<float> fitMatT; //the matrix used in line fit function;
- cv::Mat_<float> fitVec; //the vector used in line fit function;
- cv::Mat_<float> tempMatLineFit; //the matrix used in line fit function;
- cv::Mat_<float> tempVecLineFit; //the vector used in line fit function;
- /** Compare doubles by relative error.
- The resulting rounding error after floating point computations
- depend on the specific operations done. The same number computed by
- different algorithms could present different rounding errors. For a
- useful comparison, an estimation of the relative rounding error
- should be considered and compared to a factor times EPS. The factor
- should be related to the accumulated rounding error in the chain of
- computation. Here, as a simplification, a fixed factor is used.
- */
- static int double_equal( double a, double b )
- {
- double abs_diff, aa, bb, abs_max;
- /* trivial case */
- if( a == b )
- return true;
- abs_diff = fabs( a - b );
- aa = fabs( a );
- bb = fabs( b );
- abs_max = aa > bb ? aa : bb;
- /* DBL_MIN is the smallest normalized number, thus, the smallest
- number whose relative error is bounded by DBL_EPSILON. For
- smaller numbers, the same quantization steps as for DBL_MIN
- are used. Then, for smaller numbers, a meaningful "relative"
- error should be computed by dividing the difference by DBL_MIN. */
- if( abs_max < DBL_MIN )
- abs_max = DBL_MIN;
- /* equal if relative error <= factor x eps */
- return ( abs_diff / abs_max ) <= ( RELATIVE_ERROR_FACTOR * DBL_EPSILON );
- }
- /** Computes the natural logarithm of the absolute value of
- the gamma function of x using the Lanczos approximation.
- See http://www.rskey.org/gamma.htm
- The formula used is
- @f[
- \Gamma(x) = \frac{ \sum_{n=0}^{N} q_n x^n }{ \Pi_{n=0}^{N} (x+n) }
- (x+5.5)^{x+0.5} e^{-(x+5.5)}
- @f]
- so
- @f[
- \log\Gamma(x) = \log\left( \sum_{n=0}^{N} q_n x^n \right)
- + (x+0.5) \log(x+5.5) - (x+5.5) - \sum_{n=0}^{N} \log(x+n)
- @f]
- and
- q0 = 75122.6331530,
- q1 = 80916.6278952,
- q2 = 36308.2951477,
- q3 = 8687.24529705,
- q4 = 1168.92649479,
- q5 = 83.8676043424,
- q6 = 2.50662827511.
- */
- static double log_gamma_lanczos( double x )
- {
- static double q[7] =
- { 75122.6331530, 80916.6278952, 36308.2951477, 8687.24529705, 1168.92649479, 83.8676043424, 2.50662827511 };
- double a = ( x + 0.5 ) * log( x + 5.5 ) - ( x + 5.5 );
- double b = 0.0;
- int n;
- for ( n = 0; n < 7; n++ )
- {
- a -= log( x + (double) n );
- b += q[n] * pow( x, (double) n );
- }
- return a + log( b );
- }
- /** Computes the natural logarithm of the absolute value of
- the gamma function of x using Windschitl method.
- See http://www.rskey.org/gamma.htm
- The formula used is
- @f[
- \Gamma(x) = \sqrt{\frac{2\pi}{x}} \left( \frac{x}{e}
- \sqrt{ x\sinh(1/x) + \frac{1}{810x^6} } \right)^x
- @f]
- so
- @f[
- \log\Gamma(x) = 0.5\log(2\pi) + (x-0.5)\log(x) - x
- + 0.5x\log\left( x\sinh(1/x) + \frac{1}{810x^6} \right).
- @f]
- This formula is a good approximation when x > 15.
- */
- static double log_gamma_windschitl( double x )
- {
- return 0.918938533204673 + ( x - 0.5 ) * log( x ) - x + 0.5 * x * log( x * sinh( 1 / x ) + 1 / ( 810.0 * pow( x, 6.0 ) ) );
- }
- /** Computes -log10(NFA).
- NFA stands for Number of False Alarms:
- @f[
- \mathrm{NFA} = NT \cdot B(n,k,p)
- @f]
- - NT - number of tests
- - B(n,k,p) - tail of binomial distribution with parameters n,k and p:
- @f[
- B(n,k,p) = \sum_{j=k}^n
- \left(\begin{array}{c}n\\j\end{array}\right)
- p^{j} (1-p)^{n-j}
- @f]
- The value -log10(NFA) is equivalent but more intuitive than NFA:
- - -1 corresponds to 10 mean false alarms
- - 0 corresponds to 1 mean false alarm
- - 1 corresponds to 0.1 mean false alarms
- - 2 corresponds to 0.01 mean false alarms
- - ...
- Used this way, the bigger the value, better the detection,
- and a logarithmic scale is used.
- @param n,k,p binomial parameters.
- @param logNT logarithm of Number of Tests
- The computation is based in the gamma function by the following
- relation:
- @f[
- \left(\begin{array}{c}n\\k\end{array}\right)
- = \frac{ \Gamma(n+1) }{ \Gamma(k+1) \cdot \Gamma(n-k+1) }.
- @f]
- We use efficient algorithms to compute the logarithm of
- the gamma function.
- To make the computation faster, not all the sum is computed, part
- of the terms are neglected based on a bound to the error obtained
- (an error of 10% in the result is accepted).
- */
- static double nfa( int n, int k, double p, double logNT )
- {
- double tolerance = 0.1; /* an error of 10% in the result is accepted */
- double log1term, term, bin_term, mult_term, bin_tail, err, p_term;
- int i;
- /* check parameters */
- if( n < 0 || k < 0 || k > n || p <= 0.0 || p >= 1.0 )
- CV_Error(Error::StsBadArg, "nfa: wrong n, k or p values.\n");
- /* trivial cases */
- if( n == 0 || k == 0 )
- return -logNT;
- if( n == k )
- return -logNT - (double) n * log10( p );
- /* probability term */
- p_term = p / ( 1.0 - p );
- /* compute the first term of the series */
- /*
- binomial_tail(n,k,p) = sum_{i=k}^n bincoef(n,i) * p^i * (1-p)^{n-i}
- where bincoef(n,i) are the binomial coefficients.
- But
- bincoef(n,k) = gamma(n+1) / ( gamma(k+1) * gamma(n-k+1) ).
- We use this to compute the first term. Actually the log of it.
- */
- log1term = log_gamma( (double) n + 1.0 )- log_gamma( (double ) k + 1.0 )- log_gamma( (double ) ( n - k ) + 1.0 )
- + (double) k * log( p )
- + (double) ( n - k ) * log( 1.0 - p );
- term = exp( log1term );
- /* in some cases no more computations are needed */
- if( double_equal( term, 0.0 ) )
- { /* the first term is almost zero */
- if( (double) k > (double) n * p ) /* at begin or end of the tail? */
- return -log1term / MLN10 - logNT; /* end: use just the first term */
- else
- return -logNT; /* begin: the tail is roughly 1 */
- }
- /* compute more terms if needed */
- bin_tail = term;
- for ( i = k + 1; i <= n; i++ )
- {
- /* As
- term_i = bincoef(n,i) * p^i * (1-p)^(n-i)
- and
- bincoef(n,i)/bincoef(n,i-1) = n-i+1 / i,
- then,
- term_i / term_i-1 = (n-i+1)/i * p/(1-p)
- and
- term_i = term_i-1 * (n-i+1)/i * p/(1-p).
- p/(1-p) is computed only once and stored in 'p_term'.
- */
- bin_term = (double) ( n - i + 1 ) / (double) i;
- mult_term = bin_term * p_term;
- term *= mult_term;
- bin_tail += term;
- if( bin_term < 1.0 )
- {
- /* When bin_term<1 then mult_term_j<mult_term_i for j>i.
- Then, the error on the binomial tail when truncated at
- the i term can be bounded by a geometric series of form
- term_i * sum mult_term_i^j. */
- err = term * ( ( 1.0 - pow( mult_term, (double) ( n - i + 1 ) ) ) / ( 1.0 - mult_term ) - 1.0 );
- /* One wants an error at most of tolerance*final_result, or:
- tolerance * abs(-log10(bin_tail)-logNT).
- Now, the error that can be accepted on bin_tail is
- given by tolerance*final_result divided by the derivative
- of -log10(x) when x=bin_tail. that is:
- tolerance * abs(-log10(bin_tail)-logNT) / (1/bin_tail)
- Finally, we truncate the tail if the error is less than:
- tolerance * abs(-log10(bin_tail)-logNT) * bin_tail */
- if( err < tolerance * fabs( -log10( bin_tail ) - logNT ) * bin_tail )
- break;
- }
- }
- return -log10( bin_tail ) - logNT;
- }
- };
- // Specifies a vector of lines.
- typedef std::vector<OctaveSingleLine> LinesVec;
- // each element in ScaleLines is a vector of lines
- // which corresponds the same line detected in different octave images.
- typedef std::vector<LinesVec> ScaleLines;
- /* compute Gaussian pyramids */
- void computeGaussianPyramid( const Mat& image, const int numOctaves );
- /* compute Sobel's derivatives */
- void computeSobel( const Mat& image, const int numOctaves );
- /* conversion of an LBD descriptor to its binary representation */
- unsigned char binaryConversion( float* f1, float* f2 );
- /* compute LBD descriptors using EDLine extractor */
- int computeLBD( ScaleLines &keyLines, bool useDetectionData = false );
- /* gathers lines in groups using EDLine extractor.
- Each group contains the same line, detected in different octaves */
- int OctaveKeyLines( cv::Mat& image, ScaleLines &keyLines );
- /* the local gaussian coefficient applied to the orthogonal line direction within each band */
- std::vector<double> gaussCoefL_;
- /* the global gaussian coefficient applied to each row within line support region */
- std::vector<double> gaussCoefG_;
- /* descriptor parameters */
- Params params;
- /* vector of sizes of downsampled and blurred images */
- std::vector<cv::Size> images_sizes;
- /*For each octave of image, we define an EDLineDetector, because we can get gradient images (dxImg, dyImg, gImg)
- *from the EDLineDetector class without extra computation cost. Another reason is that, if we use
- *a single EDLineDetector to detect lines in different octave of images, then we need to allocate and release
- *memory for gradient images (dxImg, dyImg, gImg) repeatedly for their varying size*/
- std::vector<Ptr<EDLineDetector> > edLineVec_;
- /* Sobel's derivatives */
- std::vector<cv::Mat> dxImg_vector, dyImg_vector;
- /* Gaussian pyramid */
- std::vector<cv::Mat> octaveImages;
- };
- /**
- Lines extraction methodology
- ----------------------------
- The lines extraction methodology described in the following is mainly based on @cite EDL . The
- extraction starts with a Gaussian pyramid generated from an original image, downsampled N-1 times,
- blurred N times, to obtain N layers (one for each octave), with layer 0 corresponding to input
- image. Then, from each layer (octave) in the pyramid, lines are extracted using LSD algorithm.
- Differently from EDLine lines extractor used in original article, LSD furnishes information only
- about lines extremes; thus, additional information regarding slope and equation of line are computed
- via analytic methods. The number of pixels is obtained using *LineIterator*. Extracted lines are
- returned in the form of KeyLine objects, but since extraction is based on a method different from
- the one used in *BinaryDescriptor* class, data associated to a line's extremes in original image and
- in octave it was extracted from, coincide. KeyLine's field *class_id* is used as an index to
- indicate the order of extraction of a line inside a single octave.
- */
- class CV_EXPORTS LSDDetector : public Algorithm
- {
- public:
- /* constructor */
- /*CV_WRAP*/
- LSDDetector()
- {
- }
- ;
- /** @brief Creates ad LSDDetector object, using smart pointers.
- */
- static Ptr<LSDDetector> createLSDDetector();
- /** @brief Detect lines inside an image.
- @param image input image
- @param keypoints vector that will store extracted lines for one or more images
- @param scale scale factor used in pyramids generation
- @param numOctaves number of octaves inside pyramid
- @param mask mask matrix to detect only KeyLines of interest
- */
- void detect( const Mat& image, CV_OUT std::vector<KeyLine>& keypoints, int scale, int numOctaves, const Mat& mask = Mat() );
- /** @overload
- @param images input images
- @param keylines set of vectors that will store extracted lines for one or more images
- @param scale scale factor used in pyramids generation
- @param numOctaves number of octaves inside pyramid
- @param masks vector of mask matrices to detect only KeyLines of interest from each input image
- */
- void detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves,
- const std::vector<Mat>& masks = std::vector<Mat>() ) const;
- private:
- /* compute Gaussian pyramid of input image */
- void computeGaussianPyramid( const Mat& image, int numOctaves, int scale );
- /* implementation of line detection */
- void detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int numOctaves, int scale, const Mat& mask ) const;
- /* matrices for Gaussian pyramids */
- std::vector<cv::Mat> gaussianPyrs;
- };
- /** @brief furnishes all functionalities for querying a dataset provided by user or internal to
- class (that user must, anyway, populate) on the model of @ref features2d_match
- Once descriptors have been extracted from an image (both they represent lines and points), it
- becomes interesting to be able to match a descriptor with another one extracted from a different
- image and representing the same line or point, seen from a differente perspective or on a different
- scale. In reaching such goal, the main headache is designing an efficient search algorithm to
- associate a query descriptor to one extracted from a dataset. In the following, a matching modality
- based on *Multi-Index Hashing (MiHashing)* will be described.
- Multi-Index Hashing
- -------------------
- The theory described in this section is based on @cite MIH . Given a dataset populated with binary
- codes, each code is indexed *m* times into *m* different hash tables, according to *m* substrings it
- has been divided into. Thus, given a query code, all the entries close to it at least in one
- substring are returned by search as *neighbor candidates*. Returned entries are then checked for
- validity by verifying that their full codes are not distant (in Hamming space) more than *r* bits
- from query code. In details, each binary code **h** composed of *b* bits is divided into *m*
- disjoint substrings \f$\mathbf{h}^{(1)}, ..., \mathbf{h}^{(m)}\f$, each with length
- \f$\lfloor b/m \rfloor\f$ or \f$\lceil b/m \rceil\f$ bits. Formally, when two codes **h** and **g** differ
- by at the most *r* bits, in at the least one of their *m* substrings they differ by at the most
- \f$\lfloor r/m \rfloor\f$ bits. In particular, when \f$||\mathbf{h}-\mathbf{g}||_H \le r\f$ (where \f$||.||_H\f$
- is the Hamming norm), there must exist a substring *k* (with \f$1 \le k \le m\f$) such that
- \f[||\mathbf{h}^{(k)} - \mathbf{g}^{(k)}||_H \le \left\lfloor \frac{r}{m} \right\rfloor .\f]
- That means that if Hamming distance between each of the *m* substring is strictly greater than
- \f$\lfloor r/m \rfloor\f$, then \f$||\mathbf{h}-\mathbf{g}||_H\f$ must be larger that *r* and that is a
- contradiction. If the codes in dataset are divided into *m* substrings, then *m* tables will be
- built. Given a query **q** with substrings \f$\{\mathbf{q}^{(i)}\}^m_{i=1}\f$, *i*-th hash table is
- searched for entries distant at the most \f$\lfloor r/m \rfloor\f$ from \f$\mathbf{q}^{(i)}\f$ and a set of
- candidates \f$\mathcal{N}_i(\mathbf{q})\f$ is obtained. The union of sets
- \f$\mathcal{N}(\mathbf{q}) = \bigcup_i \mathcal{N}_i(\mathbf{q})\f$ is a superset of the *r*-neighbors
- of **q**. Then, last step of algorithm is computing the Hamming distance between **q** and each
- element in \f$\mathcal{N}(\mathbf{q})\f$, deleting the codes that are distant more that *r* from **q**.
- */
- class CV_EXPORTS BinaryDescriptorMatcher : public Algorithm
- {
- public:
- /** @brief For every input query descriptor, retrieve the best matching one from a dataset provided from user
- or from the one internal to class
- @param queryDescriptors query descriptors
- @param trainDescriptors dataset of descriptors furnished by user
- @param matches vector to host retrieved matches
- @param mask mask to select which input descriptors must be matched to one in dataset
- */
- void match( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<DMatch>& matches, const Mat& mask = Mat() ) const;
- /** @overload
- @param queryDescriptors query descriptors
- @param matches vector to host retrieved matches
- @param masks vector of masks to select which input descriptors must be matched to one in dataset
- (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in
- dataset relative to *i*-th image)
- */
- void match( const Mat& queryDescriptors, std::vector<DMatch>& matches, const std::vector<Mat>& masks = std::vector<Mat>() );
- /** @brief For every input query descriptor, retrieve the best *k* matching ones from a dataset provided from
- user or from the one internal to class
- @param queryDescriptors query descriptors
- @param trainDescriptors dataset of descriptors furnished by user
- @param matches vector to host retrieved matches
- @param k number of the closest descriptors to be returned for every input query
- @param mask mask to select which input descriptors must be matched to ones in dataset
- @param compactResult flag to obtain a compact result (if true, a vector that doesn't contain any
- matches for a given query is not inserted in final result)
- */
- void knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<std::vector<DMatch> >& matches, int k, const Mat& mask = Mat(),
- bool compactResult = false ) const;
- /** @overload
- @param queryDescriptors query descriptors
- @param matches vector to host retrieved matches
- @param k number of the closest descriptors to be returned for every input query
- @param masks vector of masks to select which input descriptors must be matched to ones in dataset
- (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in
- dataset relative to *i*-th image)
- @param compactResult flag to obtain a compact result (if true, a vector that doesn't contain any
- matches for a given query is not inserted in final result)
- */
- void knnMatch( const Mat& queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k, const std::vector<Mat>& masks = std::vector<Mat>(),
- bool compactResult = false );
- /** @brief For every input query descriptor, retrieve, from a dataset provided from user or from the one
- internal to class, all the descriptors that are not further than *maxDist* from input query
- @param queryDescriptors query descriptors
- @param trainDescriptors dataset of descriptors furnished by user
- @param matches vector to host retrieved matches
- @param maxDistance search radius
- @param mask mask to select which input descriptors must be matched to ones in dataset
- @param compactResult flag to obtain a compact result (if true, a vector that doesn't contain any
- matches for a given query is not inserted in final result)
- */
- void radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance,
- const Mat& mask = Mat(), bool compactResult = false ) const;
- /** @overload
- @param queryDescriptors query descriptors
- @param matches vector to host retrieved matches
- @param maxDistance search radius
- @param masks vector of masks to select which input descriptors must be matched to ones in dataset
- (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in
- dataset relative to *i*-th image)
- @param compactResult flag to obtain a compact result (if true, a vector that doesn't contain any
- matches for a given query is not inserted in final result)
- */
- void radiusMatch( const Mat& queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, const std::vector<Mat>& masks =
- std::vector<Mat>(),
- bool compactResult = false );
- /** @brief Store locally new descriptors to be inserted in dataset, without updating dataset.
- @param descriptors matrices containing descriptors to be inserted into dataset
- @note Each matrix *i* in **descriptors** should contain descriptors relative to lines extracted from
- *i*-th image.
- */
- void add( const std::vector<Mat>& descriptors );
- /** @brief Update dataset by inserting into it all descriptors that were stored locally by *add* function.
- @note Every time this function is invoked, current dataset is deleted and locally stored descriptors
- are inserted into dataset. The locally stored copy of just inserted descriptors is then removed.
- */
- void train();
- /** @brief Create a BinaryDescriptorMatcher object and return a smart pointer to it.
- */
- static Ptr<BinaryDescriptorMatcher> createBinaryDescriptorMatcher();
- /** @brief Clear dataset and internal data
- */
- void clear();
- /** @brief Constructor.
- The BinaryDescriptorMatcher constructed is able to store and manage 256-bits long entries.
- */
- BinaryDescriptorMatcher();
- /** destructor */
- ~BinaryDescriptorMatcher()
- {
- }
- private:
- class BucketGroup
- {
- public:
- /** constructor */
- BucketGroup(bool needAllocateGroup = true);
- /** destructor */
- ~BucketGroup();
- /** insert data into the bucket */
- void insert( int subindex, UINT32 data );
- /** perform a query to the bucket */
- UINT32* query( int subindex, int *size );
- /** utility functions */
- void insert_value( std::vector<uint32_t>& vec, int index, UINT32 data );
- void push_value( std::vector<uint32_t>& vec, UINT32 Data );
- /** data fields */
- UINT32 empty;
- std::vector<uint32_t> group;
- };
- class SparseHashtable
- {
- private:
- /** Maximum bits per key before folding the table */
- static const int MAX_B;
- /** Bins (each bin is an Array object for duplicates of the same key) */
- std::vector<BucketGroup> table;
- public:
- /** constructor */
- SparseHashtable();
- /** destructor */
- ~SparseHashtable();
- /** initializer */
- int init( int _b );
- /** insert data */
- void insert( UINT64 index, UINT32 data );
- /** query data */
- UINT32* query( UINT64 index, int* size );
- /** Bits per index */
- int b;
- /** Number of bins */
- UINT64 size;
- };
- /** class defining a sequence of bits */
- class bitarray
- {
- public:
- /** pointer to bits sequence and sequence's length */
- UINT32 *arr;
- UINT32 length;
- /** constructor setting default values */
- bitarray()
- {
- arr = NULL;
- length = 0;
- }
- /** constructor setting sequence's length */
- bitarray( UINT64 _bits )
- {
- arr = NULL;
- init( _bits );
- }
- /** initializer of private fields */
- void init( UINT64 _bits )
- {
- if( arr )
- delete[] arr;
- length = (UINT32) ceil( _bits / 32.00 );
- arr = new UINT32[length];
- erase();
- }
- /** destructor */
- ~bitarray()
- {
- if( arr )
- delete[] arr;
- }
- inline void flip( UINT64 index )
- {
- arr[index >> 5] ^= ( (UINT32) 0x01 ) << ( index % 32 );
- }
- inline void set( UINT64 index )
- {
- arr[index >> 5] |= ( (UINT32) 0x01 ) << ( index % 32 );
- }
- inline UINT8 get( UINT64 index )
- {
- return ( arr[index >> 5] & ( ( (UINT32) 0x01 ) << ( index % 32 ) ) ) != 0;
- }
- /** reserve menory for an UINT32 */
- inline void erase()
- {
- memset( arr, 0, sizeof(UINT32) * length );
- }
- };
- class Mihasher
- {
- public:
- /** Bits per code */
- int B;
- /** B/8 */
- int B_over_8;
- /** Bits per chunk (must be less than 64) */
- int b;
- /** Number of chunks */
- int m;
- /** Number of chunks with b bits (have 1 bit more than others) */
- int mplus;
- /** Maximum hamming search radius (we use B/2 by default) */
- int D;
- /** Maximum hamming search radius per substring */
- int d;
- /** Maximum results to return */
- int K;
- /** Number of codes */
- UINT64 N;
- /** Table of original full-length codes */
- cv::Mat codes;
- /** Counter for eliminating duplicate results (it is not thread safe) */
- Ptr<bitarray> counter;
- /** Array of m hashtables */
- std::vector<SparseHashtable> H;
- /** Volume of a b-bit Hamming ball with radius s (for s = 0 to d) */
- std::vector<UINT32> xornum;
- /** Used within generation of binary codes at a certain Hamming distance */
- int power[100];
- /** constructor */
- Mihasher();
- /** desctructor */
- ~Mihasher();
- /** constructor 2 */
- Mihasher( int B, int m );
- /** K setter */
- void setK( int K );
- /** populate tables */
- void populate( cv::Mat & codes, UINT32 N, int dim1codes );
- /** execute a batch query */
- void batchquery( UINT32 * results, UINT32 *numres/*, qstat *stats*/, const cv::Mat & q, UINT32 numq, int dim1queries );
- private:
- /** execute a single query */
- void query( UINT32 * results, UINT32* numres/*, qstat *stats*/, UINT8 *q, UINT64 * chunks, UINT32 * res );
- };
- /** retrieve Hamming distances */
- void checkKDistances( UINT32 * numres, int k, std::vector<int>& k_distances, int row, int string_length ) const;
- /** matrix to store new descriptors */
- Mat descriptorsMat;
- /** map storing where each bunch of descriptors benins in DS */
- std::map<int, int> indexesMap;
- /** internal MiHaser representing dataset */
- Ptr<Mihasher> dataset;
- /** index from which next added descriptors' bunch must begin */
- int nextAddedIndex;
- /** number of images whose descriptors are stored in DS */
- int numImages;
- /** number of descriptors in dataset */
- int descrInDS;
- };
- /* --------------------------------------------------------------------------------------------
- UTILITY FUNCTIONS
- -------------------------------------------------------------------------------------------- */
- /** struct for drawing options */
- struct CV_EXPORTS DrawLinesMatchesFlags
- {
- enum
- {
- DEFAULT = 0, //!< Output image matrix will be created (Mat::create),
- //!< i.e. existing memory of output image may be reused.
- //!< Two source images, matches, and single keylines
- //!< will be drawn.
- DRAW_OVER_OUTIMG = 1,//!< Output image matrix will not be
- //!< created (using Mat::create). Matches will be drawn
- //!< on existing content of output image.
- NOT_DRAW_SINGLE_LINES = 2//!< Single keylines will not be drawn.
- };
- };
- /** @brief Draws the found matches of keylines from two images.
- @param img1 first image
- @param keylines1 keylines extracted from first image
- @param img2 second image
- @param keylines2 keylines extracted from second image
- @param matches1to2 vector of matches
- @param outImg output matrix to draw on
- @param matchColor drawing color for matches (chosen randomly in case of default value)
- @param singleLineColor drawing color for keylines (chosen randomly in case of default value)
- @param matchesMask mask to indicate which matches must be drawn
- @param flags drawing flags, see DrawLinesMatchesFlags
- @note If both *matchColor* and *singleLineColor* are set to their default values, function draws
- matched lines and line connecting them with same color
- */
- CV_EXPORTS void drawLineMatches( const Mat& img1, const std::vector<KeyLine>& keylines1, const Mat& img2, const std::vector<KeyLine>& keylines2,
- const std::vector<DMatch>& matches1to2, Mat& outImg, const Scalar& matchColor = Scalar::all( -1 ),
- const Scalar& singleLineColor = Scalar::all( -1 ), const std::vector<char>& matchesMask = std::vector<char>(),
- int flags = DrawLinesMatchesFlags::DEFAULT );
- /** @brief Draws keylines.
- @param image input image
- @param keylines keylines to be drawn
- @param outImage output image to draw on
- @param color color of lines to be drawn (if set to defaul value, color is chosen randomly)
- @param flags drawing flags
- */
- CV_EXPORTS void drawKeylines( const Mat& image, const std::vector<KeyLine>& keylines, Mat& outImage, const Scalar& color = Scalar::all( -1 ),
- int flags = DrawLinesMatchesFlags::DEFAULT );
- //! @}
- }
- }
- #endif
|