| 3754 | |
| 3755 | |
| 3756 | int KDTree::findNearest(InputArray _vec, int K, int emax, |
| 3757 | OutputArray _neighborsIdx, OutputArray _neighbors, |
| 3758 | OutputArray _dist, OutputArray _labels) const |
| 3759 | |
| 3760 | { |
| 3761 | Mat vecmat = _vec.getMat(); |
| 3762 | CV_Assert( vecmat.isContinuous() && vecmat.type() == CV_32F && vecmat.total() == (size_t)points.cols ); |
| 3763 | const float* vec = vecmat.ptr<float>(); |
| 3764 | K = std::min(K, points.rows); |
| 3765 | int ptdims = points.cols; |
| 3766 | |
| 3767 | CV_Assert(K > 0 && (normType == NORM_L2 || normType == NORM_L1)); |
| 3768 | |
| 3769 | AutoBuffer<uchar> _buf((K+1)*(sizeof(float) + sizeof(int))); |
| 3770 | int* idx = (int*)(uchar*)_buf; |
| 3771 | float* dist = (float*)(idx + K + 1); |
| 3772 | int i, j, ncount = 0, e = 0; |
| 3773 | |
| 3774 | int qsize = 0, maxqsize = 1 << 10; |
| 3775 | AutoBuffer<uchar> _pqueue(maxqsize*sizeof(PQueueElem)); |
| 3776 | PQueueElem* pqueue = (PQueueElem*)(uchar*)_pqueue; |
| 3777 | emax = std::max(emax, 1); |
| 3778 | |
| 3779 | for( e = 0; e < emax; ) |
| 3780 | { |
| 3781 | float d, alt_d = 0.f; |
| 3782 | int nidx; |
| 3783 | |
| 3784 | if( e == 0 ) |
| 3785 | nidx = 0; |
| 3786 | else |
| 3787 | { |
| 3788 | // take the next node from the priority queue |
| 3789 | if( qsize == 0 ) |
| 3790 | break; |
| 3791 | nidx = pqueue[0].idx; |
| 3792 | alt_d = pqueue[0].dist; |
| 3793 | if( --qsize > 0 ) |
| 3794 | { |
| 3795 | std::swap(pqueue[0], pqueue[qsize]); |
| 3796 | d = pqueue[0].dist; |
| 3797 | for( i = 0;;) |
| 3798 | { |
| 3799 | int left = i*2 + 1, right = i*2 + 2; |
| 3800 | if( left >= qsize ) |
| 3801 | break; |
| 3802 | if( right < qsize && pqueue[right].dist < pqueue[left].dist ) |
| 3803 | left = right; |
| 3804 | if( pqueue[left].dist >= d ) |
| 3805 | break; |
| 3806 | std::swap(pqueue[i], pqueue[left]); |
| 3807 | i = left; |
| 3808 | } |
| 3809 | } |
| 3810 | |
| 3811 | if( ncount == K && alt_d > dist[ncount-1] ) |
| 3812 | continue; |
| 3813 | } |
nothing calls this directly
no test coverage detected