Merge branch 'bug_3172' of https://github.com/elmarb/opencv into bfmatcher_fix;
use different fix for the problem, embedded right into the BFMatcher.
This commit is contained in:
commit
3516e14e05
@ -2192,13 +2192,6 @@ CV_EXPORTS_W void batchDistance(InputArray src1, InputArray src2,
|
||||
InputArray mask=noArray(), int update=0,
|
||||
bool crosscheck=false);
|
||||
|
||||
//! naive nearest neighbor finder which incrementally updates dist and nidx when called repeatedly with the same K and src1, but varying src2
|
||||
CV_EXPORTS_W void batchDistanceForBFMatcher(InputArray src1, InputArray src2,
|
||||
InputOutputArray dist, int dtype, InputOutputArray nidx,
|
||||
int normType=NORM_L2, int K=1,
|
||||
InputArray mask=noArray(), int update=0,
|
||||
bool crosscheck=false);
|
||||
|
||||
//! scales and shifts array elements so that either the specified norm (alpha) or the minimum (alpha) and maximum (beta) array values get the specified values
|
||||
CV_EXPORTS_W void normalize( InputArray src, OutputArray dst, double alpha=1, double beta=0,
|
||||
int norm_type=NORM_L2, int dtype=-1, InputArray mask=noArray());
|
||||
|
@ -2460,21 +2460,32 @@ struct BatchDistInvoker : public ParallelLoopBody
|
||||
BatchDistFunc func;
|
||||
};
|
||||
|
||||
static void batchDistanceImpl( InputArray _src1, InputArray _src2,
|
||||
InputOutputArray _dist, int dtype, InputOutputArray _nidx,
|
||||
int normType, int K, InputArray _mask,
|
||||
int update, bool crosscheck )
|
||||
}
|
||||
|
||||
void cv::batchDistance( InputArray _src1, InputArray _src2,
|
||||
OutputArray _dist, int dtype, OutputArray _nidx,
|
||||
int normType, int K, InputArray _mask,
|
||||
int update, bool crosscheck )
|
||||
{
|
||||
Mat src1 = _src1.getMat(), src2 = _src2.getMat(), mask = _mask.getMat();
|
||||
int type = src1.type();
|
||||
CV_Assert( type == src2.type() && src1.cols == src2.cols &&
|
||||
(type == CV_32F || type == CV_8U));
|
||||
(type == CV_32F || type == CV_8U));
|
||||
CV_Assert( _nidx.needed() == (K > 0) );
|
||||
|
||||
if( dtype == -1 )
|
||||
{
|
||||
dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ? CV_32S : CV_32F;
|
||||
}
|
||||
CV_Assert( (type == CV_8U && dtype == CV_32S) || dtype == CV_32F);
|
||||
|
||||
K = std::min(K, src2.rows);
|
||||
|
||||
_dist.create(src1.rows, (K > 0 ? K : src2.rows), dtype);
|
||||
Mat dist = _dist.getMat(), nidx;
|
||||
if( _nidx.needed() )
|
||||
{
|
||||
_nidx.create(dist.size(), CV_32S);
|
||||
nidx = _nidx.getMat();
|
||||
}
|
||||
|
||||
@ -2562,55 +2573,6 @@ static void batchDistanceImpl( InputArray _src1, InputArray _src2,
|
||||
BatchDistInvoker(src1, src2, dist, nidx, K, mask, update, func));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void cv::batchDistance( InputArray _src1, InputArray _src2,
|
||||
OutputArray _dist, int dtype, OutputArray _nidx,
|
||||
int normType, int K, InputArray _mask,
|
||||
int update, bool crosscheck )
|
||||
{
|
||||
if( dtype == -1 )
|
||||
{
|
||||
dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ? CV_32S : CV_32F;
|
||||
}
|
||||
|
||||
// K == 0: return all matches; K > 0: return K best matches, but never more than the number of candidates in _src2
|
||||
CV_Assert( _nidx.needed() == (K > 0) );
|
||||
int candidates = _src2.size().height;
|
||||
K = std::min( K, candidates );
|
||||
_dist.create( _src1.size().height, (K > 0 ? K : candidates), dtype );
|
||||
if( _nidx.needed() )
|
||||
{
|
||||
_nidx.create( _dist.size(), CV_32S );
|
||||
}
|
||||
|
||||
batchDistanceImpl( _src1, _src2, _dist, dtype, _nidx, normType, K, _mask, update, crosscheck );
|
||||
}
|
||||
|
||||
|
||||
void cv::batchDistanceForBFMatcher( InputArray _src1, InputArray _src2,
|
||||
InputOutputArray _dist, int dtype, InputOutputArray _nidx,
|
||||
int normType, int K, InputArray _mask,
|
||||
int update, bool crosscheck )
|
||||
{
|
||||
if( dtype == -1 )
|
||||
{
|
||||
dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ? CV_32S : CV_32F;
|
||||
}
|
||||
|
||||
// always work with K matches (unlike cv::batchDistance), even if _src2 has fewer candidates
|
||||
// if this function is called in a loop, then the other loop iterations may require all K
|
||||
CV_Assert( K > 0 && _nidx.needed() );
|
||||
cv::Size size( K, _src1.size().height );
|
||||
CV_Assert( update == 0 || (_dist.size() == size && _nidx.size() == size) );
|
||||
_dist.create( size, dtype );
|
||||
_nidx.create( size, CV_32S );
|
||||
|
||||
batchDistanceImpl( _src1, _src2, _dist, dtype, _nidx, normType, K, _mask, update, crosscheck );
|
||||
CV_Assert( _dist.size() == size && _nidx.size() == size );
|
||||
}
|
||||
|
||||
|
||||
void cv::findNonZero( InputArray _src, OutputArray _idx )
|
||||
{
|
||||
|
@ -352,19 +352,28 @@ void BFMatcher::knnMatchImpl( const Mat& queryDescriptors, vector<vector<DMatch>
|
||||
|
||||
matches.reserve(queryDescriptors.rows);
|
||||
|
||||
Mat dist, nidx;
|
||||
|
||||
int iIdx, imgCount = (int)trainDescCollection.size(), update = 0;
|
||||
int dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 ||
|
||||
(normType == NORM_L1 && queryDescriptors.type() == CV_8U) ? CV_32S : CV_32F;
|
||||
int maxRows = 0;
|
||||
|
||||
CV_Assert( (int64)imgCount*IMGIDX_ONE < INT_MAX );
|
||||
|
||||
for( iIdx = 0; iIdx < imgCount; iIdx++ )
|
||||
maxRows = std::max(maxRows, trainDescCollection[iIdx].rows);
|
||||
|
||||
int m = queryDescriptors.rows;
|
||||
Mat dist(m, knn, dtype), nidx(m, knn, CV_32S);
|
||||
dist = Scalar::all(dtype == CV_32S ? (double)INT_MAX : (double)FLT_MAX);
|
||||
nidx = Scalar::all(-1);
|
||||
|
||||
for( iIdx = 0; iIdx < imgCount; iIdx++ )
|
||||
{
|
||||
CV_Assert( trainDescCollection[iIdx].rows < IMGIDX_ONE );
|
||||
batchDistanceForBFMatcher(queryDescriptors, trainDescCollection[iIdx], dist, dtype, nidx,
|
||||
normType, knn, masks.empty() ? Mat() : masks[iIdx], update, crossCheck);
|
||||
int n = std::min(knn, trainDescCollection[iIdx].rows);
|
||||
Mat dist_i = dist.colRange(0, n), nidx_i = nidx.colRange(0, n);
|
||||
batchDistance(queryDescriptors, trainDescCollection[iIdx], dist_i, dtype, nidx_i,
|
||||
normType, knn, masks.empty() ? Mat() : masks[iIdx], update, crossCheck);
|
||||
update += IMGIDX_ONE;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user