Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                           License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2008, Willow Garage Inc., all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 
     42 /*
     43 OpenCV wrapper of reference implementation of
     44 [1] Fast Explicit Diffusion for Accelerated Features in Nonlinear Scale Spaces.
     45 Pablo F. Alcantarilla, J. Nuevo and Adrien Bartoli.
     46 In British Machine Vision Conference (BMVC), Bristol, UK, September 2013
     47 http://www.robesafe.com/personal/pablo.alcantarilla/papers/Alcantarilla13bmvc.pdf
     48 @author Eugene Khvedchenya <ekhvedchenya (at) gmail.com>
     49 */
     50 
     51 #include "precomp.hpp"
     52 #include "kaze/AKAZEFeatures.h"
     53 
     54 #include <iostream>
     55 
     56 namespace cv
     57 {
     58     using namespace std;
     59 
     60     class AKAZE_Impl : public AKAZE
     61     {
     62     public:
     63         AKAZE_Impl(int _descriptor_type, int _descriptor_size, int _descriptor_channels,
     64                  float _threshold, int _octaves, int _sublevels, int _diffusivity)
     65         : descriptor(_descriptor_type)
     66         , descriptor_channels(_descriptor_channels)
     67         , descriptor_size(_descriptor_size)
     68         , threshold(_threshold)
     69         , octaves(_octaves)
     70         , sublevels(_sublevels)
     71         , diffusivity(_diffusivity)
     72         {
     73         }
     74 
     75         virtual ~AKAZE_Impl()
     76         {
     77 
     78         }
     79 
     80         void setDescriptorType(int dtype) { descriptor = dtype; }
     81         int getDescriptorType() const { return descriptor; }
     82 
     83         void setDescriptorSize(int dsize) { descriptor_size = dsize; }
     84         int getDescriptorSize() const { return descriptor_size; }
     85 
     86         void setDescriptorChannels(int dch) { descriptor_channels = dch; }
     87         int getDescriptorChannels() const { return descriptor_channels; }
     88 
     89         void setThreshold(double threshold_) { threshold = (float)threshold_; }
     90         double getThreshold() const { return threshold; }
     91 
     92         void setNOctaves(int octaves_) { octaves = octaves_; }
     93         int getNOctaves() const { return octaves; }
     94 
     95         void setNOctaveLayers(int octaveLayers_) { sublevels = octaveLayers_; }
     96         int getNOctaveLayers() const { return sublevels; }
     97 
     98         void setDiffusivity(int diff_) { diffusivity = diff_; }
     99         int getDiffusivity() const { return diffusivity; }
    100 
    101         // returns the descriptor size in bytes
    102         int descriptorSize() const
    103         {
    104             switch (descriptor)
    105             {
    106             case DESCRIPTOR_KAZE:
    107             case DESCRIPTOR_KAZE_UPRIGHT:
    108                 return 64;
    109 
    110             case DESCRIPTOR_MLDB:
    111             case DESCRIPTOR_MLDB_UPRIGHT:
    112                 // We use the full length binary descriptor -> 486 bits
    113                 if (descriptor_size == 0)
    114                 {
    115                     int t = (6 + 36 + 120) * descriptor_channels;
    116                     return (int)ceil(t / 8.);
    117                 }
    118                 else
    119                 {
    120                     // We use the random bit selection length binary descriptor
    121                     return (int)ceil(descriptor_size / 8.);
    122                 }
    123 
    124             default:
    125                 return -1;
    126             }
    127         }
    128 
    129         // returns the descriptor type
    130         int descriptorType() const
    131         {
    132             switch (descriptor)
    133             {
    134             case DESCRIPTOR_KAZE:
    135             case DESCRIPTOR_KAZE_UPRIGHT:
    136                     return CV_32F;
    137 
    138             case DESCRIPTOR_MLDB:
    139             case DESCRIPTOR_MLDB_UPRIGHT:
    140                     return CV_8U;
    141 
    142                 default:
    143                     return -1;
    144             }
    145         }
    146 
    147         // returns the default norm type
    148         int defaultNorm() const
    149         {
    150             switch (descriptor)
    151             {
    152             case DESCRIPTOR_KAZE:
    153             case DESCRIPTOR_KAZE_UPRIGHT:
    154                 return NORM_L2;
    155 
    156             case DESCRIPTOR_MLDB:
    157             case DESCRIPTOR_MLDB_UPRIGHT:
    158                 return NORM_HAMMING;
    159 
    160             default:
    161                 return -1;
    162             }
    163         }
    164 
    165         void detectAndCompute(InputArray image, InputArray mask,
    166                               std::vector<KeyPoint>& keypoints,
    167                               OutputArray descriptors,
    168                               bool useProvidedKeypoints)
    169         {
    170             Mat img = image.getMat();
    171             if (img.type() != CV_8UC1)
    172                 cvtColor(image, img, COLOR_BGR2GRAY);
    173 
    174             Mat img1_32;
    175             if ( img.depth() == CV_32F )
    176                 img1_32 = img;
    177             else if ( img.depth() == CV_8U )
    178                 img.convertTo(img1_32, CV_32F, 1.0 / 255.0, 0);
    179             else if ( img.depth() == CV_16U )
    180                 img.convertTo(img1_32, CV_32F, 1.0 / 65535.0, 0);
    181 
    182             CV_Assert( ! img1_32.empty() );
    183 
    184             AKAZEOptions options;
    185             options.descriptor = descriptor;
    186             options.descriptor_channels = descriptor_channels;
    187             options.descriptor_size = descriptor_size;
    188             options.img_width = img.cols;
    189             options.img_height = img.rows;
    190             options.dthreshold = threshold;
    191             options.omax = octaves;
    192             options.nsublevels = sublevels;
    193             options.diffusivity = diffusivity;
    194 
    195             AKAZEFeatures impl(options);
    196             impl.Create_Nonlinear_Scale_Space(img1_32);
    197 
    198             if (!useProvidedKeypoints)
    199             {
    200                 impl.Feature_Detection(keypoints);
    201             }
    202 
    203             if (!mask.empty())
    204             {
    205                 KeyPointsFilter::runByPixelsMask(keypoints, mask.getMat());
    206             }
    207 
    208             if( descriptors.needed() )
    209             {
    210                 Mat& desc = descriptors.getMatRef();
    211                 impl.Compute_Descriptors(keypoints, desc);
    212 
    213                 CV_Assert((!desc.rows || desc.cols == descriptorSize()));
    214                 CV_Assert((!desc.rows || (desc.type() == descriptorType())));
    215             }
    216         }
    217 
    218         void write(FileStorage& fs) const
    219         {
    220             fs << "descriptor" << descriptor;
    221             fs << "descriptor_channels" << descriptor_channels;
    222             fs << "descriptor_size" << descriptor_size;
    223             fs << "threshold" << threshold;
    224             fs << "octaves" << octaves;
    225             fs << "sublevels" << sublevels;
    226             fs << "diffusivity" << diffusivity;
    227         }
    228 
    229         void read(const FileNode& fn)
    230         {
    231             descriptor = (int)fn["descriptor"];
    232             descriptor_channels = (int)fn["descriptor_channels"];
    233             descriptor_size = (int)fn["descriptor_size"];
    234             threshold = (float)fn["threshold"];
    235             octaves = (int)fn["octaves"];
    236             sublevels = (int)fn["sublevels"];
    237             diffusivity = (int)fn["diffusivity"];
    238         }
    239 
    240         int descriptor;
    241         int descriptor_channels;
    242         int descriptor_size;
    243         float threshold;
    244         int octaves;
    245         int sublevels;
    246         int diffusivity;
    247     };
    248 
    249     Ptr<AKAZE> AKAZE::create(int descriptor_type,
    250                              int descriptor_size, int descriptor_channels,
    251                              float threshold, int octaves,
    252                              int sublevels, int diffusivity)
    253     {
    254         return makePtr<AKAZE_Impl>(descriptor_type, descriptor_size, descriptor_channels,
    255                                    threshold, octaves, sublevels, diffusivity);
    256     }
    257 }
    258