diff --git a/modules/line_descriptor/.cproject b/modules/line_descriptor/.cproject index 2c0bf0728..6b4844717 100644 --- a/modules/line_descriptor/.cproject +++ b/modules/line_descriptor/.cproject @@ -1,34 +1,30 @@ - - + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + @@ -36,9 +32,6 @@ - - - @@ -48,5 +41,8 @@ + + + diff --git a/modules/line_descriptor/CMakeFiles/CMakeCCompiler.cmake b/modules/line_descriptor/CMakeFiles/CMakeCCompiler.cmake deleted file mode 100644 index 657f5b0ec..000000000 --- a/modules/line_descriptor/CMakeFiles/CMakeCCompiler.cmake +++ /dev/null @@ -1,49 +0,0 @@ -SET(CMAKE_C_COMPILER "/usr/bin/gcc") -SET(CMAKE_C_COMPILER_ARG1 "") -SET(CMAKE_C_COMPILER_ID "GNU") -SET(CMAKE_C_PLATFORM_ID "Linux") - -SET(CMAKE_AR "/usr/bin/ar") -SET(CMAKE_RANLIB "/usr/bin/ranlib") -SET(CMAKE_LINKER "/usr/bin/ld") -SET(CMAKE_COMPILER_IS_GNUCC 1) -SET(CMAKE_C_COMPILER_LOADED 1) -SET(CMAKE_COMPILER_IS_MINGW ) -SET(CMAKE_COMPILER_IS_CYGWIN ) -IF(CMAKE_COMPILER_IS_CYGWIN) - SET(CYGWIN 1) - SET(UNIX 1) -ENDIF(CMAKE_COMPILER_IS_CYGWIN) - -SET(CMAKE_C_COMPILER_ENV_VAR "CC") - -IF(CMAKE_COMPILER_IS_MINGW) - SET(MINGW 1) -ENDIF(CMAKE_COMPILER_IS_MINGW) -SET(CMAKE_C_COMPILER_ID_RUN 1) -SET(CMAKE_C_SOURCE_FILE_EXTENSIONS c) -SET(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC) -SET(CMAKE_C_LINKER_PREFERENCE 10) - -# Save compiler ABI information. -SET(CMAKE_C_SIZEOF_DATA_PTR "8") -SET(CMAKE_C_COMPILER_ABI "ELF") -SET(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") - -IF(CMAKE_C_SIZEOF_DATA_PTR) - SET(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}") -ENDIF(CMAKE_C_SIZEOF_DATA_PTR) - -IF(CMAKE_C_COMPILER_ABI) - SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}") -ENDIF(CMAKE_C_COMPILER_ABI) - -IF(CMAKE_C_LIBRARY_ARCHITECTURE) - SET(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") -ENDIF() - -SET(CMAKE_C_HAS_ISYSROOT "") - - -SET(CMAKE_C_IMPLICIT_LINK_LIBRARIES "c") -SET(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") diff --git a/modules/line_descriptor/CMakeFiles/CMakeCXXCompiler.cmake b/modules/line_descriptor/CMakeFiles/CMakeCXXCompiler.cmake deleted file mode 100644 index f62d04d96..000000000 --- a/modules/line_descriptor/CMakeFiles/CMakeCXXCompiler.cmake +++ /dev/null @@ -1,50 +0,0 @@ -SET(CMAKE_CXX_COMPILER "/usr/bin/c++") -SET(CMAKE_CXX_COMPILER_ARG1 "") -SET(CMAKE_CXX_COMPILER_ID "GNU") -SET(CMAKE_CXX_PLATFORM_ID "Linux") - -SET(CMAKE_AR "/usr/bin/ar") -SET(CMAKE_RANLIB "/usr/bin/ranlib") -SET(CMAKE_LINKER "/usr/bin/ld") -SET(CMAKE_COMPILER_IS_GNUCXX 1) -SET(CMAKE_CXX_COMPILER_LOADED 1) -SET(CMAKE_COMPILER_IS_MINGW ) -SET(CMAKE_COMPILER_IS_CYGWIN ) -IF(CMAKE_COMPILER_IS_CYGWIN) - SET(CYGWIN 1) - SET(UNIX 1) -ENDIF(CMAKE_COMPILER_IS_CYGWIN) - -SET(CMAKE_CXX_COMPILER_ENV_VAR "CXX") - -IF(CMAKE_COMPILER_IS_MINGW) - SET(MINGW 1) -ENDIF(CMAKE_COMPILER_IS_MINGW) -SET(CMAKE_CXX_COMPILER_ID_RUN 1) -SET(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC) -SET(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP) -SET(CMAKE_CXX_LINKER_PREFERENCE 30) -SET(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1) - -# Save compiler ABI information. -SET(CMAKE_CXX_SIZEOF_DATA_PTR "8") -SET(CMAKE_CXX_COMPILER_ABI "ELF") -SET(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") - -IF(CMAKE_CXX_SIZEOF_DATA_PTR) - SET(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}") -ENDIF(CMAKE_CXX_SIZEOF_DATA_PTR) - -IF(CMAKE_CXX_COMPILER_ABI) - SET(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}") -ENDIF(CMAKE_CXX_COMPILER_ABI) - -IF(CMAKE_CXX_LIBRARY_ARCHITECTURE) - SET(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") -ENDIF() - -SET(CMAKE_CXX_HAS_ISYSROOT "") - - -SET(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;c") -SET(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/4.6;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib") diff --git a/modules/line_descriptor/CMakeFiles/CMakeDirectoryInformation.cmake b/modules/line_descriptor/CMakeFiles/CMakeDirectoryInformation.cmake deleted file mode 100644 index d5f94985a..000000000 --- a/modules/line_descriptor/CMakeFiles/CMakeDirectoryInformation.cmake +++ /dev/null @@ -1,33 +0,0 @@ -# CMAKE generated file: DO NOT EDIT! -# Generated by "Unix Makefiles" Generator, CMake Version 2.8 - -# Relative path conversion top directories. -SET(CMAKE_RELATIVE_PATH_TOP_SOURCE "/home/ubisum/src/opencv") -SET(CMAKE_RELATIVE_PATH_TOP_BINARY "/home/ubisum/src/opencv") - -# Force unix paths in dependencies. -SET(CMAKE_FORCE_UNIX_PATHS 1) - -# The C and CXX include file search paths: -SET(CMAKE_C_INCLUDE_PATH - "modules/optim/include" - "modules/features2d/include" - "modules/highgui/include" - "modules/imgproc/include" - "modules/flann/include" - "modules/core/include" - "modules/line_descriptor" - "modules/line_descriptor/src" - "modules/line_descriptor/include" - "." - "/usr/local/include/eigen3" - ) -SET(CMAKE_CXX_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) -SET(CMAKE_Fortran_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) -SET(CMAKE_ASM_INCLUDE_PATH ${CMAKE_C_INCLUDE_PATH}) - -# The C and CXX include file regular expressions for this directory. -SET(CMAKE_C_INCLUDE_REGEX_SCAN "^.*$") -SET(CMAKE_C_INCLUDE_REGEX_COMPLAIN "^$") -SET(CMAKE_CXX_INCLUDE_REGEX_SCAN ${CMAKE_C_INCLUDE_REGEX_SCAN}) -SET(CMAKE_CXX_INCLUDE_REGEX_COMPLAIN ${CMAKE_C_INCLUDE_REGEX_COMPLAIN}) diff --git a/modules/line_descriptor/CMakeFiles/CMakeSystem.cmake b/modules/line_descriptor/CMakeFiles/CMakeSystem.cmake deleted file mode 100644 index 9bd3958b4..000000000 --- a/modules/line_descriptor/CMakeFiles/CMakeSystem.cmake +++ /dev/null @@ -1,15 +0,0 @@ - - -SET(CMAKE_SYSTEM "Linux-3.8.0-38-generic") -SET(CMAKE_SYSTEM_NAME "Linux") -SET(CMAKE_SYSTEM_VERSION "3.8.0-38-generic") -SET(CMAKE_SYSTEM_PROCESSOR "x86_64") - -SET(CMAKE_HOST_SYSTEM "Linux-3.8.0-38-generic") -SET(CMAKE_HOST_SYSTEM_NAME "Linux") -SET(CMAKE_HOST_SYSTEM_VERSION "3.8.0-38-generic") -SET(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64") - -SET(CMAKE_CROSSCOMPILING "FALSE") - -SET(CMAKE_SYSTEM_LOADED 1) diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/EDLineDetector.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/EDLineDetector.hpp deleted file mode 100644 index ab5ad4e43..000000000 --- a/modules/line_descriptor/include/opencv2/line_descriptor/EDLineDetector.hpp +++ /dev/null @@ -1,440 +0,0 @@ -/*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) 2011-2012, Lilian Zhang, all rights reserved. -Copyright (C) 2013, Manuele Tamburrano, Stefano Fabri, 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: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions 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. -*/ - -#ifndef EDLINEDETECTOR_HH_ -#define EDLINEDETECTOR_HH_ - -#include -#include -#include -#include -//#include -#include -//#include -#include -//#include -#include -#include - -#include -#include - - -struct Pixel{ - unsigned int x;//X coordinate - unsigned int y;//Y coordinate -}; -struct EdgeChains{ - std::vector xCors;//all the x coordinates of edge points - std::vector yCors;//all the y coordinates of edge points - std::vector 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 xCors;//all the x coordinates of line points - std::vector yCors;//all the y coordinates of line points - std::vector 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 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 M_LN10 2.30258509299404568402 -#define log_gamma(x) ((x)>15.0?log_gamma_windschitl(x):log_gamma_lanczos(x)) - - -inline void writeMat(cv::Mat m, std::string name, int n) -{ - std::stringstream ss; - std::string s; - ss << n; - ss >> s; - std::string fileNameConf = name + s; - cv::FileStorage fsConf(fileNameConf, cv::FileStorage::WRITE); - cv::FileStorage fsConf(); - fsConf << "m" << m; - - fsConf.release(); -} - -/* 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 - *smoothed: In, flag to mark whether the image has already been smoothed by Gaussian filter. - *return -1: error happen - */ - int EdgeDrawing(cv::Mat &image, EdgeChains &edgeChains, bool smoothed=false); - /*extract lines from image - *image: In, gray image; - *lines: Out, store the extracted lines, - *smoothed: In, flag to mark whether the image has already been smoothed by Gaussian filter. - *return -1: error happen - */ - int EDline(cv::Mat &image, LineChains &lines, bool smoothed=false); - /*extract line from image, and store them*/ - int EDline(cv::Mat &image, bool smoothed=false); - - 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 > lineEquations_; - //store the line endpoints, [x1,y1,x2,y3] - std::vector > lineEndpoints_; - //store the line direction - std::vector lineDirection_; - //store the line salience, which is the summation of gradients of pixels on line - std::vector lineSalience_; - 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 array; - *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::array &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 array; - *newOffsetS: In, start index of extended part; - *offsetE:In, end index of this chain in array; - *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::array &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::array &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*/ - unsigned int *pFirstPartEdgeX_;//store the X coordinates of the first part of the pixels for chains - unsigned int *pFirstPartEdgeY_;//store the Y coordinates of the first part of the pixels for chains - unsigned int *pFirstPartEdgeS_;//store the start index of every edge chain in the first part arrays - unsigned int *pSecondPartEdgeX_;//store the X coordinates of the second part of the pixels for chains - unsigned int *pSecondPartEdgeY_;//store the Y coordinates of the second part of the pixels for chains - unsigned int *pSecondPartEdgeS_;//store the start index of every edge chain in the second part arrays - unsigned int *pAnchorX_;//store the X coordinates of anchors - unsigned int *pAnchorY_;//store the Y coordinates of anchors - cv::Mat edgeImage_; - - - - cv::Mat gImg_;//store the gradient image; - cv::Mat dirImg_;//store the direction image - double logNT_; - cv::Mat_ ATA; //the previous matrix of A^T * A; - cv::Mat_ ATV; //the previous vector of A^T * V; - cv::Mat_ fitMatT; //the matrix used in line fit function; - cv::Mat_ fitVec; //the vector used in line fit function; - cv::Mat_ tempMatLineFit; //the matrix used in line fit function; - cv::Mat_ 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 ){ - std::cout<<"nfa: wrong n, k or p values."< (double) n * p ) /* at begin or end of the tail? */ - return -log1term / M_LN10 - 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_ji. - 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; - } -}; - -#endif /* EDLINEDETECTOR_HH_ */ diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/LineDescriptor.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/LineDescriptor.hpp deleted file mode 100644 index 1279ff476..000000000 --- a/modules/line_descriptor/include/opencv2/line_descriptor/LineDescriptor.hpp +++ /dev/null @@ -1,141 +0,0 @@ -/*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) 2011-2012, Lilian Zhang, all rights reserved. -Copyright (C) 2013, Manuele Tamburrano, Stefano Fabri, 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: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions 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. -*/ - -#ifndef LINEDESCRIPTOR_HH_ -#define LINEDESCRIPTOR_HH_ - - -//#include "EDLineDetector.hh" -//#include "LineStructure.hh" - -//#include "/include/opencv2/line_descriptor/EDLineDetector.hpp" -//#include "opencv2/line_descriptor/LineStructure.hpp" - -//#include "opencv2/EDLineDetector.hpp" -//#include "opencv2/LineStructure.hpp" - -#include "precomp.hpp" - -#include -#include - -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 -}; - - -/* This class is used to generate the line descriptors from multi-scale images */ -class LineDescriptor -{ -public: - LineDescriptor(int n_octave); - LineDescriptor(unsigned int numOfBand, unsigned int widthOfBand, int n_octave); - ~LineDescriptor(); - enum{ - NearestNeighbor=0, //the nearest neighbor is taken as matching - NNDR=1//nearest/next ratio - }; - - /*This function is used to detect lines from multi-scale images.*/ - int OctaveKeyLines(cv::Mat & image, ScaleLines &keyLines); - int GetLineDescriptor(cv::Mat & image, ScaleLines &keyLines); - int GetLineDescriptor(std::vector &scale_images, ScaleLines &keyLines); - - void findNearestParallelLines(ScaleLines & keyLines); - - void GetLineBinaryDescriptor(std::vector & oct_binaryDescMat, ScaleLines &keyLines); - int MatchLineByDescriptor(ScaleLines &keyLinesLeft, ScaleLines &keyLinesRight, - std::vector &matchLeft, std::vector &matchRight, - int criteria=NNDR); - float LowestThreshold;//global threshold for line descriptor distance, default is 0.35 - float NNDRThreshold;//the NNDR threshold for line descriptor distance, default is 0.6 - - int ksize_; //the size of Gaussian kernel: ksize X ksize, default value is 5. - unsigned int numOfOctave_;//the number of image octave - unsigned int numOfBand_;//the number of band used to compute line descriptor - unsigned int widthOfBand_;//the width of band; - std::vector gaussCoefL_;//the local gaussian coefficient apply to the orthogonal line direction within each band; - std::vector gaussCoefG_;//the global gaussian coefficient apply to each Row within line support region - - -private: - - void sample(float *igray,float *ogray, float factor, int width, int height) - { - - int swidth = (int)((float) width / factor); - int sheight = (int)((float) height / factor); - - for(int j=0; j < sheight; j++) - for(int i=0; i < swidth; i++) - ogray[j*swidth + i] = igray[(int)((float) j * factor) * width + (int) ((float) i*factor)]; - - } - void sampleUchar(uchar *igray,uchar *ogray, float factor, int width, int height) - { - - int swidth = (int)((float) width / factor); - int sheight = (int)((float) height / factor); - - for(int j=0; j < sheight; j++) - for(int i=0; i < swidth; i++) - ogray[j*swidth + i] = igray[(int)((float) j * factor) * width + (int) ((float) i*factor)]; - - } - /*Compute the line descriptor of input line set. This function should be called - *after OctaveKeyLines() function; */ - int ComputeLBD_(ScaleLines &keyLines); - /*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 edLineVec_; - - -}; - - - - - - -#endif /* LINEDESCRIPTOR_HH_ */ diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/array32.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/array32.hpp index 22bde4f18..41f65e33d 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/array32.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/array32.hpp @@ -1,7 +1,44 @@ -/* dynamic array of 32-bit integers - * arr[0] : array size - * arr[1] : array capacity - * arr[2..] : array content */ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_ARRAY32_HPP #define __OPENCV_ARRAY32_HPP diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/bitarray.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/bitarray.hpp index 978855e31..86472e0e5 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/bitarray.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/bitarray.hpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_BITARRAY_HPP #define __OPENCV_BITARRAY_HPP diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/bitops.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/bitops.hpp index 9cbcc5a51..1a3ab5f79 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/bitops.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/bitops.hpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_BITOPTS_HPP #define __OPENCV_BITOPTS_HPP diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/bucket_group.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/bucket_group.hpp index 462676ae2..5374c31a5 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/bucket_group.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/bucket_group.hpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_BUCKET_GROUP_HPP #define __OPENCV_BUCKET_GROUP_HPP diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp index 2bb5c0ae5..b66da3a91 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/descriptor.hpp @@ -10,7 +10,7 @@ // License Agreement // For Open Source Computer Vision Library // - // Copyright (C) 2013, OpenCV Foundation, all rights reserved. + // 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, @@ -39,14 +39,11 @@ // //M*/ -//#ifdef __OPENCV_BUILD -//#error this is a compatibility header which should not be used inside the OpenCV library -//#endif #ifndef __OPENCV_DESCRIPTOR_HPP__ #define __OPENCV_DESCRIPTOR_HPP__ -#include "LineStructure.hpp" +#include "line_structure.hpp" #include "array32.hpp" #include "bitarray.hpp" #include "bitops.hpp" diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/line_detector.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/line_detector.hpp deleted file mode 100644 index 454ca79cd..000000000 --- a/modules/line_descriptor/include/opencv2/line_descriptor/line_detector.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/*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) 2013, OpenCV Foundation, 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*/ - -#ifdef __OPENCV_BUILD -#error this is a compatibility header which should not be used inside the OpenCV library -#endif - -#include "opencv2/line_descriptor.hpp" diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/LineStructure.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/line_structure.hpp similarity index 93% rename from modules/line_descriptor/include/opencv2/line_descriptor/LineStructure.hpp rename to modules/line_descriptor/include/opencv2/line_descriptor/line_structure.hpp index c765310b0..bfb859ca2 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/LineStructure.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/line_structure.hpp @@ -10,6 +10,7 @@ Copyright (C) 2011-2012, Lilian Zhang, all rights reserved. Copyright (C) 2013, Manuele Tamburrano, Stefano Fabri, all rights reserved. +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, @@ -37,8 +38,8 @@ 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. */ -#ifndef LINESTRUCTURE_HH_ -#define LINESTRUCTURE_HH_ +#ifndef __OPENCV_LINE_STRUCTURE_HH_ +#define __OPENCV_LINE_STRUCTURE_HH_ #include @@ -114,6 +115,8 @@ struct OctaveSingleLine // Specifies a vector of lines. typedef std::vector LinesVec; -typedef std::vector ScaleLines;//each element in ScaleLines is a vector of lines which corresponds the same line detected in different octave images. +// each element in ScaleLines is a vector of lines +// which corresponds the same line detected in different octave images. +typedef std::vector ScaleLines; -#endif /* LINESTRUCTURE_HH_ */ +#endif diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/mihasher.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/mihasher.hpp index 353692006..ea55b1b67 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/mihasher.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/mihasher.hpp @@ -1,18 +1,56 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_MIHASHER_HPP #define __OPENCV_MIHASHER_HPP #include "types.hpp" #include "bitops.hpp" - #include "sparse_hashtable.hpp" #include "bitarray.hpp" #include #include -//#include -//#include - class Mihasher { private: @@ -82,7 +120,7 @@ class Mihasher { private: /* execute a single query */ - void query(UINT32 * results, UINT32* numres/*, qstat *stats*/, UINT8 *q, UINT64 * chunks, UINT32 * res, int query_i); + void query(UINT32 * results, UINT32* numres/*, qstat *stats*/, UINT8 *q, UINT64 * chunks, UINT32 * res); }; #endif diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/sparse_hashtable.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/sparse_hashtable.hpp index bf53cb0b4..09b5c9c64 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/sparse_hashtable.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/sparse_hashtable.hpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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_SPARSE_HASHTABLE_HPP #define __OPENCV_SPARSE_HASHTABLE_HPP diff --git a/modules/line_descriptor/include/opencv2/line_descriptor/types.hpp b/modules/line_descriptor/include/opencv2/line_descriptor/types.hpp index af8490a9b..ac16810d2 100644 --- a/modules/line_descriptor/include/opencv2/line_descriptor/types.hpp +++ b/modules/line_descriptor/include/opencv2/line_descriptor/types.hpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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*/ + #include #ifndef __OPENCV_TYPES_HPP diff --git a/modules/line_descriptor/include/opencv2/line_detector.hpp b/modules/line_descriptor/include/opencv2/line_detector.hpp deleted file mode 100644 index b0c32040f..000000000 --- a/modules/line_descriptor/include/opencv2/line_detector.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/*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) 2013, OpenCV Foundation, 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_TRACKING_HPP__ -#define __OPENCV_TRACKING_HPP__ - -#include "opencv2/line_descriptor/line_descriptor.hpp" - -namespace cv -{ -CV_EXPORTS bool initModule_line_descriptor(void); -} - -#endif //__OPENCV_TRACKING_HPP__ diff --git a/modules/line_descriptor/samples/compute_descriptors.cpp b/modules/line_descriptor/samples/compute_descriptors.cpp index c523a8050..c9cc1994d 100644 --- a/modules/line_descriptor/samples/compute_descriptors.cpp +++ b/modules/line_descriptor/samples/compute_descriptors.cpp @@ -1,3 +1,44 @@ +/*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*/ + #include @@ -51,7 +92,7 @@ int main( int argc, char** argv ) } /* load image */ - cv::Mat imageMat = imread(image_path, 0); + cv::Mat imageMat = imread(image_path, 1); if(imageMat.data == NULL) { std::cout << "Error, image could not be loaded. Please, check its path" << std::endl; diff --git a/modules/line_descriptor/samples/images/cameraman.jpg b/modules/line_descriptor/samples/images/cameraman.jpg deleted file mode 100644 index 9345b9215..000000000 Binary files a/modules/line_descriptor/samples/images/cameraman.jpg and /dev/null differ diff --git a/modules/line_descriptor/samples/images/church.jpg b/modules/line_descriptor/samples/images/church.jpg deleted file mode 100644 index 3801b4339..000000000 Binary files a/modules/line_descriptor/samples/images/church.jpg and /dev/null differ diff --git a/modules/line_descriptor/samples/images/church2.png b/modules/line_descriptor/samples/images/church2.png deleted file mode 100644 index 66fc80c36..000000000 Binary files a/modules/line_descriptor/samples/images/church2.png and /dev/null differ diff --git a/modules/line_descriptor/samples/images/einstein.jpg b/modules/line_descriptor/samples/images/einstein.jpg deleted file mode 100644 index 38d977895..000000000 Binary files a/modules/line_descriptor/samples/images/einstein.jpg and /dev/null differ diff --git a/modules/line_descriptor/samples/images/stuff.jpg b/modules/line_descriptor/samples/images/stuff.jpg deleted file mode 100644 index 42cb9cb6a..000000000 Binary files a/modules/line_descriptor/samples/images/stuff.jpg and /dev/null differ diff --git a/modules/line_descriptor/samples/knn_matching.cpp b/modules/line_descriptor/samples/knn_matching.cpp index 728447a98..745919f20 100644 --- a/modules/line_descriptor/samples/knn_matching.cpp +++ b/modules/line_descriptor/samples/knn_matching.cpp @@ -1,3 +1,44 @@ +/*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*/ + #include #include "opencv2/core/utility.hpp" diff --git a/modules/line_descriptor/samples/lines_extraction.cpp b/modules/line_descriptor/samples/lines_extraction.cpp index 2f8579709..c6aac54de 100644 --- a/modules/line_descriptor/samples/lines_extraction.cpp +++ b/modules/line_descriptor/samples/lines_extraction.cpp @@ -1,3 +1,44 @@ +/*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*/ + #include #include "opencv2/core/utility.hpp" @@ -38,7 +79,7 @@ int main( int argc, char** argv ) } /* load image */ - cv::Mat imageMat = imread(image_path, 0); + cv::Mat imageMat = imread(image_path, 1); if(imageMat.data == NULL) { std::cout << "Error, image could not be loaded. Please, check its path" << std::endl; @@ -59,7 +100,8 @@ int main( int argc, char** argv ) /* draw lines extracted from octave 0 */ cv::Mat output = imageMat.clone(); - cvtColor(output, output, COLOR_GRAY2BGR); + if(output.channels() == 1) + cvtColor(output, output, COLOR_GRAY2BGR); for(size_t i = 0; i #include "opencv2/core/utility.hpp" diff --git a/modules/line_descriptor/samples/radius_matching.cpp b/modules/line_descriptor/samples/radius_matching.cpp index 4ddf80ac8..164fab5ac 100644 --- a/modules/line_descriptor/samples/radius_matching.cpp +++ b/modules/line_descriptor/samples/radius_matching.cpp @@ -1,3 +1,44 @@ +/*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*/ + #include #include "opencv2/core/utility.hpp" @@ -12,100 +53,88 @@ using namespace cv; static const std::string images[] = -{ - "cameraman.jpg", - "church.jpg", - "church2.png", - "einstein.jpg", - "stuff.jpg" -}; +{ "cameraman.jpg", "church.jpg", "church2.png", "einstein.jpg", "stuff.jpg" }; static const char* keys = -{ - "{@image_path | | Image path }" -}; +{ "{@image_path | | Image path }" }; static void help() { - std::cout << "\nThis example shows the functionalities of radius matching " << - "Please, run this sample using a command in the form\n" << - "./example_line_descriptor_radius_matching /" - << std::endl; + std::cout << "\nThis example shows the functionalities of radius matching " << "Please, run this sample using a command in the form\n" + << "./example_line_descriptor_radius_matching /" << std::endl; } int main( int argc, char** argv ) { - /* get parameters from comand line */ - CommandLineParser parser( argc, argv, keys ); - String pathToImages = parser.get( 0 ); + /* get parameters from comand line */ + CommandLineParser parser( argc, argv, keys ); + String pathToImages = parser.get( 0 ); - /* create structures for hosting KeyLines and descriptors */ - int num_elements = sizeof( images ) / sizeof( images[0] ); - std::vector descriptorsMat; - std::vector > linesMat; + /* create structures for hosting KeyLines and descriptors */ + int num_elements = sizeof ( images ) / sizeof ( images[0] ); + std::vector descriptorsMat; + std::vector > linesMat; - /*create a pointer to a BinaryDescriptor object */ - Ptr bd = BinaryDescriptor::createBinaryDescriptor(); + /*create a pointer to a BinaryDescriptor object */ + Ptr bd = BinaryDescriptor::createBinaryDescriptor(); + + /* compute lines and descriptors */ + for ( int i = 0; i < num_elements; i++ ) + { + /* get path to image */ + std::stringstream image_path; + image_path << pathToImages << images[i]; + + /* load image */ + Mat loadedImage = imread( image_path.str().c_str(), 1 ); + if( loadedImage.data == NULL ) + { + std::cout << "Could not load images." << std::endl; + help(); + exit( -1 ); + } /* compute lines and descriptors */ - for(int i = 0; i lines; + Mat computedDescr; + bd->detect( loadedImage, lines ); + bd->compute( loadedImage, lines, computedDescr ); + + descriptorsMat.push_back( computedDescr ); + linesMat.push_back( lines ); + + } + + /* compose a queries matrix */ + Mat queries; + for ( size_t j = 0; j < descriptorsMat.size(); j++ ) + { + if( descriptorsMat[j].rows >= 5 ) + queries.push_back( descriptorsMat[j].rowRange( 0, 5 ) ); + + else if( descriptorsMat[j].rows > 0 && descriptorsMat[j].rows < 5 ) + queries.push_back( descriptorsMat[j] ); + } + + std::cout << "It has been generated a matrix of " << queries.rows << " descriptors" << std::endl; + + /* create a BinaryDescriptorMatcher object */ + Ptr bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher(); + + /* populate matcher */ + bdm->add( descriptorsMat ); + + /* compute matches */ + std::vector > matches; + bdm->radiusMatch( queries, matches, 30 ); + + /* print matches */ + for ( size_t q = 0; q < matches.size(); q++ ) + { + for ( size_t m = 0; m < matches[q].size(); m++ ) { - /* get path to image */ - std::stringstream image_path; - image_path << pathToImages << images[i]; - - /* load image */ - Mat loadedImage = imread(image_path.str().c_str(), 1); - if(loadedImage.data == NULL) - { - std::cout << "Could not load images." << std::endl; - help(); - exit(-1); - } - - /* compute lines and descriptors */ - std::vector lines; - Mat computedDescr; - bd->detect(loadedImage, lines); - bd->compute(loadedImage, lines, computedDescr); - - descriptorsMat.push_back(computedDescr); - linesMat.push_back(lines); - - } - - /* compose a queries matrix */ - Mat queries; - for(size_t j = 0; j= 5) - queries.push_back(descriptorsMat[j].rowRange(0, 5)); - - else if(descriptorsMat[j].rows >0 && descriptorsMat[j].rows<5) - queries.push_back(descriptorsMat[j]); - } - - std::cout << "It has been generated a matrix of " << queries.rows - << " descriptors" << std::endl; - - /* create a BinaryDescriptorMatcher object */ - Ptr bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher(); - - /* populate matcher */ - bdm->add(descriptorsMat); - - /* compute matches */ - std::vector > matches; - bdm->radiusMatch(queries, matches, 30); - - /* print matches */ - for(size_t q = 0; q BinaryDescriptor::createBinaryDescriptor() -{ - return Ptr(new BinaryDescriptor()); -} - -Ptr BinaryDescriptor::createBinaryDescriptor(Params parameters) -{ - return Ptr(new BinaryDescriptor(parameters)); -} - - -/* construct a BinaryDescrptor object and compute external private parameters */ -BinaryDescriptor::BinaryDescriptor(const BinaryDescriptor::Params ¶meters) : params(parameters) -{ - - /* prepare a vector to host local weights F_l*/ - gaussCoefL_.resize(params.widthOfBand_*3); - - /* compute center of central band (every computation involves 2-3 bands) */ - double u = (params.widthOfBand_*3-1)/2; - - /* compute exponential part of F_l */ - double sigma = (params.widthOfBand_*2+1)/2;// (widthOfBand_*2+1)/2; - double invsigma2 = -1/(2*sigma*sigma); - - /* compute all local weights */ - double dis; - for(int i=0; i& keylines, - OutputArray descriptors, - bool useProvidedKeyLines) const -{ - - /* create some matrix objects */ - cv::Mat imageMat, maskMat, descrMat; - - /* store reference to input matrices */ - imageMat = image.getMat(); - maskMat = mask.getMat(); - - /* initialize output matrix */ - descriptors.create(Size(32, keylines.size()), CV_8UC1); - - /* store reference to output matrix */ - descrMat = descriptors.getMat(); - - /* require drawing KeyLines detection if demanded */ - if(!useProvidedKeyLines) - detectImpl(imageMat, keylines, maskMat); - - /* compute descriptors */ - computeImpl(imageMat, keylines, descrMat); -} - -BinaryDescriptor::~BinaryDescriptor(){} - - -/* read parameters from a FileNode object and store them (class function ) */ -void BinaryDescriptor::read( const cv::FileNode& fn ) -{ - params.read(fn); -} - -/* store parameters to a FileStorage object (class function) */ -void BinaryDescriptor::write( cv::FileStorage& fs ) const -{ - params.write(fs); -} - -/* return norm mode */ -int BinaryDescriptor::defaultNorm() const -{ - return NORM_HAMMING; -} - -/* return data type */ -int BinaryDescriptor::descriptorType() const -{ - return CV_8U; -} - -/*return descriptor size */ -int BinaryDescriptor::descriptorSize() const -{ - return 32*8; -} - -/* check whether Gaussian pyramids were created */ -bool BinaryDescriptor::empty() const -{ - return octaveImages.empty(); -} - -/* power function with error management */ -static inline int get2Pow(int i) { - if(i>=0 && i<=7) - return pow(2,i); - - else - { - CV_Assert(false); - return -1; - } -} - -/* utility function for conversion of an LBD descriptor to its binary representation */ -unsigned char BinaryDescriptor::binaryConversion(float* f1, float* f2) -{ - uchar result = 0; - for(int i = 0; i<8; i++) - { - if(f1[i]>f2[i]) - result+=get2Pow(i); - } - - return result; - -} - -/* get coefficients of line passing by two points in (line_extremes) */ -void BinaryDescriptor::getLineParameters(cv::Vec4i& line_extremes, cv::Vec3i& lineParams) -{ - int x1 = line_extremes[0]; - int x2 = line_extremes[2]; - int y1 = line_extremes[1]; - int y2 = line_extremes[3]; - - /* line is parallel to Y axis */ - if(x1 == x2) - { - lineParams[0] = 1; - lineParams[1] = 0; - lineParams[2] = x1 /* or x2 */; - } - - /* line is parallel to X axis */ - else if(y1 == y2) - { - lineParams[0] = 0; - lineParams[1] = 1; - lineParams[2] = y1 /* or y2 */; - } - - /* line is not parallel to any axis */ - else - { - lineParams[0] = y1-y2; - lineParams[1] = x2-x1; - lineParams[2] = -y1*(x2-x1) + x1*(y2-y1); - } -} - /* compute the angle between line and X axis */ -float BinaryDescriptor::getLineDirection(cv::Vec3i &lineParams) -{ - /* line is parallel to X axis */ - if(lineParams[0] == 0) - return 0; - - /* line is parallel to Y axis */ - else if(lineParams[1] == 0) - return M_PI/2; - - /* line is not parallel to any axis */ - else - return atan2(-lineParams[0], lineParams[1]); -} - - -/* compute Gaussian pyramid of input image */ -void BinaryDescriptor::computeGaussianPyramid(const Mat& image) -{ - /* clear class fields */ - images_sizes.clear(); - octaveImages.clear(); - extractedLines.clear(); - - /* insert input image into pyramid */ - cv::Mat currentMat = image.clone(); - cv::GaussianBlur(currentMat, currentMat, cv::Size(5, 5), 1); - octaveImages.push_back(currentMat); - images_sizes.push_back(currentMat.size()); - - /* fill Gaussian pyramid */ - for(int pyrCounter = 1; pyrCounter& keylines, - const Mat& mask ) -{ - if(mask.data!=NULL && (mask.size() != image.size() || mask.type()!=CV_8UC1)) - { - - std::cout << "Mask error while detecting lines: " - << "please check its dimensions and that data type is CV_8UC1" - << std::endl; - - CV_Assert(false); - } - - else - detectImpl(image, keylines, mask); -} - - -/* requires line detection (more than one image) */ -void BinaryDescriptor::detect( const std::vector& images, - std::vector >& keylines, - const std::vector& masks ) const -{ - /* detect lines from each image */ - for(size_t counter = 0; counter& keylines, - const Mat& mask ) const -{ - - cv::Mat image; - cvtColor(imageSrc, image, COLOR_BGR2GRAY); - /*check whether image depth is different from 0 */ - if(image.depth() != 0) - { - std::cout << "Warning, depth image!= 0" << std::endl; - CV_Assert(false); - } - - /* create a pointer to self */ - BinaryDescriptor *bn = const_cast(this); - - /* compute Gaussian pyramid */ - bn->computeGaussianPyramid(image); - - /* detect and arrange lines across octaves */ - ScaleLines sl; - bn->OctaveKeyLines(sl); - - /* fill KeyLines vector */ - for(int i = 0; i<(int)sl.size(); i++) - { - for(size_t j = 0; j(kl.startPointY, kl.startPointX) == 0 && - mask.at(kl.endPointY, kl.endPointX) == 0) - keylines.erase(keylines.begin() + keyCounter); - } - } - -} - - - -/* requires descriptors computation (only one image) */ -void BinaryDescriptor::compute( const Mat& image, - CV_OUT CV_IN_OUT std::vector& keylines, - CV_OUT Mat& descriptors ) const -{ - computeImpl(image, keylines, descriptors); -} - - -/* requires descriptors computation (more than one image) */ -void BinaryDescriptor::compute( const std::vector& images, - std::vector >& keylines, - std::vector& descriptors ) const -{ - for(size_t i = 0; i& keylines, - Mat& descriptors ) const -{ - /* convert input image to gray scale */ - cv::Mat image; - cvtColor(imageSrc, image, COLOR_BGR2GRAY); - - /*check whether image's depth is different from 0 */ - if(image.depth() != 0) - { - std::cout << "Error, depth of image != 0" << std::endl; - CV_Assert(false); - } - - - /* keypoints list can't be empty */ - if(keylines.size() == 0) - { - std::cout << "Error: keypoint list is empty" << std::endl; - return; - } - - /* get maximum class_id */ - int numLines = 0; - for(size_t l = 0; l numLines) - numLines = keylines[l].class_id; - } - - /* create a ScaleLines object */ - OctaveSingleLine fictiousOSL; - fictiousOSL.octaveCount = -1; - LinesVec lv(params.numOfOctave_, fictiousOSL); - ScaleLines sl(numLines+1, lv); - - /* create a map to record association between KeyLines and their position - in ScaleLines vector */ - std::map, int> correspondences; - - /* fill ScaleLines object */ - for(size_t slCounter = 0; slCounter, int>(std::pair(id, oct), - slCounter)); - } - - /* delete useless OctaveSingleLines */ - for(size_t i = 0; i(this); - /* all structures cleared in computeGaussianPyramid */ - bn->computeGaussianPyramid(image); - - /* compute Sobel's derivatives */ - bn->dxImg_vector.clear(); - bn->dyImg_vector.clear(); - - bn->dxImg_vector.resize(params.numOfOctave_); - bn->dyImg_vector.resize(params.numOfOctave_); - - for(size_t sobelCnt = 0; sobelCntdxImg_vector[sobelCnt].create(images_sizes[sobelCnt].height, images_sizes[sobelCnt].width, CV_16SC1); - bn->dyImg_vector[sobelCnt].create(images_sizes[sobelCnt].height, images_sizes[sobelCnt].width, CV_16SC1); - - cv::Sobel( octaveImages[sobelCnt], bn->dxImg_vector[sobelCnt], CV_16SC1, 1, 0, 3); - cv::Sobel( octaveImages[sobelCnt], bn->dyImg_vector[sobelCnt], CV_16SC1, 0, 1, 3); - } - - /* compute LBD descriptors */ - bn->computeLBD(sl); - - /* resize output matrix */ - descriptors = cv::Mat(keylines.size(), 32, CV_8UC1); - - /* fill output matrix with descriptors */ - for(size_t k = 0; k(k, lineOctave))->second; - - /* get a pointer to correspondent row in output matrix */ - uchar* pointerToRow = descriptors.ptr(originalIndex); - - /* get LBD data */ - float* desVec = sl[k][lineC].descriptor.data(); - - /* fill current row with binary descriptor */ - for(int comb = 0; comb<32; comb++) - { - *pointerToRow = bn->binaryConversion(&desVec[8*combinations[comb][0]], - &desVec[8*combinations[comb][1]]); - - pointerToRow++; - } - - } - } - -} - - -/* gather lines in groups. Each group contains the same line, detected in different octaves */ -int BinaryDescriptor::OctaveKeyLines(ScaleLines &keyLines) -{ - - /* final number of extracted lines */ - unsigned int numOfFinalLine = 0; - - for(size_t scaleCounter = 0; scaleCounter ls = cv::createLineSegmentDetector(cv::LSD_REFINE_ADV); - - /* prepare a vector to host extracted segments */ - std::vector lines_std; - - /* use detector to extract segments */ - ls->detect(currentScaledImage, lines_std); - - /* store lines extracted from current image */ - extractedLines.push_back(lines_std); - - /* update lines counter */ - numOfFinalLine += lines_std.size(); - - - } - - /* prepare a vector to store octave information associated to extracted lines */ - std::vector octaveLines(numOfFinalLine); - - /* set lines' counter to 0 for reuse */ - numOfFinalLine = 0; - - /* counter to give a unique ID to lines in LineVecs */ - unsigned int lineIDInScaleLineVec = 0; - - /* floats to compute lines' lengths */ - float dx, dy; - - /* loop over lines extracted from scale 0 (original image) */ - for(unsigned int lineCurId=0; lineCurId1) - { - /* some other variables' declarations */ - float twoPI = 2*M_PI; - unsigned int closeLineID; - float endPointDis,minEndPointDis,minLocalDis,maxLocalDis; - float lp0,lp1, lp2, lp3, np0,np1, np2, np3; - - /* loop over list of octaves */ - for(unsigned int octaveCount = 1; octaveCount<(unsigned int)params.numOfOctave_; octaveCount++) - { - /*for each line in current octave image, find their corresponding lines - in the octaveLines, - give them the same value of lineIDInScaleLineVec*/ - - /* loop over list of lines extracted from current octave */ - for(unsigned int lineCurId=0;lineCurId6)?(tempValue):6; - nearThreshold = (nearThreshold<12)?nearThreshold:12; - - /* compute scaled lenght of current line */ - dx = fabs((extractedLines[octaveCount][lineCurId])[0]-(extractedLines[octaveCount][lineCurId][2]));//x1-x2 - dy = fabs((extractedLines[octaveCount][lineCurId])[1]-(extractedLines[octaveCount][lineCurId][3]));//y1-y2 - length = scale[octaveCount] * sqrt(dx*dx+dy*dy); - - minEndPointDis = 12; - /* loop over the octave representations of all lines */ - for(unsigned int lineNextId=0; lineNextId0.1745 && (twoPI - direction>0.1745)) - continue; - - /*now check whether current line and next line are near to each other. - Get known term from equation to be compared */ - rho2 = scale[octaveID] * fabs(line_equation_to_compare[2]); - - /* compute difference between known terms */ - near = fabs(rho1 - rho2); - - /* two lines are not close in the image */ - if(near>nearThreshold) - continue; - - /* get the extreme points of the two lines */ - lp0 = scale[octaveCount] * (extractedLines[octaveCount][lineCurId])[0]; - lp1 = scale[octaveCount] * (extractedLines[octaveCount][lineCurId])[1]; - lp2 = scale[octaveCount] * (extractedLines[octaveCount][lineCurId])[2]; - lp3 = scale[octaveCount] * (extractedLines[octaveCount][lineCurId])[3]; - np0 = scale[octaveID] * (extractedLines[octaveID][lineIDInOctave])[0]; - np1 = scale[octaveID] * (extractedLines[octaveID][lineIDInOctave])[1]; - np2 = scale[octaveID] * (extractedLines[octaveID][lineIDInOctave])[2]; - np3 = scale[octaveID] * (extractedLines[octaveID][lineIDInOctave])[3]; - - /* get the distance between the two leftmost extremes of lines - L1(0,1)<->L2(0,1) */ - dx = lp0 - np0; - dy = lp1 - np1; - endPointDis = sqrt(dx*dx + dy*dy); - - /* set momentaneously min and max distance between lines to - the one between left extremes */ - minLocalDis = endPointDis; - maxLocalDis = endPointDis; - - /* compute distance between right extremes - L1(2,3)<->L2(2,3) */ - dx = lp2 - np2; - dy = lp3 - np3; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - /* compute distance between left extreme of current line and - right extreme of line to be compared - L1(0,1)<->L2(2,3) */ - dx = lp0 - np2; - dy = lp1 - np3; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - /* compute distance between right extreme of current line and - left extreme of line to be compared - L1(2,3)<->L2(0,1) */ - dx = lp2 - np0; - dy = lp3 - np1; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - /* check whether conditions for considering line to be compared - wremoveInvalidPointsorth to be inserted in the same LineVec are satisfied */ - if((maxLocalDis<0.8*(length+octaveLines[lineNextId].lineLength)) - &&(minLocalDis=-0.75*M_PI&&direction<-0.25*M_PI) - { - if(dy>0) - shouldChange = true; - } - - if(direction>=-0.25*M_PI&&direction<0.25*M_PI) - if(dx<0){shouldChange = true;} - - if(direction>=0.25*M_PI&&direction<0.75*M_PI) - if(dy<0){shouldChange = true;} - - if((direction>=0.75*M_PI&&direction=-M_PI&&direction<-0.75*M_PI)){ - if(dx>0) - shouldChange = true; - } - - tempValue = scale[octaveID]; - - if(shouldChange) - { - singleLine.sPointInOctaveX = e1; - singleLine.sPointInOctaveY = e2; - singleLine.ePointInOctaveX = s1; - singleLine.ePointInOctaveY = s2; - singleLine.startPointX = tempValue * e1; - singleLine.startPointY = tempValue * e2; - singleLine.endPointX = tempValue * s1; - singleLine.endPointY = tempValue * s2; - } - - else - { - singleLine.sPointInOctaveX = s1; - singleLine.sPointInOctaveY = s2; - singleLine.ePointInOctaveX = e1; - singleLine.ePointInOctaveY = e2; - singleLine.startPointX = tempValue * s1; - singleLine.startPointY = tempValue * s2; - singleLine.endPointX = tempValue * e1; - singleLine.endPointY = tempValue * e2; - } - - singleLine.direction = atan2((singleLine.endPointY-singleLine.startPointY), - (singleLine.endPointX-singleLine.startPointX)); - - tempID = octaveLines[lineID].lineIDInScaleLineVec; - - /* compute number of pixels covered by line */ - LineIterator li(octaveImages[octaveID], - Point(singleLine.startPointX, singleLine.startPointY), - Point(singleLine.endPointX, singleLine.endPointY)); - - singleLine.numOfPixels = li.count; - - /* store line */ - keyLines[tempID].push_back(singleLine); - - } - - delete [] scale; - return 1; - -} - -/* compute LBD descriptors */ -int BinaryDescriptor::computeLBD(ScaleLines &keyLines) -{ - //the default length of the band is the line length. - short numOfFinalLine = keyLines.size(); - float *dL = new float[2];//line direction cos(dir), sin(dir) - float *dO = new float[2];//the clockwise orthogonal vector of line direction. - short heightOfLSP = params.widthOfBand_*NUM_OF_BANDS;//the height of line support region; - short descriptor_size = NUM_OF_BANDS * 8;//each band, we compute the m( pgdL, ngdL, pgdO, ngdO) and std( pgdL, ngdL, pgdO, ngdO); - float pgdLRowSum;//the summation of {g_dL |g_dL>0 } for each row of the region; - float ngdLRowSum;//the summation of {g_dL |g_dL<0 } for each row of the region; - float pgdL2RowSum;//the summation of {g_dL^2 |g_dL>0 } for each row of the region; - float ngdL2RowSum;//the summation of {g_dL^2 |g_dL<0 } for each row of the region; - float pgdORowSum;//the summation of {g_dO |g_dO>0 } for each row of the region; - float ngdORowSum;//the summation of {g_dO |g_dO<0 } for each row of the region; - float pgdO2RowSum;//the summation of {g_dO^2 |g_dO>0 } for each row of the region; - float ngdO2RowSum;//the summation of {g_dO^2 |g_dO<0 } for each row of the region; - - float *pgdLBandSum = new float[NUM_OF_BANDS];//the summation of {g_dL |g_dL>0 } for each band of the region; - float *ngdLBandSum = new float[NUM_OF_BANDS];//the summation of {g_dL |g_dL<0 } for each band of the region; - float *pgdL2BandSum = new float[NUM_OF_BANDS];//the summation of {g_dL^2 |g_dL>0 } for each band of the region; - float *ngdL2BandSum = new float[NUM_OF_BANDS];//the summation of {g_dL^2 |g_dL<0 } for each band of the region; - float *pgdOBandSum = new float[NUM_OF_BANDS];//the summation of {g_dO |g_dO>0 } for each band of the region; - float *ngdOBandSum = new float[NUM_OF_BANDS];//the summation of {g_dO |g_dO<0 } for each band of the region; - float *pgdO2BandSum = new float[NUM_OF_BANDS];//the summation of {g_dO^2 |g_dO>0 } for each band of the region; - float *ngdO2BandSum = new float[NUM_OF_BANDS];//the summation of {g_dO^2 |g_dO<0 } for each band of the region; - - short numOfBitsBand = NUM_OF_BANDS*sizeof(float); - short lengthOfLSP; //the length of line support region, varies with lines - short halfHeight = (heightOfLSP-1)/2; - short halfWidth; - short bandID; - float coefInGaussion; - float lineMiddlePointX, lineMiddlePointY; - float sCorX, sCorY,sCorX0, sCorY0; - short tempCor, xCor, yCor;//pixel coordinates in image plane - short dx, dy; - float gDL;//store the gradient projection of pixels in support region along dL vector - float gDO;//store the gradient projection of pixels in support region along dO vector - short imageWidth, imageHeight, realWidth; - short *pdxImg, *pdyImg; - float *desVec; - - short sameLineSize; - short octaveCount; - OctaveSingleLine *pSingleLine; - /* loop over list of LineVec */ - for(short lineIDInScaleVec = 0; lineIDInScaleVecoctaveCount; - - /* retrieve associated dxImg and dyImg - pdxImg = edLineVec_[octaveCount]->dxImg_.ptr(); - pdyImg = edLineVec_[octaveCount]->dyImg_.ptr(); */ - pdxImg = dxImg_vector[octaveCount].ptr(); - pdyImg = dyImg_vector[octaveCount].ptr(); - - /* get image size to work on from real one - realWidth = edLineVec_[octaveCount]->imageWidth; - imageWidth = realWidth -1; - imageHeight = edLineVec_[octaveCount]->imageHeight-1; */ - realWidth = images_sizes[octaveCount].width; - imageWidth = realWidth - 1; - imageHeight = images_sizes[octaveCount].height - 1; - - - /* initialize memory areas */ - memset(pgdLBandSum, 0, numOfBitsBand); - memset(ngdLBandSum, 0, numOfBitsBand); - memset(pgdL2BandSum, 0, numOfBitsBand); - memset(ngdL2BandSum, 0, numOfBitsBand); - memset(pgdOBandSum, 0, numOfBitsBand); - memset(ngdOBandSum, 0, numOfBitsBand); - memset(pgdO2BandSum, 0, numOfBitsBand); - memset(ngdO2BandSum, 0, numOfBitsBand); - - /* get length of line and its half */ - lengthOfLSP = keyLines[lineIDInScaleVec][lineIDInSameLine].numOfPixels; - halfWidth = (lengthOfLSP-1)/2; - - /* get middlepoint of line */ - lineMiddlePointX = 0.5 * (pSingleLine->sPointInOctaveX + pSingleLine->ePointInOctaveX); - lineMiddlePointY = 0.5 * (pSingleLine->sPointInOctaveY + pSingleLine->ePointInOctaveY); - - /*1.rotate the local coordinate system to the line direction (direction is the angle - between positive line direction and positive X axis) - *2.compute the gradient projection of pixels in line support region*/ - - /* get the vector representing original image reference system after rotation to aligh with - line's direction */ - dL[0] = cos(pSingleLine->direction); - dL[1] = sin(pSingleLine->direction); - - /* set the clockwise orthogonal vector of line direction */ - dO[0] = -dL[1]; - dO[1] = dL[0]; - - /* get rotated reference frame */ - sCorX0= -dL[0]*halfWidth + dL[1]*halfHeight + lineMiddlePointX;//hID =0; wID = 0; - sCorY0= -dL[1]*halfWidth - dL[0]*halfHeight + lineMiddlePointY; - - - /* BIAS::Matrix gDLMat(heightOfLSP,lengthOfLSP) */ - for(short hID = 0; hID imageWidth)?imageWidth:tempCor; - tempCor = round(sCorY); - yCor = (tempCor<0)?0:(tempCor>imageHeight)?imageHeight:tempCor; - - /* To achieve rotation invariance, each simple gradient is rotated aligned with - * the line direction and clockwise orthogonal direction.*/ - dx = pdxImg[yCor*realWidth+xCor]; - dy = pdyImg[yCor*realWidth+xCor]; - gDL = dx * dL[0] + dy * dL[1]; - gDO = dx * dO[0] + dy * dO[1]; - if(gDL>0) - { - pgdLRowSum += gDL; - } - - else - { - ngdLRowSum -= gDL; - } - - if(gDO>0) - { - pgdORowSum += gDO; - } - - else - { - ngdORowSum -= gDO; - } - - sCorX +=dL[0]; - sCorY +=dL[1]; - /* gDLMat[hID][wID] = gDL; */ - } - sCorX0 -=dL[1]; - sCorY0 +=dL[0]; - coefInGaussion = gaussCoefG_[hID]; - pgdLRowSum = coefInGaussion * pgdLRowSum; - ngdLRowSum = coefInGaussion * ngdLRowSum; - pgdL2RowSum = pgdLRowSum * pgdLRowSum; - ngdL2RowSum = ngdLRowSum * ngdLRowSum; - pgdORowSum = coefInGaussion * pgdORowSum; - ngdORowSum = coefInGaussion * ngdORowSum; - pgdO2RowSum = pgdORowSum * pgdORowSum; - ngdO2RowSum = ngdORowSum * ngdORowSum; - - /* compute {g_dL |g_dL>0 }, {g_dL |g_dL<0 }, - {g_dO |g_dO>0 }, {g_dO |g_dO<0 } of each band in the line support region - first, current row belongs to current band */ - bandID = hID/params.widthOfBand_; - coefInGaussion = gaussCoefL_[hID%params.widthOfBand_+params.widthOfBand_]; - pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; - ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; - pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; - ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; - pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; - ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; - pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; - ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; - - /* In order to reduce boundary effect along the line gradient direction, - * a row's gradient will contribute not only to its current band, but also - * to its nearest upper and down band with gaussCoefL_.*/ - bandID--; - if(bandID>=0){/* the band above the current band */ - coefInGaussion = gaussCoefL_[hID%params.widthOfBand_ + 2*params.widthOfBand_]; - pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; - ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; - pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; - ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; - pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; - ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; - pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; - ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; - } - - bandID = bandID+2; - if(bandIDdescriptor.resize(descriptor_size); - desVec = pSingleLine->descriptor.data(); - - short desID; - - /*Note that the first and last bands only have (lengthOfLSP * widthOfBand_ * 2.0) pixels - * which are counted. */ - float invN2 = 1.0/(params.widthOfBand_ * 2.0); - float invN3 = 1.0/(params.widthOfBand_ * 3.0); - float invN, temp; - for(bandID = 0; bandIDdescriptor.data(); - - int base = 0; - for(short i=0; idescriptor.data(); - base = 0; - for(short i=0; idescriptor.data(); - for(short i=0; i0.4){ - desVec[i]=0.4; - } - } - - //re-normalize desVec; - temp = 0; - for(short i=0; i(2,2); - ATV = cv::Mat_(1,2); - tempMatLineFit = cv::Mat_(2,2); - tempVecLineFit = cv::Mat_(1,2); - fitMatT = cv::Mat_(2,minLineLen_); - fitVec = cv::Mat_(1,minLineLen_); - for(int i=0; idata.ptr, pImage, pixelNum*sizeof(unsigned char)); -// } - - unsigned int edgePixelArraySize = pixelNum/5; - unsigned int maxNumOfEdge = edgePixelArraySize/20; - //compute dx, dy images - if(gImg_.cols!= imageWidth||gImg_.rows!= imageHeight){ - if(pFirstPartEdgeX_!= NULL){ - delete [] pFirstPartEdgeX_; - delete [] pFirstPartEdgeY_; - delete [] pSecondPartEdgeX_; - delete [] pSecondPartEdgeY_; - delete [] pFirstPartEdgeS_; - delete [] pSecondPartEdgeS_; - delete [] pAnchorX_; - delete [] pAnchorY_; - } - dxImg_.create(imageHeight, imageWidth, CV_16SC1); - dyImg_.create(imageHeight, imageWidth, CV_16SC1 ); - gImgWO_.create(imageHeight, imageWidth, CV_16SC1 ); - gImg_.create(imageHeight, imageWidth, CV_16SC1 ); - dirImg_.create(imageHeight, imageWidth, CV_8UC1 ); - edgeImage_.create(imageHeight, imageWidth, CV_8UC1 ); - pFirstPartEdgeX_ = new unsigned int[edgePixelArraySize]; - pFirstPartEdgeY_ = new unsigned int[edgePixelArraySize]; - pSecondPartEdgeX_ = new unsigned int[edgePixelArraySize]; - pSecondPartEdgeY_ = new unsigned int[edgePixelArraySize]; - pFirstPartEdgeS_ = new unsigned int[maxNumOfEdge]; - pSecondPartEdgeS_ = new unsigned int[maxNumOfEdge]; - pAnchorX_ = new unsigned int[edgePixelArraySize]; - pAnchorY_ = new unsigned int[edgePixelArraySize]; - } - cv::Sobel( image, dxImg_, CV_16SC1, 1, 0, 3); - cv::Sobel( image, dyImg_, CV_16SC1, 0, 1, 3); - - - #ifdef DEBUGEdgeDrawing - cv::imshow("dxImg_", dxImg_); - cv::imshow("dyImg_", dyImg_); - cv::waitKey(); - #endif - - //compute gradient and direction images - -// double t = (double)cv::getTickCount(); - cv::Mat dxABS_m = cv::abs(dxImg_); - cv::Mat dyABS_m = cv::abs(dyImg_); - cv::Mat sumDxDy; - cv::add(dyABS_m, dxABS_m, sumDxDy); - - - cv::threshold(sumDxDy,gImg_, gradienThreshold_+1, 255, cv::THRESH_TOZERO); - gImg_ = gImg_/4; - gImgWO_ = sumDxDy/4; - cv::compare(dxABS_m, dyABS_m, dirImg_, cv::CMP_LT); - -// t = ((double)cv::getTickCount() - t)/cv::getTickFrequency(); -// std::cout<<"FOR ABS: "<(); - short *pdyImg = dyImg_.ptr(); - short *pgImg = gImg_.ptr(); - unsigned char *pdirImg = dirImg_.ptr(); - - //extract the anchors in the gradient image, store into a vector - memset(pAnchorX_, 0, edgePixelArraySize*sizeof(unsigned int));//initialization - memset(pAnchorY_, 0, edgePixelArraySize*sizeof(unsigned int)); - unsigned int anchorsSize = 0; - int indexInArray; - unsigned char gValue1, gValue2, gValue3; - for(unsigned int w=1; w=pgImg[indexInArray-imageWidth]+anchorThreshold_ - &&pgImg[indexInArray]>=pgImg[indexInArray+imageWidth]+anchorThreshold_){// (w,h) is accepted as an anchor - pAnchorX_[anchorsSize] = w; - pAnchorY_[anchorsSize++] = h; - } - }else{// if(pdirImg[indexInArray]==Vertical){//it is vertical edge, should be compared with left and right - //gValue2 = pgImg[indexInArray]; - if(pgImg[indexInArray]>=pgImg[indexInArray-1]+anchorThreshold_ - &&pgImg[indexInArray]>=pgImg[indexInArray+1]+anchorThreshold_){// (w,h) is accepted as an anchor - pAnchorX_[anchorsSize] = w; - pAnchorY_[anchorsSize++] = h; - } - } - } - } - if(anchorsSize>edgePixelArraySize){ - cout<<"anchor size is larger than its maximal size. anchorsSize="< lineEquation; - lineEquations_.clear(); - lineEndpoints_.clear(); - lineDirection_.clear(); - unsigned char *pdirImg = dirImg_.data; - unsigned int numOfLines = 0; - unsigned int offsetInEdgeArrayS, offsetInEdgeArrayE, newOffsetS;//start index and end index - unsigned int offsetInLineArray=0; - float direction;//line direction - - for(unsigned int edgeID=0; edgeID offsetInEdgeArrayS+minLineLen_){//extract line segments from an edge, may find more than one segments - //find an initial line segment - while(offsetInEdgeArrayE > offsetInEdgeArrayS+minLineLen_){ - lineFitErr = LeastSquaresLineFit_(pEdgeXCors,pEdgeYCors, - offsetInEdgeArrayS,lineEquation); - if(lineFitErr<=lineFitErrThreshold_) break;//ok, an initial line segment detected - offsetInEdgeArrayS +=SkipEdgePoint; //skip the first two pixel in the chain and try with the remaining pixels - } - if(lineFitErr>lineFitErrThreshold_) break; //no line is detected - //An initial line segment is detected. Try to extend this line segment - pLineSID[numOfLines] = offsetInLineArray; - double coef1;//for a line ax+by+c=0, coef1 = 1/sqrt(a^2+b^2); - double pointToLineDis;//for a line ax+by+c=0 and a point(xi, yi), pointToLineDis = coef1*|a*xi+b*yi+c| - bool bExtended=true; - bool bFirstTry = true; - int numOfOutlier;//to against noise, we accept a few outlier of a line. - int tryTimes = 0; - if(pdirImg[pEdgeYCors[offsetInEdgeArrayS]*imageWidth + pEdgeXCors[offsetInEdgeArrayS]]==Horizontal){//y=ax+b, i.e. ax-y+b=0 - while(bExtended){ - tryTimes++; - if(bFirstTry){ - bFirstTry = false; - for(int i=0; i offsetInEdgeArrayS){ - pointToLineDis = fabs(lineEquation[0]*pEdgeXCors[offsetInEdgeArrayS] - - pEdgeYCors[offsetInEdgeArrayS] + lineEquation[1])*coef1; - pLineXCors[offsetInLineArray] = pEdgeXCors[offsetInEdgeArrayS]; - pLineYCors[offsetInLineArray++] = pEdgeYCors[offsetInEdgeArrayS++]; - if(pointToLineDis>lineFitErrThreshold_){ - numOfOutlier++; - if(numOfOutlier>3) break; - }else{//we count number of connective outliers. - numOfOutlier=0; - } - } - //pop back the last few outliers from lines and return them to edge chain - offsetInLineArray -=numOfOutlier; - offsetInEdgeArrayS -=numOfOutlier; - if(offsetInLineArray - newOffsetS>0&&tryTimes lineEqu = {lineEquation[0]*coef1, -1*coef1, lineEquation[1]*coef1}; - if(LineValidation_(pLineXCors,pLineYCors,pLineSID[numOfLines],offsetInLineArray,lineEqu,direction)){//check the line - //store the line equation coefficients - lineEquations_.push_back(lineEqu); - /*At last, compute the line endpoints and store them. - *we project the first and last pixels in the pixelChain onto the best fit line - *to get the line endpoints. - *xp= (w2^2*x0-w1*w2*y0-w3*w1)/(w1^2+w2^2) - *yp= (w1^2*y0-w1*w2*x0-w3*w2)/(w1^2+w2^2) */ - std::array lineEndP;//line endpoints - double a1 = lineEqu[1]*lineEqu[1]; - double a2 = lineEqu[0]*lineEqu[0]; - double a3 = lineEqu[0]*lineEqu[1]; - double a4 = lineEqu[2]*lineEqu[0]; - double a5 = lineEqu[2]*lineEqu[1]; - unsigned int Px = pLineXCors[pLineSID[numOfLines] ];//first pixel - unsigned int Py = pLineYCors[pLineSID[numOfLines] ]; - lineEndP[0] = a1*Px-a3*Py-a4;//x - lineEndP[1] = a2*Py-a3*Px-a5;//y - Px = pLineXCors[offsetInLineArray -1 ];//last pixel - Py = pLineYCors[offsetInLineArray -1 ]; - lineEndP[2] = a1*Px-a3*Py-a4;//x - lineEndP[3] = a2*Py-a3*Px-a5;//y - lineEndpoints_.push_back(lineEndP); - lineDirection_.push_back(direction); - numOfLines++; - }else{ - offsetInLineArray = pLineSID[numOfLines];// line was not accepted, the offset is set back - } - }else{//x=ay+b, i.e. x-ay-b=0 - while(bExtended){ - tryTimes++; - if(bFirstTry){ - bFirstTry = false; - for(int i=0; i offsetInEdgeArrayS){ - pointToLineDis = fabs(pEdgeXCors[offsetInEdgeArrayS] - - lineEquation[0]*pEdgeYCors[offsetInEdgeArrayS] - lineEquation[1])*coef1; - pLineXCors[offsetInLineArray] = pEdgeXCors[offsetInEdgeArrayS]; - pLineYCors[offsetInLineArray++] = pEdgeYCors[offsetInEdgeArrayS++]; - if(pointToLineDis>lineFitErrThreshold_){ - numOfOutlier++; - if(numOfOutlier>3) break; - }else{//we count number of connective outliers. - numOfOutlier=0; - } - } - //pop back the last few outliers from lines and return them to edge chain - offsetInLineArray -= numOfOutlier; - offsetInEdgeArrayS -= numOfOutlier; - if(offsetInLineArray - newOffsetS>0&&tryTimes lineEqu= {1*coef1,-lineEquation[0]*coef1, -lineEquation[1]*coef1}; - if(LineValidation_(pLineXCors,pLineYCors,pLineSID[numOfLines],offsetInLineArray,lineEqu,direction)){//check the line - //store the line equation coefficients - lineEquations_.push_back(lineEqu); - /*At last, compute the line endpoints and store them. - *we project the first and last pixels in the pixelChain onto the best fit line - *to get the line endpoints. - *xp= (w2^2*x0-w1*w2*y0-w3*w1)/(w1^2+w2^2) - *yp= (w1^2*y0-w1*w2*x0-w3*w2)/(w1^2+w2^2) */ - std::array lineEndP;//line endpoints - double a1 = lineEqu[1]*lineEqu[1]; - double a2 = lineEqu[0]*lineEqu[0]; - double a3 = lineEqu[0]*lineEqu[1]; - double a4 = lineEqu[2]*lineEqu[0]; - double a5 = lineEqu[2]*lineEqu[1]; - unsigned int Px = pLineXCors[pLineSID[numOfLines] ];//first pixel - unsigned int Py = pLineYCors[pLineSID[numOfLines] ]; - lineEndP[0] = a1*Px-a3*Py-a4;//x - lineEndP[1] = a2*Py-a3*Px-a5;//y - Px = pLineXCors[offsetInLineArray -1 ];//last pixel - Py = pLineYCors[offsetInLineArray -1 ]; - lineEndP[2] = a1*Px-a3*Py-a4;//x - lineEndP[3] = a2*Py-a3*Px-a5;//y - lineEndpoints_.push_back(lineEndP); - lineDirection_.push_back(direction); - numOfLines++; - }else{ - offsetInLineArray = pLineSID[numOfLines];// line was not accepted, the offset is set back - } - } - //Extract line segments from the remaining pixel; Current chain has been shortened already. - } - }//end for(unsigned int edgeID=0; edgeIDx,iter->y); -// // char buf[10]; -// // sprintf( buf, "%d ", i); -// // cvPutText(cvColorImg,buf,point,&font,CV_RGB(r,g,b)); -// } -// cvNamedWindow("LineColorImage", CV_WINDOW_AUTOSIZE); -// cvShowImage("LineColorImage", cvColorImg); -// cvWaitKey(0); -// cvReleaseImage(&cvColorImg); -#endif - return 1; -} - - -double EDLineDetector::LeastSquaresLineFit_( unsigned int *xCors, unsigned int *yCors, - unsigned int offsetS, std::array &lineEquation) -{ - if(lineEquation.size()!=2){ - std::cout<<"SHOULD NOT BE != 2"<();//fitMatT = [x0, x1, ... xn; 1,1,...,1]; - for(int i=0; i(); - coef = 1.0/(double(pATA[0])*double(pATA[3]) - double(pATA[1])*double(pATA[2])); - // lineEquation = svd.Invert(ATA) * matT * vec; - lineEquation[0] = coef *( double(pATA[3])*double(ATV[0][0])-double(pATA[1])*double(ATV[0][1])); - lineEquation[1] = coef *( double(pATA[0])*double(ATV[0][1])-double(pATA[2])*double(ATV[0][0])); - /*compute line fit error */ - for(int i=0; i();//fitMatT = [y0, y1, ... yn; 1,1,...,1]; - for(int i=0; i(); - coef = 1.0/(double(pATA[0])*double(pATA[3]) - double(pATA[1])*double(pATA[2])); - // lineEquation = svd.Invert(ATA) * matT * vec; - lineEquation[0] = coef *( double(pATA[3])*double(ATV[0][0])-double(pATA[1])*double(ATV[0][1])); - lineEquation[1] = coef *( double(pATA[0])*double(ATV[0][1])-double(pATA[2])*double(ATV[0][0])); - /*compute line fit error */ - for(int i=0; i &lineEquation) -{ - int length = offsetE - offsetS; - int newLength = offsetE - newOffsetS; - if(length<=0||newLength<=0){ - cout<<"EDLineDetector::LeastSquaresLineFit_ Error:" - " the expected line index is wrong...offsetE = " - < matT(2,newLength); - cv::Mat_ vec(newLength,1); - float * pMatT; - float * pATA; - // double fitError = 0; - double coef; - unsigned char *pdirImg = dirImg_.data; - /*If the first pixel in this chain is horizontal, - *then we try to find a horizontal line, y=ax+b;*/ - if(pdirImg[yCors[offsetS]*imageWidth + xCors[offsetS] ]==Horizontal){ - /*Build the new system,and solve it using least square regression: mat * [a,b]^T = vec - * [x0',1] [y0'] - * [x1',1] [a] [y1'] - * . [b] = . - * [xn',1] [yn']*/ - pMatT = matT.ptr();//matT = [x0', x1', ... xn'; 1,1,...,1] - for(int i=0; i(); - coef = 1.0/(double(pATA[0])*double(pATA[3]) - double(pATA[1])*double(pATA[2])); - lineEquation[0] = coef *( double(pATA[3])*double(ATV[0][0])-double(pATA[1])*double(ATV[0][1])); - lineEquation[1] = coef *( double(pATA[0])*double(ATV[0][1])-double(pATA[2])*double(ATV[0][0])); - /*compute line fit error */ - // for(int i=0; i();//matT = [y0', y1', ... yn'; 1,1,...,1] - for(int i=0; i(); - coef = 1.0/(double(pATA[0])*double(pATA[3]) - double(pATA[1])*double(pATA[2])); - lineEquation[0] = coef *( double(pATA[3])*double(ATV[0][0])-double(pATA[1])*double(ATV[0][1])); - lineEquation[1] = coef *( double(pATA[0])*double(ATV[0][1])-double(pATA[2])*double(ATV[0][0])); - /*compute line fit error */ - // for(int i=0; i &lineEquation, float &direction) -{ - if(bValidate_){ - int n = offsetE - offsetS; - /*first compute the direction of line, make sure that the dark side always be the - *left side of a line.*/ - int meanGradientX=0, meanGradientY=0; - short *pdxImg = dxImg_.ptr(); - short *pdyImg = dyImg_.ptr(); - double dx, dy; - std::vector pointDirection; - int index; - for(int i=0; i0&&meanGradientY>=0){//first quadrant, and positive direction of X axis. - direction = atan2(-dy,dx);//line direction is in fourth quadrant - } - if(meanGradientX<=0&&meanGradientY>0){//second quadrant, and positive direction of Y axis. - direction = atan2(dy,dx);//line direction is in first quadrant - } - if(meanGradientX<0&&meanGradientY<=0){//third quadrant, and negative direction of X axis. - direction = atan2(dy,-dx);//line direction is in second quadrant - } - if(meanGradientX>=0&&meanGradientY<0){//fourth quadrant, and negative direction of Y axis. - direction = atan2(-dy,-dx);//line direction is in third quadrant - } - /*then check whether the line is on the border of the image. We don't keep the border line.*/ - if(fabs(direction)<0.15||M_PI-fabs(direction)<0.15){//Horizontal line - if(fabs(lineEquation[2])<10||fabs(imageHeight - fabs(lineEquation[2]))<10){//upper border or lower border - return false; - } - } - if(fabs(fabs(direction)-M_PI*0.5)<0.15){//Vertical line - if(fabs(lineEquation[2])<10||fabs(imageWidth - fabs(lineEquation[2]))<10){//left border or right border - return false; - } - } - //count the aligned points on the line which have the same direction as the line. - double disDirection; - int k = 0; - for(int i=0; i0); //0 corresponds to 1 mean false alarm - }else{ - return true; - } -} - -int EDLineDetector::EDline(cv::Mat &image, bool smoothed) -{ - if((EDline(image, lines_, smoothed)) != true){ - return -1; - } - lineSalience_.clear(); - lineSalience_.resize(lines_.numOfLines); - unsigned char *pgImg = gImgWO_.ptr(); - unsigned int indexInLineArray; - unsigned int *pXCor = lines_.xCors.data(); - unsigned int *pYCor = lines_.yCors.data(); - unsigned int *pSID = lines_.sId.data(); - for(unsigned int i=0; iEDline(blur,true))!= true){ - return -1; - } - - /* update number of total extracted lines */ - numOfFinalLine += edLineVec_[octaveCount]->lines_.numOfLines; - - /* resize image for next level of pyramid */ - cv::resize(blur, image, cv::Size(), (1.f/factor), (1.f/factor)); - - /* update sigma values */ - preSigma2 = curSigma2; - curSigma2 = curSigma2*2; - - } /* end of loop over number of octaves */ - - - /*lines which correspond to the same line in the octave images will be stored - in the same element of ScaleLines.*/ - - /* prepare a vector to store octave information associated to extracted lines */ - std::vector octaveLines(numOfFinalLine); - - /* set lines' counter to 0 for reuse */ - numOfFinalLine = 0; - - /* counter to give a unique ID to lines in LineVecs */ - unsigned int lineIDInScaleLineVec = 0; - - /* floats to compute lines' lengths */ - float dx, dy; - - /* loop over lines extracted from scale 0 (original image) */ - for(unsigned int lineCurId=0;lineCurIdlines_.numOfLines;lineCurId++){ - /* FOR CURRENT LINE: */ - - /* set octave from which it was extracted */ - octaveLines[numOfFinalLine].octaveCount = 0; - /* set ID within its octave */ - octaveLines[numOfFinalLine].lineIDInOctave = lineCurId; - /* set a unique ID among all lines extracted in all octaves */ - octaveLines[numOfFinalLine].lineIDInScaleLineVec = lineIDInScaleLineVec; - - /* compute absolute value of difference between X coordinates of line's extreme points */ - dx = fabs(edLineVec_[0]->lineEndpoints_[lineCurId][0]-edLineVec_[0]->lineEndpoints_[lineCurId][2]); - /* compute absolute value of difference between Y coordinates of line's extreme points */ - dy = fabs(edLineVec_[0]->lineEndpoints_[lineCurId][1]-edLineVec_[0]->lineEndpoints_[lineCurId][3]); - /* compute line's length */ - octaveLines[numOfFinalLine].lineLength = sqrt(dx*dx+dy*dy); - - /* update counters */ - numOfFinalLine++; - lineIDInScaleLineVec++; - } - - /* create and fill an array to store scale factors */ - float *scale = new float[numOfOctave_]; - scale[0] = 1; - for(unsigned int octaveCount = 1; octaveCount1){ - /* some other variables' declarations */ - float twoPI = 2*M_PI; - unsigned int closeLineID; - float endPointDis,minEndPointDis,minLocalDis,maxLocalDis; - float lp0,lp1, lp2, lp3, np0,np1, np2, np3; - - /* loop over list of octaves */ - for(unsigned int octaveCount = 1; octaveCountlines_.numOfLines;lineCurId++){ - /* get (scaled) known term from equation of current line */ - rho1 = scale[octaveCount] * fabs(edLineVec_[octaveCount]->lineEquations_[lineCurId][2]); - - /*nearThreshold depends on the distance of the image coordinate origin to current line. - *so nearThreshold = rho1 * nearThresholdRatio, where nearThresholdRatio = 1-cos(10*pi/180) = 0.0152*/ - tempValue = rho1 * 0.0152; - float nearThreshold = (tempValue>6)?(tempValue):6; - nearThreshold = (nearThreshold<12)?nearThreshold:12; - - /* compute scaled lenght of current line */ - dx = fabs(edLineVec_[octaveCount]->lineEndpoints_[lineCurId][0]-edLineVec_[octaveCount]->lineEndpoints_[lineCurId][2]);//x1-x2 - dy = fabs(edLineVec_[octaveCount]->lineEndpoints_[lineCurId][1]-edLineVec_[octaveCount]->lineEndpoints_[lineCurId][3]);//y1-y2 - length = scale[octaveCount] * sqrt(dx*dx+dy*dy); - - minEndPointDis = 12; - /* loop over the octave representations of all lines */ - for(unsigned int lineNextId=0; lineNextIdlineDirection_[lineCurId] - - edLineVec_[octaveID]->lineDirection_[lineIDInOctave]); - - /* the angle between two lines are larger than 10degrees - (i.e. 10*pi/180=0.1745), they are not close to parallel */ - if(direction>0.1745 && (twoPI - direction>0.1745)){ - continue; - } - /*now check whether current line and next line are near to each other. - *If line1:a1*x+b1*y+c1=0 and line2:a2*x+b2*y+c2=0 are near in image, then - *rho1 = |a1*0+b1*0+c1|/sqrt(a1^2+b1^2) and rho2 = |a2*0+b2*0+c2|/sqrt(a2^2+b2^2) should close. - *In our case, rho1 = |c1| and rho2 = |c2|, because sqrt(a1^2+b1^2) = sqrt(a2^2+b2^2) = 1; - *note that, lines are in different octave images, so we define near = fabs(scale*rho1 - rho2) or - *where scale is the scale factor between to octave images*/ - - /* get known term from equation to be compared */ - rho2 = scale[octaveID] * fabs(edLineVec_[octaveID]->lineEquations_[lineIDInOctave][2]); - /* compute difference between known ters */ - near = fabs(rho1 - rho2); - - /* two lines are not close in the image */ - if(near>nearThreshold){ - continue; - } - - /*now check the end points distance between two lines, the scale of distance is in the original image size. - * find the minimal and maximal end points distance*/ - - /* get the extreme points of the two lines */ - lp0 = scale[octaveCount] *edLineVec_[octaveCount]->lineEndpoints_[lineCurId][0]; - lp1 = scale[octaveCount] *edLineVec_[octaveCount]->lineEndpoints_[lineCurId][1]; - lp2 = scale[octaveCount] *edLineVec_[octaveCount]->lineEndpoints_[lineCurId][2]; - lp3 = scale[octaveCount] *edLineVec_[octaveCount]->lineEndpoints_[lineCurId][3]; - np0 = scale[octaveID] * edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][0]; - np1 = scale[octaveID] * edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][1]; - np2 = scale[octaveID] * edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][2]; - np3 = scale[octaveID] * edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][3]; - - /* get the distance between the two leftmost extremes of lines - L1(0,1)<->L2(0,1) */ - dx = lp0 - np0; - dy = lp1 - np1; - endPointDis = sqrt(dx*dx + dy*dy); - - /* set momentaneously min and max distance between lines to - the one between left extremes */ - minLocalDis = endPointDis; - maxLocalDis = endPointDis; - - /* compute distance between right extremes - L1(2,3)<->L2(2,3) */ - dx = lp2 - np2; - dy = lp3 - np3; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - - /* compute distance between left extreme of current line and - right extreme of line to be compared - L1(0,1)<->L2(2,3) */ - dx = lp0 - np2; - dy = lp1 - np3; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - /* compute distance between right extreme of current line and - left extreme of line to be compared - L1(2,3)<->L2(0,1) */ - dx = lp2 - np0; - dy = lp3 - np1; - endPointDis = sqrt(dx*dx + dy*dy); - - /* update (if necessary) min and max distance between lines */ - minLocalDis = (endPointDismaxLocalDis)?endPointDis:maxLocalDis; - - /* check whether conditions for considering line to be compared - worth to be inserted in the same LineVec are satisfied */ - if((maxLocalDis<0.8*(length+octaveLines[lineNextId].lineLength)) - &&(minLocalDis1) - - //////////////////////////////////// - //Reorganize the detected lines into keyLines - keyLines.clear(); - keyLines.resize(lineIDInScaleLineVec); - unsigned int tempID; - float s1,e1,s2,e2; - bool shouldChange; - OctaveSingleLine singleLine; - for(unsigned int lineID = 0;lineID < numOfFinalLine; lineID++){ - lineIDInOctave = octaveLines[lineID].lineIDInOctave; - octaveID = octaveLines[lineID].octaveCount; - direction = edLineVec_[octaveID]->lineDirection_[lineIDInOctave]; - singleLine.octaveCount = octaveID; - singleLine.direction = direction; - singleLine.lineLength = octaveLines[lineID].lineLength; - singleLine.salience = edLineVec_[octaveID]->lineSalience_[lineIDInOctave]; - singleLine.numOfPixels = edLineVec_[octaveID]->lines_.sId[lineIDInOctave+1]- - edLineVec_[octaveID]->lines_.sId[lineIDInOctave]; - //decide the start point and end point - shouldChange = false; - s1 = edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][0];//sx - s2 = edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][1];//sy - e1 = edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][2];//ex - e2 = edLineVec_[octaveID]->lineEndpoints_[lineIDInOctave][3];//ey - dx = e1 - s1;//ex-sx - dy = e2 - s2;//ey-sy - if(direction>=-0.75*M_PI&&direction<-0.25*M_PI){ - if(dy>0){shouldChange = true;} - } - if(direction>=-0.25*M_PI&&direction<0.25*M_PI){ - if(dx<0){shouldChange = true;} - } - if(direction>=0.25*M_PI&&direction<0.75*M_PI){ - if(dy<0){shouldChange = true;} - } - if((direction>=0.75*M_PI&&direction=-M_PI&&direction<-0.75*M_PI)){ - if(dx>0){shouldChange = true;} - } - tempValue = scale[octaveID]; - if(shouldChange){ - singleLine.sPointInOctaveX = e1; - singleLine.sPointInOctaveY = e2; - singleLine.ePointInOctaveX = s1; - singleLine.ePointInOctaveY = s2; - singleLine.startPointX = tempValue * e1; - singleLine.startPointY = tempValue * e2; - singleLine.endPointX = tempValue * s1; - singleLine.endPointY = tempValue * s2; - }else{ - singleLine.sPointInOctaveX = s1; - singleLine.sPointInOctaveY = s2; - singleLine.ePointInOctaveX = e1; - singleLine.ePointInOctaveY = e2; - singleLine.startPointX = tempValue * s1; - singleLine.startPointY = tempValue * s2; - singleLine.endPointX = tempValue * e1; - singleLine.endPointY = tempValue * e2; - } - tempID = octaveLines[lineID].lineIDInScaleLineVec; - keyLines[tempID].push_back(singleLine); - } - - //////////////////////////////////// - - delete [] scale; - return 1; -} - -/*The definitions of line descriptor,mean values of {g_dL>0},{g_dL<0},{g_dO>0},{g_dO<0} of each row in band - *and std values of sum{g_dL>0},sum{g_dL<0},sum{g_dO>0},sum{g_dO<0} of each row in band. - * With overlap region. */ -int LineDescriptor::ComputeLBD_(ScaleLines &keyLines) -{ - //the default length of the band is the line length. - short numOfFinalLine = keyLines.size(); - float *dL = new float[2];//line direction cos(dir), sin(dir) - float *dO = new float[2];//the clockwise orthogonal vector of line direction. - short heightOfLSP = widthOfBand_*numOfBand_;//the height of line support region; - short descriptorSize = numOfBand_ * 8;//each band, we compute the m( pgdL, ngdL, pgdO, ngdO) and std( pgdL, ngdL, pgdO, ngdO); - float pgdLRowSum;//the summation of {g_dL |g_dL>0 } for each row of the region; - float ngdLRowSum;//the summation of {g_dL |g_dL<0 } for each row of the region; - float pgdL2RowSum;//the summation of {g_dL^2 |g_dL>0 } for each row of the region; - float ngdL2RowSum;//the summation of {g_dL^2 |g_dL<0 } for each row of the region; - float pgdORowSum;//the summation of {g_dO |g_dO>0 } for each row of the region; - float ngdORowSum;//the summation of {g_dO |g_dO<0 } for each row of the region; - float pgdO2RowSum;//the summation of {g_dO^2 |g_dO>0 } for each row of the region; - float ngdO2RowSum;//the summation of {g_dO^2 |g_dO<0 } for each row of the region; - - float *pgdLBandSum = new float[numOfBand_];//the summation of {g_dL |g_dL>0 } for each band of the region; - float *ngdLBandSum = new float[numOfBand_];//the summation of {g_dL |g_dL<0 } for each band of the region; - float *pgdL2BandSum = new float[numOfBand_];//the summation of {g_dL^2 |g_dL>0 } for each band of the region; - float *ngdL2BandSum = new float[numOfBand_];//the summation of {g_dL^2 |g_dL<0 } for each band of the region; - float *pgdOBandSum = new float[numOfBand_];//the summation of {g_dO |g_dO>0 } for each band of the region; - float *ngdOBandSum = new float[numOfBand_];//the summation of {g_dO |g_dO<0 } for each band of the region; - float *pgdO2BandSum = new float[numOfBand_];//the summation of {g_dO^2 |g_dO>0 } for each band of the region; - float *ngdO2BandSum = new float[numOfBand_];//the summation of {g_dO^2 |g_dO<0 } for each band of the region; - - short numOfBitsBand = numOfBand_*sizeof(float); - short lengthOfLSP; //the length of line support region, varies with lines - short halfHeight = (heightOfLSP-1)/2; - short halfWidth; - short bandID; - float coefInGaussion; - float lineMiddlePointX, lineMiddlePointY; - float sCorX, sCorY,sCorX0, sCorY0; - short tempCor, xCor, yCor;//pixel coordinates in image plane - short dx, dy; - float gDL;//store the gradient projection of pixels in support region along dL vector - float gDO;//store the gradient projection of pixels in support region along dO vector - short imageWidth, imageHeight, realWidth; - short *pdxImg, *pdyImg; - float *desVec; - - short sameLineSize; - short octaveCount; - OctaveSingleLine *pSingleLine; - /* loop over list of LineVec */ - for(short lineIDInScaleVec = 0; lineIDInScaleVecoctaveCount; - - /* retrieve associated dxImg and dyImg */ - pdxImg = edLineVec_[octaveCount]->dxImg_.ptr(); - pdyImg = edLineVec_[octaveCount]->dyImg_.ptr(); - - /* get image size to work on from real one */ - realWidth = edLineVec_[octaveCount]->imageWidth; - imageWidth = realWidth -1; - imageHeight = edLineVec_[octaveCount]->imageHeight-1; - - - /* initialize memory areas */ - memset(pgdLBandSum, 0, numOfBitsBand); - memset(ngdLBandSum, 0, numOfBitsBand); - memset(pgdL2BandSum, 0, numOfBitsBand); - memset(ngdL2BandSum, 0, numOfBitsBand); - memset(pgdOBandSum, 0, numOfBitsBand); - memset(ngdOBandSum, 0, numOfBitsBand); - memset(pgdO2BandSum, 0, numOfBitsBand); - memset(ngdO2BandSum, 0, numOfBitsBand); - - /* get length of line and its half */ - lengthOfLSP = keyLines[lineIDInScaleVec][lineIDInSameLine].numOfPixels; - halfWidth = (lengthOfLSP-1)/2; - - /* get middlepoint of line */ - lineMiddlePointX = 0.5 * (pSingleLine->sPointInOctaveX + pSingleLine->ePointInOctaveX); - lineMiddlePointY = 0.5 * (pSingleLine->sPointInOctaveY + pSingleLine->ePointInOctaveY); - - /*1.rotate the local coordinate system to the line direction (direction is the angle - between positive line direction and positive X axis) - *2.compute the gradient projection of pixels in line support region*/ - - /* get the vector representing original image reference system after rotation to aligh with - line's direction */ - dL[0] = cos(pSingleLine->direction); - dL[1] = sin(pSingleLine->direction); - - /* set the clockwise orthogonal vector of line direction */ - dO[0] = -dL[1]; - dO[1] = dL[0]; - - /* get rotated reference frame */ - sCorX0= -dL[0]*halfWidth + dL[1]*halfHeight + lineMiddlePointX;//hID =0; wID = 0; - sCorY0= -dL[1]*halfWidth - dL[0]*halfHeight + lineMiddlePointY; - - - /* BIAS::Matrix gDLMat(heightOfLSP,lengthOfLSP) */ - for(short hID = 0; hID imageWidth)?imageWidth:tempCor; - tempCor = round(sCorY); - yCor = (tempCor<0)?0:(tempCor>imageHeight)?imageHeight:tempCor; - - /* To achieve rotation invariance, each simple gradient is rotated aligned with - * the line direction and clockwise orthogonal direction.*/ - dx = pdxImg[yCor*realWidth+xCor]; - dy = pdyImg[yCor*realWidth+xCor]; - gDL = dx * dL[0] + dy * dL[1]; - gDO = dx * dO[0] + dy * dO[1]; - if(gDL>0){ - pgdLRowSum += gDL; - }else{ - ngdLRowSum -= gDL; - } - if(gDO>0){ - pgdORowSum += gDO; - }else{ - ngdORowSum -= gDO; - } - sCorX +=dL[0]; - sCorY +=dL[1]; - /* gDLMat[hID][wID] = gDL; */ - } - sCorX0 -=dL[1]; - sCorY0 +=dL[0]; - coefInGaussion = gaussCoefG_[hID]; - pgdLRowSum = coefInGaussion * pgdLRowSum; - ngdLRowSum = coefInGaussion * ngdLRowSum; - pgdL2RowSum = pgdLRowSum * pgdLRowSum; - ngdL2RowSum = ngdLRowSum * ngdLRowSum; - pgdORowSum = coefInGaussion * pgdORowSum; - ngdORowSum = coefInGaussion * ngdORowSum; - pgdO2RowSum = pgdORowSum * pgdORowSum; - ngdO2RowSum = ngdORowSum * ngdORowSum; - - /* compute {g_dL |g_dL>0 }, {g_dL |g_dL<0 }, - {g_dO |g_dO>0 }, {g_dO |g_dO<0 } of each band in the line support region - first, current row belong to current band */ - bandID = hID/widthOfBand_; - coefInGaussion = gaussCoefL_[hID%widthOfBand_+widthOfBand_]; - pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; - ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; - pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; - ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; - pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; - ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; - pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; - ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; - - /* In order to reduce boundary effect along the line gradient direction, - * a row's gradient will contribute not only to its current band, but also - * to its nearest upper and down band with gaussCoefL_.*/ - bandID--; - if(bandID>=0){/* the band above the current band */ - coefInGaussion = gaussCoefL_[hID%widthOfBand_ + 2*widthOfBand_]; - pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; - ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; - pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; - ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; - pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; - ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; - pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; - ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; - } - bandID = bandID+2; - if(bandIDdescriptor.resize(descriptorSize); - desVec = pSingleLine->descriptor.data(); - - short desID; - - /*Note that the first and last bands only have (lengthOfLSP * widthOfBand_ * 2.0) pixels - * which are counted. */ - float invN2 = 1.0/(widthOfBand_ * 2.0); - float invN3 = 1.0/(widthOfBand_ * 3.0); - float invN, temp; - for(bandID = 0; bandIDdescriptor.data(); - - int base = 0; - for(short i=0; idescriptor.data(); - base = 0; - for(short i=0; idescriptor.data(); - for(short i=0; i0.4){ - desVec[i]=0.4; - } - } - - //re-normalize desVec; - temp = 0; - for(short i=0; if2[i]) - { -// std::cout<< " ------ 1 ------- "<f2[i]) -// { -//// std::cout<< " ------ 1 ------- "<& desc) -{ - uchar result=0; - for(int i = 0; i<8; i++) - { -// std::cout<<"f1[: "<desc[i+f2]) - { -// std::cout<< " ------ 1 ------- "< & oct_binaryDescMat, ScaleLines & keyLines) -{ - - /* std::cout<<"numOfOctave: "< rows_size; - for(int i = 0; i vec_binaryMat_p; - - /* loop on the number of the octaves */ - for(int i = 0; i(i, j) = (float)keyLines[i][0].descriptor[j]; -// } -// std::cout<= 3.12) - return true; - - return false; -} - - -void LineDescriptor::findNearestParallelLines(ScaleLines & keyLines) -{ - - std::cout<<"PARALLELLINES: size: "< parallels; - - /* loop over LineVecs */ - for(int j = 0; j::iterator it; - - /* scan map to searck for a line parallel to current one */ - bool foundParallel = false; - for(it = parallels.begin(); it != parallels.end(); it++) { - if(!areParallels(it->first, singleLine.direction)) - { - foundParallel = true; - break; - } - - } - - /* if a parallel line has not been found, add current line - to map, using its direction as a key */ - if(!foundParallel) - parallels[singleLine.direction] = singleLine; - - } - } - - /* create a vector of LineVecs, each one containing a line that is - not parallel to any other one inside a different LineVec */ - ScaleLines newKeyLines; - std::map::iterator it; - for(it = parallels.begin(); it != parallels.end(); it++) { - LinesVec lineScaleLs; - lineScaleLs.push_back(it->second); - newKeyLines.push_back(lineScaleLs); - } - - keyLines = newKeyLines; - -} - -int LineDescriptor::GetLineDescriptor(std::vector &scale_images, ScaleLines &keyLines) -{ - - /*check whether image depth is different from 0 - if(image.depth() != 0) - { - std::cout << "Warning, depth image != 0" << std::endl; - CV_Assert(false); - }*/ - - for(size_t scaleCounter = 0; scaleCounter ls = cv::createLineSegmentDetector(cv::LSD_REFINE_STD); - - /* prepare a vectore to host extracted segments */ - std::vector lines_std; - - /* use detector to extract segments */ - ls->detect(currentScaledImage, lines_std); - - /* store information for every extracted segment */ - for (size_t lineCounter = 0; lineCounter &matchLeft, std::vector &matchRight, - int criteria) -{ - - /* check whether any input is void */ - int leftSize = keyLinesLeft.size(); - int rightSize = keyLinesRight.size(); - if(leftSize<1||rightSize<1){ - return -1; - } - - /* void vectors */ - matchLeft.clear(); - matchRight.clear(); - - - int desDim = keyLinesLeft[0][0].descriptor.size(); - float *desL, *desR, *desMax, *desOld; - - if(criteria==NearestNeighbor) - { - float minDis,dis,temp; - int corresId; - - /* loop over left list of LineVecs */ - for(int idL=0; idL - (realloc (arr, sizeof(UINT32)*(2 + arr[1]))); - if (new_Data == NULL) + if (arr[0] == arr[1]) { - /* could not realloc, but orig still valid */ - std::cout << "ALERT!!!! Not enough memory, operation aborted!" - << std::endl; - exit(0); - } - else - { - arr = new_Data; - } - - } + arr[1] = std::max(ceil(arr[1]*ARRAY_RESIZE_FACTOR), + arr[1]+ARRAY_RESIZE_ADD_FACTOR); + UINT32* new_Data = static_cast + (realloc (arr, sizeof(UINT32)*(2 + arr[1]))); + if (new_Data == NULL) + { + /* could not realloc, but orig still valid */ + std::cout << "ALERT!!!! Not enough memory, operation aborted!" + << std::endl; + exit(0); + } + else + { + arr = new_Data; + } - arr[2 + arr[0]] = Data; - arr[0]++; + } + + arr[2 + arr[0]] = Data; + arr[0]++; } @@ -137,19 +174,19 @@ UINT32 Array32::capacity () /* print data */ void Array32::print() { - for (int i=0; i BinaryDescriptor::createBinaryDescriptor() +{ + return Ptr( new BinaryDescriptor() ); +} + +Ptr BinaryDescriptor::createBinaryDescriptor( Params parameters ) +{ + return Ptr( new BinaryDescriptor( parameters ) ); +} + +/* construct a BinaryDescrptor object and compute external private parameters */ +BinaryDescriptor::BinaryDescriptor( const BinaryDescriptor::Params ¶meters ) : + params( parameters ) +{ + + /* prepare a vector to host local weights F_l*/ + gaussCoefL_.resize( params.widthOfBand_ * 3 ); + + /* compute center of central band (every computation involves 2-3 bands) */ + double u = ( params.widthOfBand_ * 3 - 1 ) / 2; + + /* compute exponential part of F_l */ + double sigma = ( params.widthOfBand_ * 2 + 1 ) / 2; // (widthOfBand_*2+1)/2; + double invsigma2 = -1 / ( 2 * sigma * sigma ); + + /* compute all local weights */ + double dis; + for ( int i = 0; i < params.widthOfBand_ * 3; i++ ) + { + dis = i - u; + gaussCoefL_[i] = exp( dis * dis * invsigma2 ); + } + + /* prepare a vector for global weights F_g*/ + gaussCoefG_.resize( NUM_OF_BANDS * params.widthOfBand_ ); + + /* compute center of LSR */ + u = ( NUM_OF_BANDS * params.widthOfBand_ - 1 ) / 2; + + /* compute exponential part of F_g */ + sigma = u; + invsigma2 = -1 / ( 2 * sigma * sigma ); + for ( int i = 0; i < NUM_OF_BANDS * params.widthOfBand_; i++ ) + { + dis = i - u; + gaussCoefG_[i] = exp( dis * dis * invsigma2 ); + } +} + +/* definition of operator () */ +void BinaryDescriptor::operator()( InputArray image, InputArray mask, CV_OUT std::vector& keylines, OutputArray descriptors, + bool useProvidedKeyLines ) const +{ + + /* create some matrix objects */ + cv::Mat imageMat, maskMat, descrMat; + + /* store reference to input matrices */ + imageMat = image.getMat(); + maskMat = mask.getMat(); + + /* initialize output matrix */ + descriptors.create( Size( 32, keylines.size() ), CV_8UC1 ); + + /* store reference to output matrix */ + descrMat = descriptors.getMat(); + + /* require drawing KeyLines detection if demanded */ + if( !useProvidedKeyLines ) + detectImpl( imageMat, keylines, maskMat ); + + /* compute descriptors */ + computeImpl( imageMat, keylines, descrMat ); +} + +BinaryDescriptor::~BinaryDescriptor() +{ +} + +/* read parameters from a FileNode object and store them (class function ) */ +void BinaryDescriptor::read( const cv::FileNode& fn ) +{ + params.read( fn ); +} + +/* store parameters to a FileStorage object (class function) */ +void BinaryDescriptor::write( cv::FileStorage& fs ) const +{ + params.write( fs ); +} + +/* return norm mode */ +int BinaryDescriptor::defaultNorm() const +{ + return NORM_HAMMING; +} + +/* return data type */ +int BinaryDescriptor::descriptorType() const +{ + return CV_8U; +} + +/*return descriptor size */ +int BinaryDescriptor::descriptorSize() const +{ + return 32 * 8; +} + +/* check whether Gaussian pyramids were created */ +bool BinaryDescriptor::empty() const +{ + return octaveImages.empty(); +} + +/* power function with error management */ +static inline int get2Pow( int i ) +{ + if( i >= 0 && i <= 7 ) + return pow( 2, i ); + + else + { + CV_Assert( false ); + return -1; + } +} + +/* utility function for conversion of an LBD descriptor to its binary representation */ +unsigned char BinaryDescriptor::binaryConversion( float* f1, float* f2 ) +{ + uchar result = 0; + for ( int i = 0; i < 8; i++ ) + { + if( f1[i] > f2[i] ) + result += get2Pow( i ); + } + + return result; + +} + +/* get coefficients of line passing by two points in (line_extremes) */ +void BinaryDescriptor::getLineParameters( cv::Vec4i& line_extremes, cv::Vec3i& lineParams ) +{ + int x1 = line_extremes[0]; + int x2 = line_extremes[2]; + int y1 = line_extremes[1]; + int y2 = line_extremes[3]; + + /* line is parallel to Y axis */ + if( x1 == x2 ) + { + lineParams[0] = 1; + lineParams[1] = 0; + lineParams[2] = x1 /* or x2 */; + } + + /* line is parallel to X axis */ + else if( y1 == y2 ) + { + lineParams[0] = 0; + lineParams[1] = 1; + lineParams[2] = y1 /* or y2 */; + } + + /* line is not parallel to any axis */ + else + { + lineParams[0] = y1 - y2; + lineParams[1] = x2 - x1; + lineParams[2] = -y1 * ( x2 - x1 ) + x1 * ( y2 - y1 ); + } +} +/* compute the angle between line and X axis */ +float BinaryDescriptor::getLineDirection( cv::Vec3i &lineParams ) +{ + /* line is parallel to X axis */ + if( lineParams[0] == 0 ) + return 0; + + /* line is parallel to Y axis */ + else if( lineParams[1] == 0 ) + return M_PI / 2; + + /* line is not parallel to any axis */ + else + return atan2( -lineParams[0], lineParams[1] ); +} + +/* compute Gaussian pyramid of input image */ +void BinaryDescriptor::computeGaussianPyramid( const Mat& image ) +{ + /* clear class fields */ + images_sizes.clear(); + octaveImages.clear(); + extractedLines.clear(); + + /* insert input image into pyramid */ + cv::Mat currentMat = image.clone(); + cv::GaussianBlur( currentMat, currentMat, cv::Size( 5, 5 ), 1 ); + octaveImages.push_back( currentMat ); + images_sizes.push_back( currentMat.size() ); + + /* fill Gaussian pyramid */ + for ( int pyrCounter = 1; pyrCounter < params.numOfOctave_; pyrCounter++ ) + { + /* compute and store next image in pyramid and its size */ + pyrDown( currentMat, currentMat, Size( currentMat.cols / params.reductionRatio, currentMat.rows / params.reductionRatio ) ); + octaveImages.push_back( currentMat ); + images_sizes.push_back( currentMat.size() ); + } +} + +/* requires line detection (only one image) */ +void BinaryDescriptor::detect( const Mat& image, CV_OUT std::vector& keylines, const Mat& mask ) +{ + if( mask.data != NULL && ( mask.size() != image.size() || mask.type() != CV_8UC1 ) ) + { + + std::cout << "Mask error while detecting lines: " << "please check its dimensions and that data type is CV_8UC1" << std::endl; + + CV_Assert( false ); + } + + else + detectImpl( image, keylines, mask ); +} + +/* requires line detection (more than one image) */ +void BinaryDescriptor::detect( const std::vector& images, std::vector >& keylines, const std::vector& masks ) const +{ + /* detect lines from each image */ + for ( size_t counter = 0; counter < images.size(); counter++ ) + { + if( masks[counter].data != NULL && ( masks[counter].size() != images[counter].size() || masks[counter].type() != CV_8UC1 ) ) + { + + std::cout << "Masks error while detecting lines: " << "please check their dimensions and that data types are CV_8UC1" << std::endl; + + CV_Assert( false ); + } + + detectImpl( images[counter], keylines[counter], masks[counter] ); + } +} + +void BinaryDescriptor::detectImpl( const Mat& imageSrc, std::vector& keylines, const Mat& mask ) const +{ + + cv::Mat image; + if(imageSrc.channels() != 1) + cvtColor( imageSrc, image, COLOR_BGR2GRAY ); + else + image = imageSrc.clone(); + + /*check whether image depth is different from 0 */ + if( image.depth() != 0 ) + { + std::cout << "Warning, depth image!= 0" << std::endl; + CV_Assert( false ); + } + + /* create a pointer to self */ + BinaryDescriptor *bn = const_cast( this ); + + /* compute Gaussian pyramid */ + bn->computeGaussianPyramid( image ); + + /* detect and arrange lines across octaves */ + ScaleLines sl; + bn->OctaveKeyLines( sl ); + + /* fill KeyLines vector */ + for ( int i = 0; i < (int) sl.size(); i++ ) + { + for ( size_t j = 0; j < sl[i].size(); j++ ) + { + /* get current line */ + OctaveSingleLine osl = sl[i][j]; + + /* create a KeyLine object */ + KeyLine kl; + + /* fill KeyLine's fields */ + kl.startPointX = osl.startPointX; + kl.startPointY = osl.startPointY; + kl.endPointX = osl.endPointX; + kl.endPointY = osl.endPointY; + kl.sPointInOctaveX = osl.sPointInOctaveX; + kl.sPointInOctaveY = osl.sPointInOctaveY; + kl.ePointInOctaveX = osl.ePointInOctaveX; + kl.ePointInOctaveY = osl.ePointInOctaveY; + kl.lineLength = osl.lineLength; + kl.numOfPixels = osl.numOfPixels; + + kl.angle = osl.direction; + kl.class_id = i; + kl.octave = osl.octaveCount; + kl.size = ( osl.endPointX - osl.startPointX ) * ( osl.endPointY - osl.startPointY ); + kl.response = osl.lineLength / max( images_sizes[osl.octaveCount].width, images_sizes[osl.octaveCount].height ); + kl.pt = Point( ( osl.endPointX + osl.startPointX ) / 2, ( osl.endPointY + osl.startPointY ) / 2 ); + + /* store KeyLine */ + keylines.push_back( kl ); + } + + } + + /* delete undesired KeyLines, according to input mask */ + if( !mask.empty() ) + { + for ( size_t keyCounter = 0; keyCounter < keylines.size(); keyCounter++ ) + { + KeyLine kl = keylines[keyCounter]; + if( mask.at( kl.startPointY, kl.startPointX ) == 0 && mask.at( kl.endPointY, kl.endPointX ) == 0 ) + keylines.erase( keylines.begin() + keyCounter ); + } + } + +} + +/* requires descriptors computation (only one image) */ +void BinaryDescriptor::compute( const Mat& image, CV_OUT CV_IN_OUT std::vector& keylines, CV_OUT Mat& descriptors ) const +{ + computeImpl( image, keylines, descriptors ); +} + +/* requires descriptors computation (more than one image) */ +void BinaryDescriptor::compute( const std::vector& images, std::vector >& keylines, std::vector& descriptors ) const +{ + for ( size_t i = 0; i < images.size(); i++ ) + computeImpl( images[i], keylines[i], descriptors[i] ); +} + +/* implementation of descriptors computation */ +void BinaryDescriptor::computeImpl( const Mat& imageSrc, std::vector& keylines, Mat& descriptors ) const +{ + /* convert input image to gray scale */ + cv::Mat image; + if(imageSrc.channels() != 1) + cvtColor( imageSrc, image, COLOR_BGR2GRAY ); + else + image = imageSrc.clone(); + + /*check whether image's depth is different from 0 */ + if( image.depth() != 0 ) + { + std::cout << "Error, depth of image != 0" << std::endl; + CV_Assert( false ); + } + + /* keypoints list can't be empty */ + if( keylines.size() == 0 ) + { + std::cout << "Error: keypoint list is empty" << std::endl; + return; + } + + /* get maximum class_id */ + int numLines = 0; + for ( size_t l = 0; l < keylines.size(); l++ ) + { + if( keylines[l].class_id > numLines ) + numLines = keylines[l].class_id; + } + + /* create a ScaleLines object */ + OctaveSingleLine fictiousOSL; + fictiousOSL.octaveCount = -1; + LinesVec lv( params.numOfOctave_, fictiousOSL ); + ScaleLines sl( numLines + 1, lv ); + + /* create a map to record association between KeyLines and their position + in ScaleLines vector */ + std::map, int> correspondences; + + /* fill ScaleLines object */ + for ( size_t slCounter = 0; slCounter < keylines.size(); slCounter++ ) + { + /* get a KeyLine object and create a new line */ + KeyLine kl = keylines[slCounter]; + OctaveSingleLine osl; + + /* insert data in newly created line */ + osl.startPointX = kl.startPointX; + osl.startPointY = kl.startPointY; + osl.endPointX = kl.endPointX; + osl.endPointY = kl.endPointY; + osl.sPointInOctaveX = kl.sPointInOctaveX; + osl.sPointInOctaveY = kl.sPointInOctaveY; + osl.ePointInOctaveX = kl.ePointInOctaveX; + osl.ePointInOctaveY = kl.ePointInOctaveY; + osl.lineLength = kl.lineLength; + osl.numOfPixels = kl.numOfPixels; + osl.salience = kl.response; + + osl.direction = kl.angle; + osl.octaveCount = kl.octave; + + /* store new line */ + sl[kl.class_id][kl.octave] = osl; + + /* update map */ + int id = kl.class_id; + int oct = kl.octave; + correspondences.insert( std::pair, int>( std::pair( id, oct ), slCounter ) ); + } + + /* delete useless OctaveSingleLines */ + for ( size_t i = 0; i < sl.size(); i++ ) + { + for ( size_t j = 0; j < sl[i].size(); j++ ) + { + if( (int) ( sl[i][j] ).octaveCount == -1 ) + ( sl[i] ).erase( ( sl[i] ).begin() + j ); + } + } + + /* compute Gaussian pyramid, if image is new or pyramid was not + computed before */ + BinaryDescriptor *bn = const_cast( this ); + /* all structures cleared in computeGaussianPyramid */ + bn->computeGaussianPyramid( image ); + + /* compute Sobel's derivatives */ + bn->dxImg_vector.clear(); + bn->dyImg_vector.clear(); + + bn->dxImg_vector.resize( params.numOfOctave_ ); + bn->dyImg_vector.resize( params.numOfOctave_ ); + + for ( size_t sobelCnt = 0; sobelCnt < octaveImages.size(); sobelCnt++ ) + { + bn->dxImg_vector[sobelCnt].create( images_sizes[sobelCnt].height, images_sizes[sobelCnt].width, CV_16SC1 ); + bn->dyImg_vector[sobelCnt].create( images_sizes[sobelCnt].height, images_sizes[sobelCnt].width, CV_16SC1 ); + + cv::Sobel( octaveImages[sobelCnt], bn->dxImg_vector[sobelCnt], CV_16SC1, 1, 0, 3 ); + cv::Sobel( octaveImages[sobelCnt], bn->dyImg_vector[sobelCnt], CV_16SC1, 0, 1, 3 ); + } + + /* compute LBD descriptors */ + bn->computeLBD( sl ); + + /* resize output matrix */ + descriptors = cv::Mat( keylines.size(), 32, CV_8UC1 ); + + /* fill output matrix with descriptors */ + for ( size_t k = 0; k < sl.size(); k++ ) + { + for ( size_t lineC = 0; lineC < sl[k].size(); lineC++ ) + { + /* get original index of keypoint */ + int lineOctave = ( sl[k][lineC] ).octaveCount; + int originalIndex = correspondences.find( std::pair( k, lineOctave ) )->second; + + /* get a pointer to correspondent row in output matrix */ + uchar* pointerToRow = descriptors.ptr( originalIndex ); + + /* get LBD data */ + float* desVec = sl[k][lineC].descriptor.data(); + + /* fill current row with binary descriptor */ + for ( int comb = 0; comb < 32; comb++ ) + { + *pointerToRow = bn->binaryConversion( &desVec[8 * combinations[comb][0]], &desVec[8 * combinations[comb][1]] ); + + pointerToRow++; + } + + } + } + +} + +/* gather lines in groups. Each group contains the same line, detected in different octaves */ +int BinaryDescriptor::OctaveKeyLines( ScaleLines &keyLines ) +{ + + /* final number of extracted lines */ + unsigned int numOfFinalLine = 0; + + for ( size_t scaleCounter = 0; scaleCounter < octaveImages.size(); scaleCounter++ ) + { + /* get current scaled image */ + cv::Mat currentScaledImage = octaveImages[scaleCounter]; + + /* create an LSD detector and store a pointer to it */ + cv::Ptr ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV ); + + /* prepare a vector to host extracted segments */ + std::vector lines_std; + + /* use detector to extract segments */ + ls->detect( currentScaledImage, lines_std ); + + /* store lines extracted from current image */ + extractedLines.push_back( lines_std ); + + /* update lines counter */ + numOfFinalLine += lines_std.size(); + + } + + /* prepare a vector to store octave information associated to extracted lines */ + std::vector octaveLines( numOfFinalLine ); + + /* set lines' counter to 0 for reuse */ + numOfFinalLine = 0; + + /* counter to give a unique ID to lines in LineVecs */ + unsigned int lineIDInScaleLineVec = 0; + + /* floats to compute lines' lengths */ + float dx, dy; + + /* loop over lines extracted from scale 0 (original image) */ + for ( unsigned int lineCurId = 0; lineCurId < extractedLines[0].size(); lineCurId++ ) + { + /* set octave from which it was extracted */ + octaveLines[numOfFinalLine].octaveCount = 0; + /* set ID within its octave */ + octaveLines[numOfFinalLine].lineIDInOctave = lineCurId; + /* set a unique ID among all lines extracted in all octaves */ + octaveLines[numOfFinalLine].lineIDInScaleLineVec = lineIDInScaleLineVec; + + /* compute absolute value of difference between X coordinates of line's extreme points */ + dx = fabs( ( extractedLines[0][lineCurId] )[0] - ( extractedLines[0][lineCurId] )[2] ); + /* compute absolute value of difference between Y coordinates of line's extreme points */ + dy = fabs( ( extractedLines[0][lineCurId] )[1] - ( extractedLines[0][lineCurId] )[3] ); + /* compute line's length */ + octaveLines[numOfFinalLine].lineLength = sqrt( dx * dx + dy * dy ); + + /* update counters */ + numOfFinalLine++; + lineIDInScaleLineVec++; + + } + + /* create and fill an array to store scale factors */ + float *scale = new float[params.numOfOctave_]; + scale[0] = 1; + for ( unsigned int octaveCount = 1; octaveCount < (unsigned int) params.numOfOctave_; octaveCount++ ) + { + scale[octaveCount] = params.reductionRatio * scale[octaveCount - 1]; + } + + /* some variables' declarations */ + float rho1, rho2, tempValue; + float direction, near, length; + unsigned int octaveID, lineIDInOctave; + + /*more than one octave image, organize lines in scale space. + *lines corresponding to the same line in octave images should have the same index in the ScaleLineVec */ + if( params.numOfOctave_ > 1 ) + { + /* some other variables' declarations */ + float twoPI = 2 * M_PI; + unsigned int closeLineID; + float endPointDis, minEndPointDis, minLocalDis, maxLocalDis; + float lp0, lp1, lp2, lp3, np0, np1, np2, np3; + + /* loop over list of octaves */ + for ( unsigned int octaveCount = 1; octaveCount < (unsigned int) params.numOfOctave_; octaveCount++ ) + { + /*for each line in current octave image, find their corresponding lines + in the octaveLines, + give them the same value of lineIDInScaleLineVec*/ + + /* loop over list of lines extracted from current octave */ + for ( unsigned int lineCurId = 0; lineCurId < extractedLines[octaveCount].size(); lineCurId++ ) + { + /* get (scaled) known term from equation of current line */ + cv::Vec3i line_equation; + getLineParameters( extractedLines[octaveCount][lineCurId], line_equation ); + rho1 = scale[octaveCount] * fabs( line_equation[2] ); + + /*nearThreshold depends on the distance of the image coordinate origin to current line. + *so nearThreshold = rho1 * nearThresholdRatio, where nearThresholdRatio = 1-cos(10*pi/180) = 0.0152*/ + tempValue = rho1 * 0.0152; + float nearThreshold = ( tempValue > 6 ) ? ( tempValue ) : 6; + nearThreshold = ( nearThreshold < 12 ) ? nearThreshold : 12; + + /* compute scaled lenght of current line */ + dx = fabs( ( extractedLines[octaveCount][lineCurId] )[0] - ( extractedLines[octaveCount][lineCurId][2] ) ); //x1-x2 + dy = fabs( ( extractedLines[octaveCount][lineCurId] )[1] - ( extractedLines[octaveCount][lineCurId][3] ) ); //y1-y2 + length = scale[octaveCount] * sqrt( dx * dx + dy * dy ); + + minEndPointDis = 12; + /* loop over the octave representations of all lines */ + for ( unsigned int lineNextId = 0; lineNextId < numOfFinalLine; lineNextId++ ) + { + /* if a line from same octave is encountered, + a comparison with it shouldn't be considered */ + octaveID = octaveLines[lineNextId].octaveCount; + if( octaveID == octaveCount ) + break; + + /* take ID (in octave) of line to be compared */ + lineIDInOctave = octaveLines[lineNextId].lineIDInOctave; + + /* compute difference between lines' directions, to check + whether they are parallel */ + cv::Vec3i line_equation_to_compare; + getLineParameters( extractedLines[octaveID][lineIDInOctave], line_equation_to_compare ); + + direction = fabs( getLineDirection( line_equation ) - getLineDirection( line_equation_to_compare ) ); + + /* the angle between two lines are larger than 10degrees + (i.e. 10*pi/180=0.1745), they are not close to parallel */ + if( direction > 0.1745 && ( twoPI - direction > 0.1745 ) ) + continue; + + /*now check whether current line and next line are near to each other. + Get known term from equation to be compared */ + rho2 = scale[octaveID] * fabs( line_equation_to_compare[2] ); + + /* compute difference between known terms */ + near = fabs( rho1 - rho2 ); + + /* two lines are not close in the image */ + if( near > nearThreshold ) + continue; + + /* get the extreme points of the two lines */ + lp0 = scale[octaveCount] * ( extractedLines[octaveCount][lineCurId] )[0]; + lp1 = scale[octaveCount] * ( extractedLines[octaveCount][lineCurId] )[1]; + lp2 = scale[octaveCount] * ( extractedLines[octaveCount][lineCurId] )[2]; + lp3 = scale[octaveCount] * ( extractedLines[octaveCount][lineCurId] )[3]; + np0 = scale[octaveID] * ( extractedLines[octaveID][lineIDInOctave] )[0]; + np1 = scale[octaveID] * ( extractedLines[octaveID][lineIDInOctave] )[1]; + np2 = scale[octaveID] * ( extractedLines[octaveID][lineIDInOctave] )[2]; + np3 = scale[octaveID] * ( extractedLines[octaveID][lineIDInOctave] )[3]; + + /* get the distance between the two leftmost extremes of lines + L1(0,1)<->L2(0,1) */ + dx = lp0 - np0; + dy = lp1 - np1; + endPointDis = sqrt( dx * dx + dy * dy ); + + /* set momentaneously min and max distance between lines to + the one between left extremes */ + minLocalDis = endPointDis; + maxLocalDis = endPointDis; + + /* compute distance between right extremes + L1(2,3)<->L2(2,3) */ + dx = lp2 - np2; + dy = lp3 - np3; + endPointDis = sqrt( dx * dx + dy * dy ); + + /* update (if necessary) min and max distance between lines */ + minLocalDis = ( endPointDis < minLocalDis ) ? endPointDis : minLocalDis; + maxLocalDis = ( endPointDis > maxLocalDis ) ? endPointDis : maxLocalDis; + + /* compute distance between left extreme of current line and + right extreme of line to be compared + L1(0,1)<->L2(2,3) */ + dx = lp0 - np2; + dy = lp1 - np3; + endPointDis = sqrt( dx * dx + dy * dy ); + + /* update (if necessary) min and max distance between lines */ + minLocalDis = ( endPointDis < minLocalDis ) ? endPointDis : minLocalDis; + maxLocalDis = ( endPointDis > maxLocalDis ) ? endPointDis : maxLocalDis; + + /* compute distance between right extreme of current line and + left extreme of line to be compared + L1(2,3)<->L2(0,1) */ + dx = lp2 - np0; + dy = lp3 - np1; + endPointDis = sqrt( dx * dx + dy * dy ); + + /* update (if necessary) min and max distance between lines */ + minLocalDis = ( endPointDis < minLocalDis ) ? endPointDis : minLocalDis; + maxLocalDis = ( endPointDis > maxLocalDis ) ? endPointDis : maxLocalDis; + + /* check whether conditions for considering line to be compared + wremoveInvalidPointsorth to be inserted in the same LineVec are satisfied */ + if( ( maxLocalDis < 0.8 * ( length + octaveLines[lineNextId].lineLength ) ) && ( minLocalDis < minEndPointDis ) ) + { + /* keep the closest line */ + minEndPointDis = minLocalDis; + closeLineID = lineNextId; + } + + } + + /* add current line into octaveLines */ + if( minEndPointDis < 12 ) + octaveLines[numOfFinalLine].lineIDInScaleLineVec = octaveLines[closeLineID].lineIDInScaleLineVec; + else + { + octaveLines[numOfFinalLine].lineIDInScaleLineVec = lineIDInScaleLineVec; + lineIDInScaleLineVec++; + } + + octaveLines[numOfFinalLine].octaveCount = octaveCount; + octaveLines[numOfFinalLine].lineIDInOctave = lineCurId; + octaveLines[numOfFinalLine].lineLength = length; + numOfFinalLine++; + } + } + } + + /* Reorganize the detected lines into keyLines */ + keyLines.clear(); + keyLines.resize( lineIDInScaleLineVec ); + unsigned int tempID; + float s1, e1, s2, e2; + bool shouldChange; + OctaveSingleLine singleLine; + for ( unsigned int lineID = 0; lineID < numOfFinalLine; lineID++ ) + { + lineIDInOctave = octaveLines[lineID].lineIDInOctave; + octaveID = octaveLines[lineID].octaveCount; + + cv::Vec3i tempParams; + getLineParameters( extractedLines[octaveID][lineIDInOctave], tempParams ); + + singleLine.octaveCount = octaveID; + singleLine.lineLength = octaveLines[lineID].lineLength; + + // decide the start point and end point + shouldChange = false; + + s1 = ( extractedLines[octaveID][lineIDInOctave] )[0]; //sx + s2 = ( extractedLines[octaveID][lineIDInOctave] )[1]; //sy + e1 = ( extractedLines[octaveID][lineIDInOctave] )[2]; //ex + e2 = ( extractedLines[octaveID][lineIDInOctave] )[3]; //ey + + dx = e1 - s1; //ex-sx + dy = e2 - s2; //ey-sy + + if( direction >= -0.75 * M_PI && direction < -0.25 * M_PI ) + { + if( dy > 0 ) + shouldChange = true; + } + + if( direction >= -0.25 * M_PI && direction < 0.25 * M_PI ) + if( dx < 0 ) + { + shouldChange = true; + } + + if( direction >= 0.25 * M_PI && direction < 0.75 * M_PI ) + if( dy < 0 ) + { + shouldChange = true; + } + + if( ( direction >= 0.75 * M_PI && direction < M_PI ) || ( direction >= -M_PI && direction < -0.75 * M_PI ) ) + { + if( dx > 0 ) + shouldChange = true; + } + + tempValue = scale[octaveID]; + + if( shouldChange ) + { + singleLine.sPointInOctaveX = e1; + singleLine.sPointInOctaveY = e2; + singleLine.ePointInOctaveX = s1; + singleLine.ePointInOctaveY = s2; + singleLine.startPointX = tempValue * e1; + singleLine.startPointY = tempValue * e2; + singleLine.endPointX = tempValue * s1; + singleLine.endPointY = tempValue * s2; + } + + else + { + singleLine.sPointInOctaveX = s1; + singleLine.sPointInOctaveY = s2; + singleLine.ePointInOctaveX = e1; + singleLine.ePointInOctaveY = e2; + singleLine.startPointX = tempValue * s1; + singleLine.startPointY = tempValue * s2; + singleLine.endPointX = tempValue * e1; + singleLine.endPointY = tempValue * e2; + } + + singleLine.direction = atan2( ( singleLine.endPointY - singleLine.startPointY ), ( singleLine.endPointX - singleLine.startPointX ) ); + + tempID = octaveLines[lineID].lineIDInScaleLineVec; + + /* compute number of pixels covered by line */ + LineIterator li( octaveImages[octaveID], Point( singleLine.startPointX, singleLine.startPointY ), + Point( singleLine.endPointX, singleLine.endPointY ) ); + + singleLine.numOfPixels = li.count; + + /* store line */ + keyLines[tempID].push_back( singleLine ); + + } + + delete[] scale; + return 1; + +} + +/* compute LBD descriptors */ +int BinaryDescriptor::computeLBD( ScaleLines &keyLines ) +{ + //the default length of the band is the line length. + short numOfFinalLine = keyLines.size(); + float *dL = new float[2]; //line direction cos(dir), sin(dir) + float *dO = new float[2]; //the clockwise orthogonal vector of line direction. + short heightOfLSP = params.widthOfBand_ * NUM_OF_BANDS; //the height of line support region; + short descriptor_size = NUM_OF_BANDS * 8; //each band, we compute the m( pgdL, ngdL, pgdO, ngdO) and std( pgdL, ngdL, pgdO, ngdO); + float pgdLRowSum; //the summation of {g_dL |g_dL>0 } for each row of the region; + float ngdLRowSum; //the summation of {g_dL |g_dL<0 } for each row of the region; + float pgdL2RowSum; //the summation of {g_dL^2 |g_dL>0 } for each row of the region; + float ngdL2RowSum; //the summation of {g_dL^2 |g_dL<0 } for each row of the region; + float pgdORowSum; //the summation of {g_dO |g_dO>0 } for each row of the region; + float ngdORowSum; //the summation of {g_dO |g_dO<0 } for each row of the region; + float pgdO2RowSum; //the summation of {g_dO^2 |g_dO>0 } for each row of the region; + float ngdO2RowSum; //the summation of {g_dO^2 |g_dO<0 } for each row of the region; + + float *pgdLBandSum = new float[NUM_OF_BANDS]; //the summation of {g_dL |g_dL>0 } for each band of the region; + float *ngdLBandSum = new float[NUM_OF_BANDS]; //the summation of {g_dL |g_dL<0 } for each band of the region; + float *pgdL2BandSum = new float[NUM_OF_BANDS]; //the summation of {g_dL^2 |g_dL>0 } for each band of the region; + float *ngdL2BandSum = new float[NUM_OF_BANDS]; //the summation of {g_dL^2 |g_dL<0 } for each band of the region; + float *pgdOBandSum = new float[NUM_OF_BANDS]; //the summation of {g_dO |g_dO>0 } for each band of the region; + float *ngdOBandSum = new float[NUM_OF_BANDS]; //the summation of {g_dO |g_dO<0 } for each band of the region; + float *pgdO2BandSum = new float[NUM_OF_BANDS]; //the summation of {g_dO^2 |g_dO>0 } for each band of the region; + float *ngdO2BandSum = new float[NUM_OF_BANDS]; //the summation of {g_dO^2 |g_dO<0 } for each band of the region; + + short numOfBitsBand = NUM_OF_BANDS * sizeof(float); + short lengthOfLSP; //the length of line support region, varies with lines + short halfHeight = ( heightOfLSP - 1 ) / 2; + short halfWidth; + short bandID; + float coefInGaussion; + float lineMiddlePointX, lineMiddlePointY; + float sCorX, sCorY, sCorX0, sCorY0; + short tempCor, xCor, yCor; //pixel coordinates in image plane + short dx, dy; + float gDL; //store the gradient projection of pixels in support region along dL vector + float gDO; //store the gradient projection of pixels in support region along dO vector + short imageWidth, imageHeight, realWidth; + short *pdxImg, *pdyImg; + float *desVec; + + short sameLineSize; + short octaveCount; + OctaveSingleLine *pSingleLine; + /* loop over list of LineVec */ + for ( short lineIDInScaleVec = 0; lineIDInScaleVec < numOfFinalLine; lineIDInScaleVec++ ) + { + sameLineSize = keyLines[lineIDInScaleVec].size(); + /* loop over current LineVec's lines */ + for ( short lineIDInSameLine = 0; lineIDInSameLine < sameLineSize; lineIDInSameLine++ ) + { + /* get a line in current LineVec and its original ID in its octave */ + pSingleLine = & ( keyLines[lineIDInScaleVec][lineIDInSameLine] ); + octaveCount = pSingleLine->octaveCount; + + /* retrieve associated dxImg and dyImg + pdxImg = edLineVec_[octaveCount]->dxImg_.ptr(); + pdyImg = edLineVec_[octaveCount]->dyImg_.ptr(); */ + pdxImg = dxImg_vector[octaveCount].ptr(); + pdyImg = dyImg_vector[octaveCount].ptr(); + + /* get image size to work on from real one + realWidth = edLineVec_[octaveCount]->imageWidth; + imageWidth = realWidth -1; + imageHeight = edLineVec_[octaveCount]->imageHeight-1; */ + realWidth = images_sizes[octaveCount].width; + imageWidth = realWidth - 1; + imageHeight = images_sizes[octaveCount].height - 1; + + /* initialize memory areas */ + memset( pgdLBandSum, 0, numOfBitsBand ); + memset( ngdLBandSum, 0, numOfBitsBand ); + memset( pgdL2BandSum, 0, numOfBitsBand ); + memset( ngdL2BandSum, 0, numOfBitsBand ); + memset( pgdOBandSum, 0, numOfBitsBand ); + memset( ngdOBandSum, 0, numOfBitsBand ); + memset( pgdO2BandSum, 0, numOfBitsBand ); + memset( ngdO2BandSum, 0, numOfBitsBand ); + + /* get length of line and its half */ + lengthOfLSP = keyLines[lineIDInScaleVec][lineIDInSameLine].numOfPixels; + halfWidth = ( lengthOfLSP - 1 ) / 2; + + /* get middlepoint of line */ + lineMiddlePointX = 0.5 * ( pSingleLine->sPointInOctaveX + pSingleLine->ePointInOctaveX ); + lineMiddlePointY = 0.5 * ( pSingleLine->sPointInOctaveY + pSingleLine->ePointInOctaveY ); + + /*1.rotate the local coordinate system to the line direction (direction is the angle + between positive line direction and positive X axis) + *2.compute the gradient projection of pixels in line support region*/ + + /* get the vector representing original image reference system after rotation to aligh with + line's direction */ + dL[0] = cos( pSingleLine->direction ); + dL[1] = sin( pSingleLine->direction ); + + /* set the clockwise orthogonal vector of line direction */ + dO[0] = -dL[1]; + dO[1] = dL[0]; + + /* get rotated reference frame */ + sCorX0 = -dL[0] * halfWidth + dL[1] * halfHeight + lineMiddlePointX; //hID =0; wID = 0; + sCorY0 = -dL[1] * halfWidth - dL[0] * halfHeight + lineMiddlePointY; + + /* BIAS::Matrix gDLMat(heightOfLSP,lengthOfLSP) */ + for ( short hID = 0; hID < heightOfLSP; hID++ ) + { + /*initialization */ + sCorX = sCorX0; + sCorY = sCorY0; + + pgdLRowSum = 0; + ngdLRowSum = 0; + pgdORowSum = 0; + ngdORowSum = 0; + + for ( short wID = 0; wID < lengthOfLSP; wID++ ) + { + tempCor = round( sCorX ); + xCor = ( tempCor < 0 ) ? 0 : ( tempCor > imageWidth ) ? imageWidth : tempCor; + tempCor = round( sCorY ); + yCor = ( tempCor < 0 ) ? 0 : ( tempCor > imageHeight ) ? imageHeight : tempCor; + + /* To achieve rotation invariance, each simple gradient is rotated aligned with + * the line direction and clockwise orthogonal direction.*/ + dx = pdxImg[yCor * realWidth + xCor]; + dy = pdyImg[yCor * realWidth + xCor]; + gDL = dx * dL[0] + dy * dL[1]; + gDO = dx * dO[0] + dy * dO[1]; + if( gDL > 0 ) + { + pgdLRowSum += gDL; + } + + else + { + ngdLRowSum -= gDL; + } + + if( gDO > 0 ) + { + pgdORowSum += gDO; + } + + else + { + ngdORowSum -= gDO; + } + + sCorX += dL[0]; + sCorY += dL[1]; + /* gDLMat[hID][wID] = gDL; */ + } + sCorX0 -= dL[1]; + sCorY0 += dL[0]; + coefInGaussion = gaussCoefG_[hID]; + pgdLRowSum = coefInGaussion * pgdLRowSum; + ngdLRowSum = coefInGaussion * ngdLRowSum; + pgdL2RowSum = pgdLRowSum * pgdLRowSum; + ngdL2RowSum = ngdLRowSum * ngdLRowSum; + pgdORowSum = coefInGaussion * pgdORowSum; + ngdORowSum = coefInGaussion * ngdORowSum; + pgdO2RowSum = pgdORowSum * pgdORowSum; + ngdO2RowSum = ngdORowSum * ngdORowSum; + + /* compute {g_dL |g_dL>0 }, {g_dL |g_dL<0 }, + {g_dO |g_dO>0 }, {g_dO |g_dO<0 } of each band in the line support region + first, current row belongs to current band */ + bandID = hID / params.widthOfBand_; + coefInGaussion = gaussCoefL_[hID % params.widthOfBand_ + params.widthOfBand_]; + pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; + ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; + pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; + ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; + pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; + ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; + pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; + ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; + + /* In order to reduce boundary effect along the line gradient direction, + * a row's gradient will contribute not only to its current band, but also + * to its nearest upper and down band with gaussCoefL_.*/ + bandID--; + if( bandID >= 0 ) + {/* the band above the current band */ + coefInGaussion = gaussCoefL_[hID % params.widthOfBand_ + 2 * params.widthOfBand_]; + pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; + ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; + pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; + ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; + pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; + ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; + pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; + ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; + } + + bandID = bandID + 2; + if( bandID < NUM_OF_BANDS ) + {/*the band below the current band */ + coefInGaussion = gaussCoefL_[hID % params.widthOfBand_]; + pgdLBandSum[bandID] += coefInGaussion * pgdLRowSum; + ngdLBandSum[bandID] += coefInGaussion * ngdLRowSum; + pgdL2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdL2RowSum; + ngdL2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdL2RowSum; + pgdOBandSum[bandID] += coefInGaussion * pgdORowSum; + ngdOBandSum[bandID] += coefInGaussion * ngdORowSum; + pgdO2BandSum[bandID] += coefInGaussion * coefInGaussion * pgdO2RowSum; + ngdO2BandSum[bandID] += coefInGaussion * coefInGaussion * ngdO2RowSum; + } + } + /* gDLMat.Save("gDLMat.txt"); + return 0; */ + + /* construct line descriptor */ + pSingleLine->descriptor.resize( descriptor_size ); + desVec = pSingleLine->descriptor.data(); + + short desID; + + /*Note that the first and last bands only have (lengthOfLSP * widthOfBand_ * 2.0) pixels + * which are counted. */ + float invN2 = 1.0 / ( params.widthOfBand_ * 2.0 ); + float invN3 = 1.0 / ( params.widthOfBand_ * 3.0 ); + float invN, temp; + for ( bandID = 0; bandID < NUM_OF_BANDS; bandID++ ) + { + if( bandID == 0 || bandID == NUM_OF_BANDS - 1 ) + { + invN = invN2; + } + else + { + invN = invN3; + } + desID = bandID * 8; + temp = pgdLBandSum[bandID] * invN; + desVec[desID] = temp;/* mean value of pgdL; */ + desVec[desID + 4] = sqrt( pgdL2BandSum[bandID] * invN - temp * temp ); //std value of pgdL; + temp = ngdLBandSum[bandID] * invN; + desVec[desID + 1] = temp; //mean value of ngdL; + desVec[desID + 5] = sqrt( ngdL2BandSum[bandID] * invN - temp * temp ); //std value of ngdL; + + temp = pgdOBandSum[bandID] * invN; + desVec[desID + 2] = temp; //mean value of pgdO; + desVec[desID + 6] = sqrt( pgdO2BandSum[bandID] * invN - temp * temp ); //std value of pgdO; + temp = ngdOBandSum[bandID] * invN; + desVec[desID + 3] = temp; //mean value of ngdO; + desVec[desID + 7] = sqrt( ngdO2BandSum[bandID] * invN - temp * temp ); //std value of ngdO; + } + + // normalize; + float tempM, tempS; + tempM = 0; + tempS = 0; + desVec = pSingleLine->descriptor.data(); + + int base = 0; + for ( short i = 0; i < NUM_OF_BANDS * 8; ++base, i = base * 8 ) + { + tempM += * ( desVec + i ) * * ( desVec + i ); //desVec[8*i+0] * desVec[8*i+0]; + tempM += * ( desVec + i + 1 ) * * ( desVec + i + 1 ); //desVec[8*i+1] * desVec[8*i+1]; + tempM += * ( desVec + i + 2 ) * * ( desVec + i + 2 ); //desVec[8*i+2] * desVec[8*i+2]; + tempM += * ( desVec + i + 3 ) * * ( desVec + i + 3 ); //desVec[8*i+3] * desVec[8*i+3]; + tempS += * ( desVec + i + 4 ) * * ( desVec + i + 4 ); //desVec[8*i+4] * desVec[8*i+4]; + tempS += * ( desVec + i + 5 ) * * ( desVec + i + 5 ); //desVec[8*i+5] * desVec[8*i+5]; + tempS += * ( desVec + i + 6 ) * * ( desVec + i + 6 ); //desVec[8*i+6] * desVec[8*i+6]; + tempS += * ( desVec + i + 7 ) * * ( desVec + i + 7 ); //desVec[8*i+7] * desVec[8*i+7]; + } + + tempM = 1 / sqrt( tempM ); + tempS = 1 / sqrt( tempS ); + desVec = pSingleLine->descriptor.data(); + base = 0; + for ( short i = 0; i < NUM_OF_BANDS * 8; ++base, i = base * 8 ) + { + * ( desVec + i ) = * ( desVec + i ) * tempM; //desVec[8*i] = desVec[8*i] * tempM; + * ( desVec + 1 + i ) = * ( desVec + 1 + i ) * tempM; //desVec[8*i+1] = desVec[8*i+1] * tempM; + * ( desVec + 2 + i ) = * ( desVec + 2 + i ) * tempM; //desVec[8*i+2] = desVec[8*i+2] * tempM; + * ( desVec + 3 + i ) = * ( desVec + 3 + i ) * tempM; //desVec[8*i+3] = desVec[8*i+3] * tempM; + * ( desVec + 4 + i ) = * ( desVec + 4 + i ) * tempS; //desVec[8*i+4] = desVec[8*i+4] * tempS; + * ( desVec + 5 + i ) = * ( desVec + 5 + i ) * tempS; //desVec[8*i+5] = desVec[8*i+5] * tempS; + * ( desVec + 6 + i ) = * ( desVec + 6 + i ) * tempS; //desVec[8*i+6] = desVec[8*i+6] * tempS; + * ( desVec + 7 + i ) = * ( desVec + 7 + i ) * tempS; //desVec[8*i+7] = desVec[8*i+7] * tempS; + } + + /* In order to reduce the influence of non-linear illumination, + * a threshold is used to limit the value of element in the unit feature + * vector no larger than this threshold. In Z.Wang's work, a value of 0.4 is found + * empirically to be a proper threshold.*/ + desVec = pSingleLine->descriptor.data(); + for ( short i = 0; i < descriptor_size; i++ ) + { + if( desVec[i] > 0.4 ) + { + desVec[i] = 0.4; + } + } + + //re-normalize desVec; + temp = 0; + for ( short i = 0; i < descriptor_size; i++ ) + { + temp += desVec[i] * desVec[i]; + } + + temp = 1 / sqrt( temp ); + for ( short i = 0; i < descriptor_size; i++ ) + { + desVec[i] = desVec[i] * temp; + } + }/* end for(short lineIDInSameLine = 0; lineIDInSameLinesetK(1); - /* add new descriptors to dataset, if needed */ train(); + /* set number of requested matches to return for each query */ + dataset->setK(1); + /* prepare structures for query */ UINT32 *results = new UINT32[queryDescriptors.rows]; UINT32 * numres = new UINT32[(256+1)*(queryDescriptors.rows)]; @@ -314,12 +355,12 @@ void BinaryDescriptorMatcher::knnMatch( const Mat& queryDescriptors, return; } - /* set number of requested matches to return for each query */ - dataset->setK(k); - /* add new descriptors to dataset, if needed */ train(); + /* set number of requested matches to return for each query */ + dataset->setK(k); + /* prepare structures for query */ UINT32 *results = new UINT32[k*queryDescriptors.rows]; UINT32 * numres = new UINT32[(256+1)*(queryDescriptors.rows)]; diff --git a/modules/line_descriptor/src/bucket_group.cpp b/modules/line_descriptor/src/bucket_group.cpp index 52e296711..748d8d135 100644 --- a/modules/line_descriptor/src/bucket_group.cpp +++ b/modules/line_descriptor/src/bucket_group.cpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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*/ + #include "precomp.hpp" /* constructor */ diff --git a/modules/line_descriptor/src/draw.cpp b/modules/line_descriptor/src/draw.cpp index 3a0b89e77..71e60d511 100644 --- a/modules/line_descriptor/src/draw.cpp +++ b/modules/line_descriptor/src/draw.cpp @@ -1,3 +1,44 @@ +/*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*/ + #include "precomp.hpp" namespace cv diff --git a/modules/line_descriptor/src/line_descriptor_init.cpp b/modules/line_descriptor/src/line_descriptor_init.cpp index a2b10aabf..0fb5eb0c2 100644 --- a/modules/line_descriptor/src/line_descriptor_init.cpp +++ b/modules/line_descriptor/src/line_descriptor_init.cpp @@ -10,7 +10,7 @@ // License Agreement // For Open Source Computer Vision Library // - // Copyright (C) 2013, OpenCV Foundation, all rights reserved. + // 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, diff --git a/modules/line_descriptor/src/line_descriptor_init.cpp~ b/modules/line_descriptor/src/line_descriptor_init.cpp~ deleted file mode 100644 index 4d55c3512..000000000 --- a/modules/line_descriptor/src/line_descriptor_init.cpp~ +++ /dev/null @@ -1,61 +0,0 @@ -/*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) 2013, OpenCV Foundation, 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*/ - -#include "precomp.hpp" -#include "opencv2/tracking.hpp" - -namespace cv -{ - -CV_INIT_ALGORITHM(EDLineDetector, "EDLINEDETECTOR",); - -CV_INIT_ALGORITHM(LineDescriptor, "LINEDESCRIPTOR",); - -bool initModule_tracking(void) -{ - bool all = true; - all &= !EDLineDetector_info_auto.name().empty(); - all &= !LineDescriptor_info_auto.name().empty(); - - return all; -} - -} diff --git a/modules/line_descriptor/src/mihasher.cpp b/modules/line_descriptor/src/mihasher.cpp index 55d448d44..e6c2472fb 100644 --- a/modules/line_descriptor/src/mihasher.cpp +++ b/modules/line_descriptor/src/mihasher.cpp @@ -1,3 +1,45 @@ +/*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, Mohammad Norouzi, Ali Punjani, David J. Fleet, + // 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*/ + #include "precomp.hpp" @@ -22,7 +64,7 @@ void Mihasher::batchquery(UINT32 * results, UINT32 *numres, const cv::Mat & quer /* loop over number of descriptors */ for (size_t i=0; i MAX_B || b > sizeof(UINT64)*8) + if (b < 5 || b > MAX_B || b > (int)(sizeof(UINT64)*8)) return 1; size = UINT64_1 << (b-5); // size = 2 ^ b table = (BucketGroup*) calloc(size, sizeof(BucketGroup)); return 0; + } /* destructor */