Commit b4edf34f authored by Vadim Pisarevsky's avatar Vadim Pisarevsky

Merge pull request #38 from ubisum/line_descriptor_module

Line descriptor module
parents 71c98af0 c28417c8
set(the_description "Line descriptor")
ocv_define_module(line_descriptor opencv_features2d opencv_imgproc opencv_optim)
.. _LSDDetector:
Line Segments Detector
======================
Lines extraction methodology
----------------------------
The lines extraction methodology described in the following is mainly based on [EDLN]_.
The extraction starts with a Gaussian pyramid generated from an original image, downsampled N-1 times, blurred N times, to obtain N layers (one for each octave), with layer 0 corresponding to input image. Then, from each layer (octave) in the pyramid, lines are extracted using LSD algorithm.
Differently from EDLine lines extractor used in original article, LSD furnishes information only about lines extremes; thus, additional information regarding slope and equation of line are computed via analytic methods. The number of pixels is obtained using *LineIterator*. Extracted lines are returned in the form of KeyLine objects, but since extraction is based on a method different from the one used in *BinaryDescriptor* class, data associated to a line's extremes in original image and in octave it was extracted from, coincide. KeyLine's field *class_id* is used as an index to indicate the order of extraction of a line inside a single octave.
LSDDetector::createLSDDetector
------------------------------
Creates ad LSDDetector object, using smart pointers.
.. ocv:function:: Ptr<LSDDetector> LSDDetector::createLSDDetector()
LSDDetector::detect
-------------------
Detect lines inside an image.
.. ocv:function:: void LSDDetector::detect( const Mat& image, std::vector<KeyLine>& keylines, int scale, int numOctaves, const Mat& mask=Mat())
.. ocv:function:: void LSDDetector::detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves, const std::vector<Mat>& masks=std::vector<Mat>() ) const
:param image: input image
:param images: input images
:param keylines: vector or set of vectors that will store extracted lines for one or more images
:param mask: mask matrix to detect only KeyLines of interest
:param masks: vector of mask matrices to detect only KeyLines of interest from each input image
:param scale: scale factor used in pyramids generation
:param numOctaves: number of octaves inside pyramid
References
----------
.. [EDLN] Von Gioi, R. Grompone, et al. *LSD: A fast line segment detector with a false detection control*, IEEE Transactions on Pattern Analysis and Machine Intelligence 32.4 (2010): 722-732.
.. _binary_descriptor:
BinaryDescriptor Class
======================
.. highlight:: cpp
BinaryDescriptor Class implements both functionalities for detection of lines and computation of their binary descriptor. Class' interface is mainly based on the ones of classical detectors and extractors, such as Feature2d's `FeatureDetector <http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_feature_detectors.html?highlight=featuredetector#featuredetector>`_ and `DescriptorExtractor <http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_extractors.html?highlight=extractor#DescriptorExtractor : public Algorithm>`_.
Retrieved information about lines is stored in *KeyLine* objects.
BinaryDescriptor::Params
-----------------------------------------------------------------------
.. ocv:struct:: BinaryDescriptor::Params
List of BinaryDescriptor parameters::
struct CV_EXPORTS_W_SIMPLE Params{
CV_WRAP Params();
/* the number of image octaves (default = 1) */
CV_PROP_RW int numOfOctave_;
/* the width of band; (default = 7) */
CV_PROP_RW int widthOfBand_;
/* image's reduction ratio in construction of Gaussian pyramids (default = 2) */
CV_PROP_RW int reductionRatio;
/* read parameters from a FileNode object and store them (struct function) */
void read( const FileNode& fn );
/* store parameters to a FileStorage object (struct function) */
void write( FileStorage& fs ) const;
};
BinaryDescriptor::BinaryDescriptor
----------------------------------
Constructor
.. ocv:function:: bool BinaryDescriptor::BinaryDescriptor( const BinaryDescriptor::Params &parameters = BinaryDescriptor::Params() )
:param parameters: configuration parameters :ocv:struct:`BinaryDescriptor::Params`
If no argument is provided, constructor sets default values (see comments in the code snippet in previous section). Default values are strongly reccomended.
BinaryDescriptor::getNumOfOctaves
---------------------------------
Get current number of octaves
.. ocv:function:: int BinaryDescriptor::getNumOfOctaves()
BinaryDescriptor::setNumOfOctaves
---------------------------------
Set number of octaves
.. ocv:function:: void BinaryDescriptor::setNumOfOctaves( int octaves )
:param octaves: number of octaves
BinaryDescriptor::getWidthOfBand
--------------------------------
Get current width of bands
.. ocv:function:: int BinaryDescriptor::getWidthOfBand()
BinaryDescriptor::setWidthOfBand
--------------------------------
Set width of bands
.. ocv:function:: void BinaryDescriptor::setWidthOfBand( int width )
:param width: width of bands
BinaryDescriptor::getReductionRatio
-----------------------------------
Get current reduction ratio (used in Gaussian pyramids)
.. ocv:function:: int BinaryDescriptor::getReductionRatio()
BinaryDescriptor::setReductionRatio
-----------------------------------
Set reduction ratio (used in Gaussian pyramids)
.. ocv:function:: void BinaryDescriptor::setReductionRatio( int rRatio )
:param rRatio: reduction ratio
BinaryDescriptor::createBinaryDescriptor
----------------------------------------
Create a BinaryDescriptor object with default parameters (or with the ones provided) and return a smart pointer to it
.. ocv:function:: Ptr<BinaryDescriptor> BinaryDescriptor::createBinaryDescriptor()
.. ocv:function:: Ptr<BinaryDescriptor> BinaryDescriptor::createBinaryDescriptor( Params parameters )
BinaryDescriptor::operator()
----------------------------
Define operator '()' to perform detection of KeyLines and computation of descriptors in a row.
.. ocv:function:: void BinaryDescriptor::operator()( InputArray image, InputArray mask, vector<KeyLine>& keylines, OutputArray descriptors, bool useProvidedKeyLines=false, bool returnFloatDescr ) const
:param image: input image
:param mask: mask matrix to select which lines in KeyLines must be accepted among the ones extracted (used when *keylines* is not empty)
:param keylines: vector that contains input lines (when filled, the detection part will be skipped and input lines will be passed as input to the algorithm computing descriptors)
:param descriptors: matrix that will store final descriptors
:param useProvidedKeyLines: flag (when set to true, detection phase will be skipped and only computation of descriptors will be executed, using lines provided in *keylines*)
:param returnFloatDescr: flag (when set to true, original non-binary descriptors are returned)
BinaryDescriptor::read
----------------------
Read parameters from a FileNode object and store them
.. ocv:function:: void BinaryDescriptor::read( const FileNode& fn )
:param fn: source FileNode file
BinaryDescriptor::write
-----------------------
Store parameters to a FileStorage object
.. ocv:function:: void BinaryDescriptor::write( FileStorage& fs ) const
:param fs: output FileStorage file
BinaryDescriptor::defaultNorm
-----------------------------
Return norm mode
.. ocv:function:: int BinaryDescriptor::defaultNorm() const
BinaryDescriptor::descriptorType
--------------------------------
Return data type
.. ocv:function:: int BinaryDescriptor::descriptorType() const
BinaryDescriptor::descriptorSize
--------------------------------
Return descriptor size
.. ocv:function:: int BinaryDescriptor::descriptorSize() const
BinaryDescriptor::detect
------------------------
Requires line detection (for one or more images)
.. ocv:function:: void detect( const Mat& image, vector<KeyLine>& keylines, Mat& mask=Mat() )
.. ocv:function:: void detect( const vector<Mat>& images, vector<vector<KeyLine> >& keylines, vector<Mat>& masks=vector<Mat>() ) const
:param image: input image
:param images: input images
:param keylines: vector or set of vectors that will store extracted lines for one or more images
:param mask: mask matrix to detect only KeyLines of interest
:param masks: vector of mask matrices to detect only KeyLines of interest from each input image
BinaryDescriptor::compute
-------------------------
Requires descriptors computation (for one or more images)
.. ocv:function:: void compute( const Mat& image, vector<KeyLine>& keylines, Mat& descriptors, bool returnFloatDescr ) const
.. ocv:function:: void compute( const vector<Mat>& images, vector<vector<KeyLine> >& keylines, vector<Mat>& descriptors, bool returnFloatDescr ) const
:param image: input image
:param images: input images
:param keylines: vector or set of vectors containing lines for which descriptors must be computed
:param mask: mask to select for which lines, among the ones provided in input, descriptors must be computed
:param masks: set of masks to select for which lines, among the ones provided in input, descriptors must be computed
:param returnFloatDescr: flag (when set to true, original non-binary descriptors are returned)
Related pages
-------------
* :ref:`line_descriptor`
* :ref:`matching`
* :ref:`drawing`
.. _drawing:
Drawing Functions for Keylines and Matches
==========================================
.. highlight:: cpp
drawLineMatches
---------------
Draws the found matches of keylines from two images.
.. ocv:function:: void drawLineMatches( const Mat& img1, const std::vector<KeyLine>& keylines1, const Mat& img2, const std::vector<KeyLine>& keylines2, const std::vector<DMatch>& matches1to2, Mat& outImg, const Scalar& matchColor=Scalar::all(-1), const Scalar& singleLineColor=Scalar::all(-1), const std::vector<char>& matchesMask=std::vector<char>(), int flags=DrawLinesMatchesFlags::DEFAULT )
:param img1: first image
:param keylines1: keylines extracted from first image
:param img2: second image
:param keylines2: keylines extracted from second image
:param matches1to2: vector of matches
:param outImg: output matrix to draw on
:param matchColor: drawing color for matches (chosen randomly in case of default value)
:param singleLineColor: drawing color for keylines (chosen randomly in case of default value)
:param matchesMask: mask to indicate which matches must be drawn
:param flags: drawing flags
.. note:: If both *matchColor* and *singleLineColor* are set to their default values, function draws matched lines and line connecting them with same color
The structure of drawing flags is shown in the following:
.. code-block:: cpp
/* struct for drawing options */
struct CV_EXPORTS DrawLinesMatchesFlags
{
enum
{
DEFAULT = 0, // Output image matrix will be created (Mat::create),
// i.e. existing memory of output image may be reused.
// Two source images, matches, and single keylines
// will be drawn.
DRAW_OVER_OUTIMG = 1, // Output image matrix will not be
// created (using Mat::create). Matches will be drawn
// on existing content of output image.
NOT_DRAW_SINGLE_LINES = 2 // Single keylines will not be drawn.
};
};
..
drawKeylines
------------
Draws keylines.
.. ocv:function:: void drawKeylines( const Mat& image, const std::vector<KeyLine>& keylines, Mat& outImage, const Scalar& color=Scalar::all(-1), int flags=DrawLinesMatchesFlags::DEFAULT )
:param image: input image
:param keylines: keylines to be drawn
:param outImage: output image to draw on
:param color: color of lines to be drawn (if set to defaul value, color is chosen randomly)
:param flags: drawing flags
Related pages
-------------
* :ref:`line_descriptor`
* :ref:`binary_descriptor`
* :ref:`matching`
.. _line_descriptor:
Binary descriptors for lines extracted from an image
====================================================
.. highlight:: cpp
Introduction
------------
One of the most challenging activities in computer vision is the extraction of useful information from a given image. Such information, usually comes in the form of points that preserve some kind of property (for instance, they are scale-invariant) and are actually representative of input image.
The goal of this module is seeking a new kind of representative information inside an image and providing the functionalities for its extraction and representation. In particular, differently from previous methods for detection of relevant elements inside an image, lines are extracted in place of points; a new class is defined ad hoc to summarize a line's properties, for reuse and plotting purposes.
A class to represent a line: KeyLine
------------------------------------
As aformentioned, it is been necessary to design a class that fully stores the information needed to characterize completely a line and plot it on image it was extracted from, when required.
*KeyLine* class has been created for such goal; it is mainly inspired to Feature2d's KeyPoint class, since KeyLine shares some of *KeyPoint*'s fields, even if a part of them assumes a different meaning, when speaking about lines.
In particular:
* the *class_id* field is used to gather lines extracted from different octaves which refer to same line inside original image (such lines and the one they represent in original image share the same *class_id* value)
* the *angle* field represents line's slope with respect to (positive) X axis
* the *pt* field represents line's midpoint
* the *response* field is computed as the ratio between the line's length and maximum between image's width and height
* the *size* field is the area of the smallest rectangle containing line
Apart from fields inspired to KeyPoint class, KeyLines stores information about extremes of line in original image and in octave it was extracted from, about line's length and number of pixels it covers. Code relative to KeyLine class is reported in the following snippet:
.. ocv:class:: KeyLine
::
class CV_EXPORTS_W KeyLine
{
public:
/* orientation of the line */
float angle;
/* object ID, that can be used to cluster keylines by the line they represent */
int class_id;
/* octave (pyramid layer), from which the keyline has been extracted */
int octave;
/* coordinates of the middlepoint */
Point pt;
/* the response, by which the strongest keylines have been selected.
It's represented by the ratio between line's length and maximum between
image's width and height */
float response;
/* minimum area containing line */
float size;
/* lines's extremes in original image */
float startPointX;
float startPointY;
float endPointX;
float endPointY;
/* line's extremes in image it was extracted from */
float sPointInOctaveX;
float sPointInOctaveY;
float ePointInOctaveX;
float ePointInOctaveY;
/* the length of line */
float lineLength;
/* number of pixels covered by the line */
unsigned int numOfPixels;
/* constructor */
KeyLine(){}
};
Computation of binary descriptors
---------------------------------
To obtatin a binary descriptor representing a certain line detected from a certain octave of an image, we first compute a non-binary descriptor as described in [LBD]_. Such algorithm works on lines extracted using EDLine detector, as explained in [EDL]_. Given a line, we consider a rectangular region centered at it and called *line support region (LSR)*. Such region is divided into a set of bands :math:`\{B_1, B_2, ..., B_m\}`, whose length equals the one of line.
If we indicate with :math:`\bf{d}_L` the direction of line, the orthogonal and clockwise direction to line :math:`\bf{d}_{\perp}` can be determined; these two directions, are used to construct a reference frame centered in the middle point of line. The gradients of pixels :math:`\bf{g'}` inside LSR can be projected to the newly determined frame, obtaining their local equivalent :math:`\bf{g'} = (\bf{g}^T \cdot \bf{d}_{\perp}, \bf{g}^T \cdot \bf{d}_L)^T \triangleq (\bf{g'}_{d_{\perp}}, \bf{g'}_{d_L})^T`.
Later on, a Gaussian function is applied to all LSR's pixels along :math:`\bf{d}_\perp` direction; first, we assign a global weighting coefficient :math:`f_g(i) = (1/\sqrt{2\pi}\sigma_g)e^{-d^2_i/2\sigma^2_g}` to *i*-th row in LSR, where :math:`d_i` is the distance of *i*-th row from the center row in LSR, :math:`\sigma_g = 0.5(m \cdot w - 1)` and :math:`w` is the width of bands (the same for every band). Secondly, considering a band :math:`B_j` and its neighbor bands :math:`B_{j-1}, B_{j+1}`, we assign a local weighting :math:`F_l(k) = (1/\sqrt{2\pi}\sigma_l)e^{-d'^2_k/2\sigma_l^2}`, where :math:`d'_k` is the distance of *k*-th row from the center row in :math:`B_j` and :math:`\sigma_l = w`. Using the global and local weights, we obtain, at the same time, the reduction of role played by gradients far from line and of boundary effect, respectively.
Each band :math:`B_j` in LSR has an associated *band descriptor(BD)* which is computed considering previous and next band (top and bottom bands are ignored when computing descriptor for first and last band). Once each band has been assignen its BD, the LBD descriptor of line is simply given by
.. math::
LBD = (BD_1^T, BD_2^T, ... , BD^T_m)^T.
To compute a band descriptor :math:`B_j`, each *k*-th row in it is considered and the gradients in such row are accumulated:
.. math::
\begin{matrix} \bf{V1}^k_j = \lambda \sum\limits_{\bf{g}'_{d_\perp}>0}\bf{g}'_{d_\perp}, & \bf{V2}^k_j = \lambda \sum\limits_{\bf{g}'_{d_\perp}<0} -\bf{g}'_{d_\perp}, \\ \bf{V3}^k_j = \lambda \sum\limits_{\bf{g}'_{d_L}>0}\bf{g}'_{d_L}, & \bf{V4}^k_j = \lambda \sum\limits_{\bf{g}'_{d_L}<0} -\bf{g}'_{d_L}\end{matrix}.
with :math:`\lambda = f_g(k)f_l(k)`.
By stacking previous results, we obtain the *band description matrix (BDM)*
.. math::
BDM_j = \left(\begin{matrix} \bf{V1}_j^1 & \bf{V1}_j^2 & \ldots & \bf{V1}_j^n \\ \bf{V2}_j^1 & \bf{V2}_j^2 & \ldots & \bf{V2}_j^n \\ \bf{V3}_j^1 & \bf{V3}_j^2 & \ldots & \bf{V3}_j^n \\ \bf{V4}_j^1 & \bf{V4}_j^2 & \ldots & \bf{V4}_j^n \end{matrix} \right) \in \mathbb{R}^{4\times n},
with :math:`n` the number of rows in band :math:`B_j`:
.. math::
n = \begin{cases} 2w, & j = 1||m; \\ 3w, & \mbox{else}. \end{cases}
Each :math:`BD_j` can be obtained using the standard deviation vector :math:`S_j` and mean vector :math:`M_j` of :math:`BDM_J`. Thus, finally:
.. math::
LBD = (M_1^T, S_1^T, M_2^T, S_2^T, \ldots, M_m^T, S_m^T)^T \in \mathbb{R}^{8m}
Once the LBD has been obtained, it must be converted into a binary form. For such purpose, we consider 32 possible pairs of BD inside it; each couple of BD is compared bit by bit and comparison generates an 8 bit string. Concatenating 32 comparison strings, we get the 256-bit final binary representation of a single LBD.
References
----------
.. [LBD] Zhang, Lilian, and Reinhard Koch. *An efficient and robust line segment matching approach based on LBD descriptor and pairwise geometric consistency*, Journal of Visual Communication and Image Representation 24.7 (2013): 794-805.
.. [EDL] Von Gioi, R. Grompone, et al. *LSD: A fast line segment detector with a false detection control*, IEEE Transactions on Pattern Analysis and Machine Intelligence 32.4 (2010): 722-732.
Summary
-------
.. toctree::
:maxdepth: 2
binary_descriptor
LSDDetector
matching
drawing_functions
tutorial
.. _matching:
Matching with binary descriptors
================================
.. highlight:: cpp
Once descriptors have been extracted from an image (both they represent lines and points), it becomes interesting to be able to match a descriptor with another one extracted from a different image and representing the same line or point, seen from a differente perspective or on a different scale.
In reaching such goal, the main headache is designing an efficient search algorithm to associate a query descriptor to one extracted from a dataset.
In the following, a matching modality based on *Multi-Index Hashing (MiHashing)* will be described.
Multi-Index Hashing
-------------------
The theory described in this section is based on [MIH]_.
Given a dataset populated with binary codes, each code is indexed *m* times into *m* different hash tables, according to *m* substrings it has been divided into. Thus, given a query code, all the entries close to it at least in one substring are returned by search as *neighbor candidates*. Returned entries are then checked for validity by verifying that their full codes are not distant (in Hamming space) more than *r* bits from query code.
In details, each binary code **h** composed of *b* bits is divided into *m* disjoint substrings :math:`\mathbf{h}^{(1)}, ..., \mathbf{h}^{(m)}`, each with length :math:`\lfloor b/m \rfloor` or :math:`\lceil b/m \rceil` bits. Formally, when two codes **h** and **g** differ by at the most *r* bits, in at the least one of their *m* substrings they differ by at the most :math:`\lfloor r/m \rfloor` bits. In particular, when :math:`||\mathbf{h}-\mathbf{g}||_H \le r` (where :math:`||.||_H` is the Hamming norm), there must exist a substring *k* (with :math:`1 \le k \le m`) such that
.. math::
||\mathbf{h}^{(k)} - \mathbf{g}^{(k)}||_H \le \left\lfloor \frac{r}{m} \right\rfloor .
That means that if Hamming distance between each of the *m* substring is strictly greater than :math:`\lfloor r/m \rfloor`, then :math:`||\mathbf{h}-\mathbf{g}||_H` must be larger that *r* and that is a contradiction.
If the codes in dataset are divided into *m* substrings, then *m* tables will be built. Given a query **q** with substrings :math:`\{\mathbf{q}^{(i)}\}^m_{i=1}`, *i*-th hash table is searched for entries distant at the most :math:`\lfloor r/m \rfloor` from :math:`\mathbf{q}^{(i)}` and a set of candidates :math:`\mathcal{N}_i(\mathbf{q})` is obtained.
The union of sets :math:`\mathcal{N}(\mathbf{q}) = \bigcup_i \mathcal{N}_i(\mathbf{q})` is a superset of the *r*-neighbors of **q**. Then, last step of algorithm is computing the Hamming distance between **q** and each element in :math:`\mathcal{N}(\mathbf{q})`, deleting the codes that are distant more that *r* from **q**.
BinaryDescriptorMatcher Class
=============================
BinaryDescriptorMatcher Class furnishes all functionalities for querying a dataset provided by user or internal to class (that user must, anyway, populate) on the model of Feature2d's `DescriptorMatcher <http://docs.opencv.org/modules/features2d/doc/common_interfaces_of_descriptor_matchers.html?highlight=bfmatcher#descriptormatcher>`_.
BinaryDescriptorMatcher::BinaryDescriptorMatcher
--------------------------------------------------
Constructor.
.. ocv:function:: BinaryDescriptorMatcher::BinaryDescriptorMatcher()
The BinaryDescriptorMatcher constructed is able to store and manage 256-bits long entries.
BinaryDescriptorMatcher::createBinaryDescriptorMatcher
------------------------------------------------------
Create a BinaryDescriptorMatcher object and return a smart pointer to it.
.. ocv:function:: Ptr<BinaryDescriptorMatcher> BinaryDescriptorMatcher::createBinaryDescriptorMatcher()
BinaryDescriptorMatcher::add
----------------------------
Store locally new descriptors to be inserted in dataset, without updating dataset.
.. ocv:function:: void BinaryDescriptorMatcher::add( const std::vector<Mat>& descriptors )
:param descriptors: matrices containing descriptors to be inserted into dataset
.. note:: Each matrix *i* in **descriptors** should contain descriptors relative to lines extracted from *i*-th image.
BinaryDescriptorMatcher::train
------------------------------
Update dataset by inserting into it all descriptors that were stored locally by *add* function.
.. ocv:function:: void BinaryDescriptorMatcher::train()
.. note:: Every time this function is invoked, current dataset is deleted and locally stored descriptors are inserted into dataset. The locally stored copy of just inserted descriptors is then removed.
BinaryDescriptorMatcher::clear
------------------------------
Clear dataset and internal data
.. ocv:function:: void BinaryDescriptorMatcher::clear()
BinaryDescriptorMatcher::match
------------------------------
For every input query descriptor, retrieve the best matching one from a dataset provided from user or from the one internal to class
.. ocv:function:: void BinaryDescriptorMatcher::match( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<DMatch>& matches, const Mat& mask=Mat() ) const
.. ocv:function:: void BinaryDescriptorMatcher::match( const Mat& queryDescriptors, std::vector<DMatch>& matches, const std::vector<Mat>& masks=std::vector<Mat>() )
:param queryDescriptors: query descriptors
:param trainDescriptors: dataset of descriptors furnished by user
:param matches: vector to host retrieved matches
:param mask: mask to select which input descriptors must be matched to one in dataset
:param masks: vector of masks to select which input descriptors must be matched to one in dataset (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in dataset relative to *i*-th image)
BinaryDescriptorMatcher::knnMatch
---------------------------------
For every input query descriptor, retrieve the best *k* matching ones from a dataset provided from user or from the one internal to class
.. ocv:function:: void BinaryDescriptorMatcher::knnMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<std::vector<DMatch> >& matches, int k, const Mat& mask=Mat(), bool compactResult=false ) const
.. ocv:function:: void BinaryDescriptorMatcher::knnMatch( const Mat& queryDescriptors, std::vector<std::vector<DMatch> >& matches, int k, const std::vector<Mat>& masks=std::vector<Mat>(), bool compactResult=false )
:param queryDescriptors: query descriptors
:param trainDescriptors: dataset of descriptors furnished by user
:param matches: vector to host retrieved matches
:param k: number of the closest descriptors to be returned for every input query
:param mask: mask to select which input descriptors must be matched to ones in dataset
:param masks: vector of masks to select which input descriptors must be matched to ones in dataset (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in dataset relative to *i*-th image)
:param compactResult: flag to obtain a compact result (if true, a vector that doesn't contain any matches for a given query is not inserted in final result)
BinaryDescriptorMatcher::radiusMatch
------------------------------------
For every input query descriptor, retrieve, from a dataset provided from user or from the one internal to class, all the descriptors that are not further than *maxDist* from input query
.. ocv:function:: void BinaryDescriptorMatcher::radiusMatch( const Mat& queryDescriptors, const Mat& trainDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, const Mat& mask=Mat(), bool compactResult=false ) const
.. ocv:function:: void BinaryDescriptorMatcher::radiusMatch( const Mat& queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, const std::vector<Mat>& masks=std::vector<Mat>(), bool compactResult=false )
:param queryDescriptors: query descriptors
:param trainDescriptors: dataset of descriptors furnished by user
:param matches: vector to host retrieved matches
:param maxDist: search radius
:param mask: mask to select which input descriptors must be matched to ones in dataset
:param masks: vector of masks to select which input descriptors must be matched to ones in dataset (the *i*-th mask in vector indicates whether each input query can be matched with descriptors in dataset relative to *i*-th image)
:param compactResult: flag to obtain a compact result (if true, a vector that doesn't contain any matches for a given query is not inserted in final result)
Related pages
-------------
* :ref:`line_descriptor`
* :ref:`binary_descriptor`
* :ref:`drawing`
References
----------
.. [MIH] Norouzi, Mohammad, Ali Punjani, and David J. Fleet. *Fast search in hamming space with multi-index hashing*, Computer Vision and Pattern Recognition (CVPR), 2012 IEEE Conference on. IEEE, 2012.
This diff is collapsed.
/*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_LINE_DESCRIPTOR_HPP__
#define __OPENCV_LINE_DESCRIPTOR_HPP__
#include "opencv2/line_descriptor/descriptor.hpp"
namespace cv
{
CV_EXPORTS bool initModule_line_descriptor( void );
}
#endif
/*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 "perf_precomp.hpp"
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;
typedef perf::TestBaseWithParam<std::string> file_str;
#define IMAGES \
"line_descriptor_data/cameraman.jpg", "line_descriptor_data/lena.bmp"
PERF_TEST_P(file_str, descriptors, testing::Values(IMAGES))
{
std::string filename = getDataPath( GetParam() );
Mat frame = imread( filename, 1 );
if( frame.empty() )
FAIL()<< "Unable to load source image " << filename;
Mat descriptors;
std::vector<KeyLine> keylines;
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
TEST_CYCLE()
{
bd->detect( frame, keylines );
bd->compute( frame, keylines, descriptors );
}
SANITY_CHECK( descriptors );
}
/*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 "perf_precomp.hpp"
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;
typedef perf::TestBaseWithParam<std::string> file_str;
#define IMAGES \
"line_descriptor_data/cameraman.jpg", "line_descriptor_data/lena.bmp"
void createMatFromVec( const std::vector<KeyLine>& linesVec, Mat& output );
void createMatFromVec( const std::vector<KeyLine>& linesVec, Mat& output )
{
output = Mat( (int) linesVec.size(), 17, CV_32FC1 );
for ( int i = 0; i < (int) linesVec.size(); i++ )
{
std::vector<float> klData;
KeyLine kl = linesVec[i];
klData.push_back( kl.angle );
klData.push_back( (float) kl.class_id );
klData.push_back( kl.ePointInOctaveX );
klData.push_back( kl.ePointInOctaveY );
klData.push_back( kl.endPointX );
klData.push_back( kl.endPointY );
klData.push_back( kl.lineLength );
klData.push_back( (float) kl.numOfPixels );
klData.push_back( (float) kl.octave );
klData.push_back( kl.pt.x );
klData.push_back( kl.pt.y );
klData.push_back( kl.response );
klData.push_back( kl.sPointInOctaveX );
klData.push_back( kl.sPointInOctaveY );
klData.push_back( kl.size );
klData.push_back( kl.startPointX );
klData.push_back( kl.startPointY );
float* pointerToRow = output.ptr<float>( i );
for ( int j = 0; j < 17; j++ )
{
*pointerToRow = klData[j];
pointerToRow++;
}
}
}
PERF_TEST_P(file_str, detect, testing::Values(IMAGES))
{
std::string filename = getDataPath( GetParam() );
Mat frame = imread( filename, 1 );
if( frame.empty() )
FAIL()<< "Unable to load source image " << filename;
Mat lines;
std::vector<KeyLine> keylines;
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
TEST_CYCLE()
{
bd->detect( frame, keylines );
createMatFromVec( keylines, lines );
}
SANITY_CHECK( lines );
}
PERF_TEST_P(file_str, detect_lsd, testing::Values(IMAGES))
{
std::string filename = getDataPath( GetParam() );
std::cout << filename.c_str() << std::endl;
Mat frame = imread( filename, 1 );
if( frame.empty() )
FAIL()<< "Unable to load source image " << filename;
Mat lines;
std::vector<KeyLine> keylines;
Ptr<LSDDetector> lsd = LSDDetector::createLSDDetector();
TEST_CYCLE()
{
lsd->detect( frame, keylines, 2, 1 );
createMatFromVec( keylines, lines );
}
SANITY_CHECK( lines );
}
/*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 "perf_precomp.hpp"
CV_PERF_TEST_MAIN( line_descriptor )
/*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 "perf_precomp.hpp"
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;
#define QUERY_DES_COUNT 300
#define DIM 32
#define COUNT_FACTOR 4
#define RADIUS 3
void generateData( Mat& query, Mat& train );
uchar invertSingleBits( uchar dividend_char, int numBits );
/* invert numBits bits in input char */
uchar invertSingleBits( uchar dividend_char, int numBits )
{
std::vector<int> bin_vector;
long dividend;
long bin_num;
/* convert input char to a long */
dividend = (long) dividend_char;
/*if a 0 has been obtained, just generate a 8-bit long vector of zeros */
if( dividend == 0 )
bin_vector = std::vector<int>( 8, 0 );
/* else, apply classic decimal to binary conversion */
else
{
while ( dividend >= 1 )
{
bin_num = dividend % 2;
dividend /= 2;
bin_vector.push_back( bin_num );
}
}
/* ensure that binary vector always has length 8 */
if( bin_vector.size() < 8 )
{
std::vector<int> zeros( 8 - bin_vector.size(), 0 );
bin_vector.insert( bin_vector.end(), zeros.begin(), zeros.end() );
}
/* invert numBits bits */
for ( int index = 0; index < numBits; index++ )
{
if( bin_vector[index] == 0 )
bin_vector[index] = 1;
else
bin_vector[index] = 0;
}
/* reconvert to decimal */
uchar result = 0;
for ( int i = (int) bin_vector.size() - 1; i >= 0; i-- )
result += (uchar) ( bin_vector[i] * pow( 2, i ) );
return result;
}
void generateData( Mat& query, Mat& train )
{
RNG& rng = theRNG();
Mat buf( QUERY_DES_COUNT, DIM, CV_8UC1 );
rng.fill( buf, RNG::UNIFORM, Scalar( 0 ), Scalar( 255 ) );
buf.convertTo( query, CV_8UC1 );
for ( int i = 0; i < query.rows; i++ )
{
for ( int j = 0; j < COUNT_FACTOR; j++ )
{
train.push_back( query.row( i ) );
int randCol = rand() % 32;
uchar u = query.at<uchar>( i, randCol );
uchar modified_u = invertSingleBits( u, j + 1 );
train.at<uchar>( i * COUNT_FACTOR + j, randCol ) = modified_u;
}
}
}
PERF_TEST(matching, single_match)
{
Mat query, train;
std::vector<DMatch> dm;
Ptr<BinaryDescriptorMatcher> bd = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
generateData( query, train );
TEST_CYCLE()
bd->match( query, train, dm );
SANITY_CHECK_MATCHES( dm );
}
PERF_TEST(knn_matching, knn_match_distances_test)
{
Mat query, train, distances;
std::vector<std::vector<DMatch> > dm;
Ptr<BinaryDescriptorMatcher> bd = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
generateData( query, train );
TEST_CYCLE()
{
bd->knnMatch( query, train, dm, QUERY_DES_COUNT );
for ( int i = 0; i < (int) dm.size(); i++ )
{
for ( int j = 0; j < (int) dm[i].size(); j++ )
distances.push_back( dm[i][j].distance );
}
}
SANITY_CHECK( distances );
}
PERF_TEST(radius_match, radius_match_distances_test)
{
Mat query, train, distances;
std::vector<std::vector<DMatch> > dm;
Ptr<BinaryDescriptorMatcher> bd = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
generateData( query, train );
TEST_CYCLE()
{
bd->radiusMatch( query, train, dm, RADIUS );
for ( int i = 0; i < (int) dm.size(); i++ )
{
for ( int j = 0; j < (int) dm[i].size(); j++ )
distances.push_back( dm[i][j].distance );
}
}
SANITY_CHECK( distances );
}
/*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*/
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_PERF_PRECOMP_HPP__
#define __OPENCV_PERF_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/line_descriptor.hpp"
#ifdef GTEST_CREATE_SHARED_LIBRARY
#error no modules except ts should have GTEST_CREATE_SHARED_LIBRARY defined
#endif
#endif
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace cv::line_descriptor;
static const char* keys =
{ "{@image_path | | Image path }" };
static void help()
{
std::cout << "\nThis example shows the functionalities of lines extraction " << "and descriptors computation furnished by BinaryDescriptor class\n"
<< "Please, run this sample using a command in the form\n" << "./example_line_descriptor_compute_descriptors <path_to_input_image>"
<< std::endl;
}
int main( int argc, char** argv )
{
/* get parameters from command line */
CommandLineParser parser( argc, argv, keys );
String image_path = parser.get<String>( 0 );
if( image_path.empty() )
{
help();
return -1;
}
/* load image */
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;
}
/* create a binary mask */
cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with default parameters */
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
/* compute lines */
std::vector<KeyLine> keylines;
bd->detect( imageMat, keylines, mask );
/* compute descriptors */
cv::Mat descriptors;
bd->compute( imageMat, keylines, descriptors);
}
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <vector>
#include <time.h>
using namespace cv;
using namespace cv::line_descriptor;
static const char* keys =
{ "{@image_path1 | | Image path 1 }"
"{@image_path2 | | Image path 2 }" };
static void help()
{
std::cout << "\nThis example shows the functionalities of descriptors matching\n" << "Please, run this sample using a command in the form\n"
<< "./example_line_descriptor_matching <path_to_input_image 1>" << "<path_to_input_image 2>" << std::endl;
}
uchar invertSingleBits( uchar dividend_char, int numBits );
/* invert numBits bits in input char */
uchar invertSingleBits( uchar dividend_char, int numBits )
{
std::vector<int> bin_vector;
long dividend;
long bin_num;
/* convert input char to a long */
dividend = (long) dividend_char;
/*if a 0 has been obtained, just generate a 8-bit long vector of zeros */
if( dividend == 0 )
bin_vector = std::vector<int>( 8, 0 );
/* else, apply classic decimal to binary conversion */
else
{
while ( dividend >= 1 )
{
bin_num = dividend % 2;
dividend /= 2;
bin_vector.push_back( bin_num );
}
}
/* ensure that binary vector always has length 8 */
if( bin_vector.size() < 8 )
{
std::vector<int> zeros( 8 - bin_vector.size(), 0 );
bin_vector.insert( bin_vector.end(), zeros.begin(), zeros.end() );
}
/* invert numBits bits */
for ( int index = 0; index < numBits; index++ )
{
if( bin_vector[index] == 0 )
bin_vector[index] = 1;
else
bin_vector[index] = 0;
}
/* reconvert to decimal */
uchar result = 0;
for ( int i = (int) bin_vector.size() - 1; i >= 0; i-- )
result += (uchar) ( bin_vector[i] * pow( 2, i ) );
return result;
}
int main( int argc, char** argv )
{
/* get parameters from comand line */
CommandLineParser parser( argc, argv, keys );
String image_path1 = parser.get<String>( 0 );
String image_path2 = parser.get<String>( 1 );
if( image_path1.empty() || image_path2.empty() )
{
help();
return -1;
}
/* load image */
cv::Mat imageMat1 = imread( image_path1, 1 );
cv::Mat imageMat2 = imread( image_path2, 1 );
if( imageMat1.data == NULL || imageMat2.data == NULL )
{
std::cout << "Error, images could not be loaded. Please, check their paths" << std::endl;
}
/* create binary masks */
cv::Mat mask1 = Mat::ones( imageMat1.size(), CV_8UC1 );
cv::Mat mask2 = Mat::ones( imageMat2.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with default parameters */
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
/* compute lines */
std::vector<KeyLine> keylines1, keylines2;
bd->detect( imageMat1, keylines1, mask1 );
bd->detect( imageMat2, keylines2, mask2 );
/* compute descriptors */
cv::Mat descr1, descr2;
bd->compute( imageMat1, keylines1, descr1 );
bd->compute( imageMat2, keylines2, descr2 );
/* create a BinaryDescriptorMatcher object */
Ptr<BinaryDescriptorMatcher> bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
/* make a copy of descr2 mat */
Mat descr2Copy = descr1.clone();
/* randomly change some bits in original descriptors */
srand( (unsigned int) time( NULL ) );
for ( int j = 0; j < descr1.rows; j++ )
{
/* select a random column */
int randCol = rand() % 32;
/* get correspondent data */
uchar u = descr1.at<uchar>( j, randCol );
/* change bits */
for ( int k = 1; k <= 5; k++ )
{
/* copy current row to train matrix */
descr2Copy.push_back( descr1.row( j ) );
/* invert k bits */
uchar uc = invertSingleBits( u, k );
/* update current row in train matrix */
descr2Copy.at<uchar>( descr2Copy.rows - 1, randCol ) = uc;
}
}
/* prepare a structure to host matches */
std::vector<std::vector<DMatch> > matches;
/* require knn match */
bdm->knnMatch( descr1, descr2, matches, 6 );
}
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
static const char* keys =
{ "{@image_path | | Image path }" };
static void help()
{
cout << "\nThis example shows the functionalities of lines extraction " << "furnished by BinaryDescriptor class\n"
<< "Please, run this sample using a command in the form\n" << "./example_line_descriptor_lines_extraction <path_to_input_image>" << endl;
}
int main( int argc, char** argv )
{
/* get parameters from comand line */
CommandLineParser parser( argc, argv, keys );
String image_path = parser.get<String>( 0 );
if( image_path.empty() )
{
help();
return -1;
}
/* load image */
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;
return -1;
}
/* create a random binary mask */
cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with deafult parameters */
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor();
/* create a structure to store extracted lines */
vector<KeyLine> lines;
/* extract lines */
cv::Mat output = imageMat.clone();
bd->detect( imageMat, lines, mask );
/* draw lines extracted from octave 0 */
if( output.channels() == 1 )
cvtColor( output, output, COLOR_GRAY2BGR );
for ( size_t i = 0; i < lines.size(); i++ )
{
KeyLine kl = lines[i];
if( kl.octave == 0)
{
/* get a random color */
int R = ( rand() % (int) ( 255 + 1 ) );
int G = ( rand() % (int) ( 255 + 1 ) );
int B = ( rand() % (int) ( 255 + 1 ) );
/* get extremes of line */
Point pt1 = Point2f( kl.startPointX, kl.startPointY );
Point pt2 = Point2f( kl.endPointX, kl.endPointY );
/* draw line */
line( output, pt1, pt2, Scalar( B, G, R ), 3 );
}
}
/* show lines on image */
imshow( "Lines", output );
waitKey();
}
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace cv::line_descriptor;
using namespace std;
static const char* keys =
{ "{@image_path | | Image path }" };
static void help()
{
cout << "\nThis example shows the functionalities of lines extraction " << "furnished by BinaryDescriptor class\n"
<< "Please, run this sample using a command in the form\n" << "./example_line_descriptor_lines_extraction <path_to_input_image>" << endl;
}
int main( int argc, char** argv )
{
/* get parameters from comand line */
CommandLineParser parser( argc, argv, keys );
String image_path = parser.get<String>( 0 );
if( image_path.empty() )
{
help();
return -1;
}
/* load image */
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;
return -1;
}
/* create a random binary mask */
cv::Mat mask = Mat::ones( imageMat.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with deafult parameters */
Ptr<LSDDetector> bd = LSDDetector::createLSDDetector();
/* create a structure to store extracted lines */
vector<KeyLine> lines;
/* extract lines */
cv::Mat output = imageMat.clone();
bd->detect( imageMat, lines, 2, 1, mask );
/* draw lines extracted from octave 0 */
if( output.channels() == 1 )
cvtColor( output, output, COLOR_GRAY2BGR );
for ( size_t i = 0; i < lines.size(); i++ )
{
KeyLine kl = lines[i];
if( kl.octave == 0)
{
/* get a random color */
int R = ( rand() % (int) ( 255 + 1 ) );
int G = ( rand() % (int) ( 255 + 1 ) );
int B = ( rand() % (int) ( 255 + 1 ) );
/* get extremes of line */
Point pt1 = Point2f( kl.startPointX, kl.startPointY );
Point pt2 = Point2f( kl.endPointX, kl.endPointY );
/* draw line */
line( output, pt1, pt2, Scalar( B, G, R ), 3 );
}
}
/* show lines on image */
imshow( "LSD lines", output );
waitKey();
}
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#define MATCHES_DIST_THRESHOLD 25
using namespace cv;
using namespace cv::line_descriptor;
static const char* keys =
{ "{@image_path1 | | Image path 1 }"
"{@image_path2 | | Image path 2 }" };
static void help()
{
std::cout << "\nThis example shows the functionalities of lines extraction " << "and descriptors computation furnished by BinaryDescriptor class\n"
<< "Please, run this sample using a command in the form\n" << "./example_line_descriptor_compute_descriptors <path_to_input_image 1>"
<< "<path_to_input_image 2>" << std::endl;
}
int main( int argc, char** argv )
{
/* get parameters from command line */
CommandLineParser parser( argc, argv, keys );
String image_path1 = parser.get<String>( 0 );
String image_path2 = parser.get<String>( 1 );
if( image_path1.empty() || image_path2.empty() )
{
help();
return -1;
}
/* load image */
cv::Mat imageMat1 = imread( image_path1, 1 );
cv::Mat imageMat2 = imread( image_path2, 1 );
if( imageMat1.data == NULL || imageMat2.data == NULL )
{
std::cout << "Error, images could not be loaded. Please, check their path" << std::endl;
}
/* create binary masks */
cv::Mat mask1 = Mat::ones( imageMat1.size(), CV_8UC1 );
cv::Mat mask2 = Mat::ones( imageMat2.size(), CV_8UC1 );
/* create a pointer to a BinaryDescriptor object with default parameters */
Ptr<BinaryDescriptor> bd = BinaryDescriptor::createBinaryDescriptor( );
/* compute lines and descriptors */
std::vector<KeyLine> keylines1, keylines2;
cv::Mat descr1, descr2;
( *bd )( imageMat1, mask1, keylines1, descr1, false, false );
( *bd )( imageMat2, mask2, keylines2, descr2, false, false );
/* select keylines from first octave and their descriptors */
std::vector<KeyLine> lbd_octave1, lbd_octave2;
Mat left_lbd, right_lbd;
for ( int i = 0; i < (int) keylines1.size(); i++ )
{
if( keylines1[i].octave == 0 )
{
lbd_octave1.push_back( keylines1[i] );
left_lbd.push_back( descr1.row( i ) );
}
}
for ( int j = 0; j < (int) keylines2.size(); j++ )
{
if( keylines2[j].octave == 0 )
{
lbd_octave2.push_back( keylines2[j] );
right_lbd.push_back( descr2.row( j ) );
}
}
/* create a BinaryDescriptorMatcher object */
Ptr<BinaryDescriptorMatcher> bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
/* require match */
std::vector<DMatch> matches;
bdm->match( left_lbd, right_lbd, matches );
/* select best matches */
std::vector<DMatch> good_matches;
for ( int i = 0; i < (int) matches.size(); i++ )
{
if( matches[i].distance < MATCHES_DIST_THRESHOLD )
good_matches.push_back( matches[i] );
}
/* plot matches */
cv::Mat outImg;
cv::Mat scaled1, scaled2;
std::vector<char> mask( matches.size(), 1 );
drawLineMatches( imageMat1, lbd_octave1, imageMat2, lbd_octave2, good_matches, outImg, Scalar::all( -1 ), Scalar::all( -1 ), mask,
DrawLinesMatchesFlags::DEFAULT );
imshow( "Matches", outImg );
waitKey();
imwrite("/home/ubisum/Desktop/images/env_match/matches.jpg", outImg);
/* create an LSD detector */
Ptr<LSDDetector> lsd = LSDDetector::createLSDDetector();
/* detect lines */
std::vector<KeyLine> klsd1, klsd2;
Mat lsd_descr1, lsd_descr2;
lsd->detect( imageMat1, klsd1, 2, 2, mask1 );
lsd->detect( imageMat2, klsd2, 2, 2, mask2 );
/* compute descriptors for lines from first octave */
bd->compute( imageMat1, klsd1, lsd_descr1 );
bd->compute( imageMat2, klsd2, lsd_descr2 );
/* select lines and descriptors from first octave */
std::vector<KeyLine> octave0_1, octave0_2;
Mat leftDEscr, rightDescr;
for ( int i = 0; i < (int) klsd1.size(); i++ )
{
if( klsd1[i].octave == 1 )
{
octave0_1.push_back( klsd1[i] );
leftDEscr.push_back( lsd_descr1.row( i ) );
}
}
for ( int j = 0; j < (int) klsd2.size(); j++ )
{
if( klsd2[j].octave == 1 )
{
octave0_2.push_back( klsd2[j] );
rightDescr.push_back( lsd_descr2.row( j ) );
}
}
/* compute matches */
std::vector<DMatch> lsd_matches;
bdm->match( leftDEscr, rightDescr, lsd_matches );
/* select best matches */
good_matches.clear();
for ( int i = 0; i < (int) lsd_matches.size(); i++ )
{
if( lsd_matches[i].distance < MATCHES_DIST_THRESHOLD )
good_matches.push_back( lsd_matches[i] );
}
/* plot matches */
cv::Mat lsd_outImg;
resize( imageMat1, imageMat1, Size( imageMat1.cols / 2, imageMat1.rows / 2 ) );
resize( imageMat2, imageMat2, Size( imageMat2.cols / 2, imageMat2.rows / 2 ) );
std::vector<char> lsd_mask( matches.size(), 1 );
drawLineMatches( imageMat1, octave0_1, imageMat2, octave0_2, good_matches, lsd_outImg, Scalar::all( -1 ), Scalar::all( -1 ), lsd_mask,
DrawLinesMatchesFlags::DEFAULT );
imshow( "LSD matches", lsd_outImg );
waitKey();
}
/*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 <opencv2/line_descriptor.hpp>
#include "opencv2/core/utility.hpp"
#include "opencv2/core/private.hpp"
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace cv::line_descriptor;
static const std::string images[] =
{ "cameraman.jpg", "church.jpg", "church2.png", "einstein.jpg", "stuff.jpg" };
static const char* keys =
{ "{@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 <path_to_input_images>/" << std::endl;
}
int main( int argc, char** argv )
{
/* get parameters from comand line */
CommandLineParser parser( argc, argv, keys );
String pathToImages = parser.get < String > ( 0 );
/* create structures for hosting KeyLines and descriptors */
int num_elements = sizeof ( images ) / sizeof ( images[0] );
std::vector < Mat > descriptorsMat;
std::vector < std::vector<KeyLine> > linesMat;
/*create a pointer to a BinaryDescriptor object */
Ptr < BinaryDescriptor > 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];
std::cout << image_path.str().c_str() << std::endl;
/* 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 < KeyLine > 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 < BinaryDescriptorMatcher > bdm = BinaryDescriptorMatcher::createBinaryDescriptorMatcher();
/* populate matcher */
bdm->add( descriptorsMat );
/* compute matches */
std::vector < std::vector<DMatch> > matches;
bdm->radiusMatch( queries, matches, 30 );
std::cout << "size matches sample " << matches.size() << std::endl;
for ( int i = 0; i < (int) matches.size(); i++ )
{
for ( int j = 0; j < (int) matches[i].size(); j++ )
{
std::cout << "match: " << matches[i][j].queryIdx << " " << matches[i][j].trainIdx << " " << matches[i][j].distance << std::endl;
}
}
}
/*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"
//using namespace cv;
namespace cv
{
namespace line_descriptor
{
Ptr<LSDDetector> LSDDetector::createLSDDetector()
{
return Ptr<LSDDetector>( new LSDDetector() );
}
/* compute Gaussian pyramid of input image */
void LSDDetector::computeGaussianPyramid( const Mat& image, int numOctaves, int scale )
{
/* clear class fields */
gaussianPyrs.clear();
/* insert input image into pyramid */
cv::Mat currentMat = image.clone();
//cv::GaussianBlur( currentMat, currentMat, cv::Size( 5, 5 ), 1 );
gaussianPyrs.push_back( currentMat );
/* fill Gaussian pyramid */
for ( int pyrCounter = 1; pyrCounter < numOctaves; pyrCounter++ )
{
/* compute and store next image in pyramid and its size */
pyrDown( currentMat, currentMat, Size( currentMat.cols / scale, currentMat.rows / scale ) );
gaussianPyrs.push_back( currentMat );
}
}
/* check lines' extremes */
inline void checkLineExtremes( cv::Vec4i& extremes, cv::Size imageSize )
{
if( extremes[0] < 0 )
extremes[0] = 0;
if( extremes[0] >= imageSize.width )
extremes[0] = imageSize.width - 1;
if( extremes[2] < 0 )
extremes[2] = 0;
if( extremes[2] >= imageSize.width )
extremes[2] = imageSize.width - 1;
if( extremes[1] < 0 )
extremes[1] = 0;
if( extremes[1] >= imageSize.height )
extremes[1] = imageSize.height - 1;
if( extremes[3] < 0 )
extremes[3] = 0;
if( extremes[3] >= imageSize.height )
extremes[3] = imageSize.height - 1;
}
/* requires line detection (only one image) */
void LSDDetector::detect( const Mat& image, CV_OUT std::vector<KeyLine>& keylines, int scale, int numOctaves, const Mat& mask )
{
if( mask.data != NULL && ( mask.size() != image.size() || mask.type() != CV_8UC1 ) )
throw std::runtime_error( "Mask error while detecting lines: please check its dimensions and that data type is CV_8UC1" );
else
detectImpl( image, keylines, numOctaves, scale, mask );
}
/* requires line detection (more than one image) */
void LSDDetector::detect( const std::vector<Mat>& images, std::vector<std::vector<KeyLine> >& keylines, int scale, int numOctaves,
const std::vector<Mat>& 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 ) )
throw std::runtime_error( "Masks error while detecting lines: please check their dimensions and that data types are CV_8UC1" );
else
detectImpl( images[counter], keylines[counter], numOctaves, scale, masks[counter] );
}
}
/* implementation of line detection */
void LSDDetector::detectImpl( const Mat& imageSrc, std::vector<KeyLine>& keylines, int numOctaves, int scale, 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 )
throw std::runtime_error( "Error, depth image!= 0" );
/* create a pointer to self */
LSDDetector *lsd = const_cast<LSDDetector*>( this );
/* compute Gaussian pyramids */
lsd->computeGaussianPyramid( image, numOctaves, scale );
/* create an LSD extractor */
cv::Ptr<cv::LineSegmentDetector> ls = cv::createLineSegmentDetector( cv::LSD_REFINE_ADV );
/* prepare a vector to host extracted segments */
std::vector<std::vector<cv::Vec4i> > lines_lsd;
/* extract lines */
for ( int i = 0; i < numOctaves; i++ )
{
std::vector<Vec4i> octave_lines;
ls->detect( gaussianPyrs[i], octave_lines );
lines_lsd.push_back( octave_lines );
}
/* create keylines */
int class_counter = -1;
for ( int j = 0; j < (int) lines_lsd.size(); j++ )
{
for ( int k = 0; k < (int) lines_lsd[j].size(); k++ )
{
KeyLine kl;
cv::Vec4i extremes = lines_lsd[j][k];
/* check data validity */
checkLineExtremes( extremes, gaussianPyrs[j].size() );
/* fill KeyLine's fields */
kl.startPointX = (float) extremes[0];
kl.startPointY = (float) extremes[1];
kl.endPointX = (float) extremes[2];
kl.endPointY = (float) extremes[3];
kl.sPointInOctaveX = (float) extremes[0];
kl.sPointInOctaveY = (float) extremes[1];
kl.ePointInOctaveX = (float) extremes[2];
kl.ePointInOctaveY = (float) extremes[3];
kl.lineLength = (float) sqrt( pow( extremes[0] - extremes[2], 2 ) + pow( extremes[1] - extremes[3], 2 ) );
/* compute number of pixels covered by line */
LineIterator li( gaussianPyrs[j], Point( extremes[0], extremes[1] ), Point( extremes[2], extremes[3] ) );
kl.numOfPixels = li.count;
kl.angle = atan2( ( kl.endPointY - kl.startPointY ), ( kl.endPointX - kl.startPointX ) );
kl.class_id = ++class_counter;
kl.octave = j;
kl.size = ( kl.endPointX - kl.startPointX ) * ( kl.endPointY - kl.startPointY );
kl.response = kl.lineLength / max( gaussianPyrs[j].cols, gaussianPyrs[j].rows );
kl.pt = Point2f( ( kl.endPointX + kl.startPointX ) / 2, ( kl.endPointY + kl.startPointY ) / 2 );
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<uchar>( (int) kl.startPointY, (int) kl.startPointX ) == 0 && mask.at<uchar>( (int) kl.endPointY, (int) kl.endPointX ) == 0 )
keylines.erase( keylines.begin() + keyCounter );
}
}
}
}
}
This diff is collapsed.
This diff is collapsed.
/*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
#ifdef _WIN32
#pragma warning( disable : 4267 )
#endif
#include "types.hpp"
#include <stdio.h>
#include <math.h>
#include <string.h>
/* class defining a sequence of bits */
class bitarray
{
public:
/* pointer to bits sequence and sequence's length */
UINT32 *arr;
UINT32 length;
/* constructor setting default values */
bitarray()
{
arr = NULL;
length = 0;
}
/* constructor setting sequence's length */
bitarray( UINT64 _bits )
{
init( _bits );
}
/* initializer of private fields */
void init( UINT64 _bits )
{
length = (UINT32) ceil( _bits / 32.00 );
arr = new UINT32[length];
erase();
}
/* destructor */
~bitarray()
{
if( arr )
delete[] arr;
}
inline void flip( UINT64 index )
{
arr[index >> 5] ^= ( (UINT32) 0x01 ) << ( index % 32 );
}
inline void set( UINT64 index )
{
arr[index >> 5] |= ( (UINT32) 0x01 ) << ( index % 32 );
}
inline UINT8 get( UINT64 index )
{
return ( arr[index >> 5] & ( ( (UINT32) 0x01 ) << ( index % 32 ) ) ) != 0;
}
/* reserve menory for an UINT32 */
inline void erase()
{
memset( arr, 0, sizeof(UINT32) * length );
}
};
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#include "test_precomp.hpp"
CV_TEST_MAIN("cv")
This diff is collapsed.
#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wmissing-declarations"
# if defined __clang__ || defined __APPLE__
# pragma GCC diagnostic ignored "-Wmissing-prototypes"
# pragma GCC diagnostic ignored "-Wextra"
# endif
#endif
#ifndef __OPENCV_TEST_PRECOMP_HPP__
#define __OPENCV_TEST_PRECOMP_HPP__
#include "opencv2/ts.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/features2d.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/line_descriptor.hpp"
#include <opencv2/core.hpp>
#include <iostream>
#include <string.h>
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment