Repository: opencv
Issue: cvflann::hierarchicalClustering doesn't compile with Hamming Distance
Labels: RFC

Hello:

**Edit: 
Long story short: It is possible to cluster features using Hamming with _deprecated_ `cv::flann::hierarchicalClustering<ELEM_TYPE,DIST_TYPE>` after fixing the bug in Hamming distance code by removing spurious pointers and work with iterators instead.**
I can provide the bug-fix for the latter if someone can establish what is the future of hierarchicalClustering function.

Original problem encountered:

Function call: `cv::flann::hierarchicalClustering<cv::flann::Hamming<uchar>>` causes compilation error: 

```
include/opencv2/flann/dist.h:450:31: error: reinterpret_cast from 'cvflann::ZeroIterator<unsigned char>' to 'const pop_t *' (aka 'const unsigned long long *') is not allowed
            const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Works fine with L2 distance.

Possibly the same problem as in [this very old issue 1346 from OpenCV 2.3.1](http://code.opencv.org/issues/1346)
## Please state the information for your system
- OpenCV version: 3.0
### Expected behaviour

hierarchical clustering of binary feature descriptors (stored as chars).
### Actual behaviour

compilation error
### Additional description
### Code example to reproduce the issue:

```
    cvflann::KMeansIndexParams params;  
    cv::Mat words = cv::Mat::zeros(dictionarySize, features.cols, CV_32F);
    int count = cv::flann::hierarchicalClustering<cv::flann::Hamming<uchar>>(features,words,params);    
//works fine with L2 distance
//    int count = cv::flann::hierarchicalClustering<cv::flann::L2<float>>(features,words,params);   

```

Error in compiling:

```
[ 11%] Building CXX object CMakeFiles/r-bow.dir/bow.cpp.o
In file included from /home/mix/rachael/source/bow.cpp:1:
In file included from /home/mix/rachael/source/common.h:11:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:48:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:43:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/all_indices.h:36:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/kdtree_index.h:41:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/dynamic_bitset.h:49:
/opt/opencv-3.0.0-dbg/include/opencv2/flann/dist.h:450:31: error: reinterpret_cast from 'cvflann::ZeroIterator<unsigned char>' to 'const pop_t *' (aka 'const unsigned long long *') is not allowed
            const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:681:25: note: in instantiation of function template specialization 'cvflann::Hamming<unsigned char>::operator()<unsigned char *, cvflann::ZeroIterator<unsigned char> >' requested here
            variance += distance_(vec, ZeroIterator<ElementType>(), veclen_);
                        ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:444:9: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::computeNodeStatistics' requested here
        computeNodeStatistics(root_, indices_, (int)size_);
        ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:283:12: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::buildIndex' requested here
    kmeans.buildIndex();
           ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:532:23: note: in instantiation of function template specialization 'cvflann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
    return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
                      ^
/home/mix/rachael/source/bow.cpp:24:25: note: in instantiation of function template specialization 'cv::flann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
        int count = cv::flann::hierarchicalClustering<cv::flann::Hamming<uchar>>(features,words,params);        
                               ^
In file included from /home/mix/rachael/source/bow.cpp:1:
In file included from /home/mix/rachael/source/common.h:11:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:48:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:43:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/all_indices.h:36:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/kdtree_index.h:41:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/dynamic_bitset.h:49:
/opt/opencv-3.0.0-dbg/include/opencv2/flann/dist.h:450:31: error: reinterpret_cast from 'cvflann::ZeroIterator<unsigned char>' to 'const pop_t *' (aka 'const unsigned long long *') is not allowed
            const pop_t* b2 = reinterpret_cast<const pop_t*> (b);
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:687:21: note: in instantiation of function template specialization 'cvflann::Hamming<unsigned char>::operator()<int *, cvflann::ZeroIterator<unsigned char> >' requested here
        variance -= distance_(mean, ZeroIterator<ElementType>(), veclen_);
                    ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:444:9: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::computeNodeStatistics' requested here
        computeNodeStatistics(root_, indices_, (int)size_);
        ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:283:12: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::buildIndex' requested here
    kmeans.buildIndex();
           ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:532:23: note: in instantiation of function template specialization 'cvflann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
    return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
                      ^
/home/mix/rachael/source/bow.cpp:24:25: note: in instantiation of function template specialization 'cv::flann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
        int count = cv::flann::hierarchicalClustering<cv::flann::Hamming<uchar>>(features,words,params);        
                               ^
In file included from /home/mix/rachael/source/bow.cpp:1:
In file included from /home/mix/rachael/source/common.h:11:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:48:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:43:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/all_indices.h:38:
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:854:38: error: no matching function for call to object of type 'cvflann::Hamming<unsigned char>'
                    DistanceType d = distance_(dataset_[indices[i]], ZeroIterator<ElementType>(), veclen_);
                                     ^~~~~~~~~
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:445:9: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::computeClustering' requested here
        computeClustering(root_, indices_, (int)size_, branching_,0);
        ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:283:12: note: in instantiation of member function 'cvflann::KMeansIndex<cvflann::Hamming<unsigned char> >::buildIndex' requested here
    kmeans.buildIndex();
           ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:532:23: note: in instantiation of function template specialization 'cvflann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
    return ::cvflann::hierarchicalClustering<Distance>(m_features, m_centers, params, d);
                      ^
/home/mix/rachael/source/bow.cpp:24:25: note: in instantiation of function template specialization 'cv::flann::hierarchicalClustering<cvflann::Hamming<unsigned char> >' requested here
        int count = cv::flann::hierarchicalClustering<cv::flann::Hamming<uchar>>(features,words,params);        
                               ^
/opt/opencv-3.0.0-dbg/include/opencv2/flann/dist.h:425:16: note: candidate template ignored: substitution failure [with Iterator1 = unsigned char *, Iterator2 = cvflann::ZeroIterator<unsigned char>]
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
               ^
In file included from /home/mix/rachael/source/bow.cpp:1:
In file included from /home/mix/rachael/source/common.h:11:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann.hpp:48:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/flann_base.hpp:43:
In file included from /opt/opencv-3.0.0-dbg/include/opencv2/flann/all_indices.h:38:
/opt/opencv-3.0.0-dbg/include/opencv2/flann/kmeans_index.h:864:25: error: no matching function for call to object of type 'cvflann::Hamming<unsigned char>'
            variance -= distance_(centers[c], ZeroIterator<ElementType>(), veclen_);
                        ^~~~~~~~~
/opt/opencv-3.0.0-dbg/include/opencv2/flann/dist.h:425:16: note: candidate template ignored: substitution failure [with Iterator1 = int *, Iterator2 = cvflann::ZeroIterator<unsigned char>]
    ResultType operator()(Iterator1 a, Iterator2 b, size_t size, ResultType /*worst_dist*/ = -1) const
               ^
4 errors generated.
```