1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*M/////////////////////////////////////////////////////////////////////////////////////// 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// By downloading, copying, installing or using the software you agree to this license. 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// If you do not agree to this license, do not download, install, 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// copy or use the software. 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Intel License Agreement 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// For Open Source Computer Vision Library 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Copyright (C) 2000, Intel Corporation, all rights reserved. 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Third party copyrights are property of their respective owners. 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// Redistribution and use in source and binary forms, with or without modification, 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// are permitted provided that the following conditions are met: 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * Redistribution's of source code must retain the above copyright notice, 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// this list of conditions and the following disclaimer. 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * Redistribution's in binary form must reproduce the above copyright notice, 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// this list of conditions and the following disclaimer in the documentation 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and/or other materials provided with the distribution. 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// * The name of Intel Corporation may not be used to endorse or promote products 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// derived from this software without specific prior written permission. 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// This software is provided by the copyright holders and contributors "as is" and 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// any express or implied warranties, including, but not limited to, the implied 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// warranties of merchantability and fitness for a particular purpose are disclaimed. 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// In no event shall the Intel Corporation or contributors be liable for any direct, 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// indirect, incidental, special, exemplary, or consequential damages 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// (including, but not limited to, procurement of substitute goods or services; 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// loss of use, data, or profits; or business interruption) however caused 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// and on any theory of liability, whether in contract, strict liability, 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// or tort (including negligence or otherwise) arising in any way out of 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// the use of this software, even if advised of the possibility of such damage. 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler// 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler//M*/ 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "precomp.hpp" 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <limits> 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "opencl_kernels_features2d.hpp" 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#if defined(HAVE_EIGEN) && EIGEN_WORLD_VERSION == 2 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <Eigen/Array> 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslernamespace cv 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////// ocl functions for BFMatcher /////////////////////////// 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void ensureSizeIsEnough(int rows, int cols, int type, UMat &m) 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (m.type() == type && m.rows >= rows && m.cols >= cols) 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m = m(Rect(0, 0, cols, rows)); 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler m.create(rows, cols, type); 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_matchSingle(InputArray query, InputArray train, 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat &trainIdx, UMat &distance, int distType) 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (query.empty() || train.empty()) 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int query_rows = query.rows(); 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int query_cols = query.cols(); 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(1, query_rows, CV_32S, trainIdx); 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(1, query_rows, CV_32F, distance); 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Device devDef = ocl::Device::getDefault(); 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat uquery = query.getUMat(), utrain = train.getUMat(); 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int kercn = 1; 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (devDef.isIntel() && 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (uquery.step % 4)) && (0 == (uquery.cols % 4)) && (0 == (uquery.offset % 4)) && 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (utrain.step % 4)) && (0 == (utrain.cols % 4)) && (0 == (utrain.offset % 4))) 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler kercn = 4; 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int block_size = 16; 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int max_desc_len = 0; 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bool is_cpu = devDef.type() == ocl::Device::TYPE_CPU; 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (query_cols <= 64) 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler max_desc_len = 64 / kercn; 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (query_cols <= 128 && !is_cpu) 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler max_desc_len = 128 / kercn; 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int depth = query.depth(); 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cv::String opts; 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler opts = cv::format("-D T=%s -D TN=%s -D kercn=%d %s -D DIST_TYPE=%d -D BLOCK_SIZE=%d -D MAX_DESC_LEN=%d", 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::typeToStr(depth), ocl::typeToStr(CV_MAKETYPE(depth, kercn)), kercn, depth == CV_32F ? "-D T_FLOAT" : "", distType, block_size, max_desc_len); 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Kernel k("BruteForceMatch_Match", ocl::features2d::brute_force_match_oclsrc, opts); 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(k.empty()) 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t globalSize[] = {(query.size().height + block_size - 1) / block_size * block_size, block_size}; 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t localSize[] = {block_size, block_size}; 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int idx = 0; 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(uquery)); 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(utrain)); 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(trainIdx)); 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(distance)); 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.rows); 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.cols); 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.rows); 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.cols); 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, (int)(uquery.step / sizeof(float))); 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return k.run(2, globalSize, localSize, false); 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_matchConvert(const Mat &trainIdx, const Mat &distance, std::vector< std::vector<DMatch> > &matches) 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty()) 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (trainIdx.type() != CV_32SC1) || (distance.type() != CV_32FC1 || distance.cols != trainIdx.cols) ) 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int nQuery = trainIdx.cols; 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.reserve(nQuery); 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int *trainIdx_ptr = trainIdx.ptr<int>(); 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const float *distance_ptr = distance.ptr<float>(); 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (int queryIdx = 0; queryIdx < nQuery; ++queryIdx, ++trainIdx_ptr, ++distance_ptr) 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainIndex = *trainIdx_ptr; 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIndex == -1) 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float dst = *distance_ptr; 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DMatch m(queryIdx, trainIndex, 0, dst); 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch> temp; 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler temp.push_back(m); 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back(temp); 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_matchDownload(const UMat &trainIdx, const UMat &distance, std::vector< std::vector<DMatch> > &matches) 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty()) 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat trainIdxCPU = trainIdx.getMat(ACCESS_READ); 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat distanceCPU = distance.getMat(ACCESS_READ); 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ocl_matchConvert(trainIdxCPU, distanceCPU, matches); 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_knnMatchSingle(InputArray query, InputArray train, UMat &trainIdx, 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat &distance, int distType) 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (query.empty() || train.empty()) 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int query_rows = query.rows(); 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int query_cols = query.cols(); 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(1, query_rows, CV_32SC2, trainIdx); 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(1, query_rows, CV_32FC2, distance); 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainIdx.setTo(Scalar::all(-1)); 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Device devDef = ocl::Device::getDefault(); 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat uquery = query.getUMat(), utrain = train.getUMat(); 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int kercn = 1; 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (devDef.isIntel() && 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (uquery.step % 4)) && (0 == (uquery.cols % 4)) && (0 == (uquery.offset % 4)) && 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (utrain.step % 4)) && (0 == (utrain.cols % 4)) && (0 == (utrain.offset % 4))) 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler kercn = 4; 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int block_size = 16; 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int max_desc_len = 0; 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bool is_cpu = devDef.type() == ocl::Device::TYPE_CPU; 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (query_cols <= 64) 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler max_desc_len = 64 / kercn; 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (query_cols <= 128 && !is_cpu) 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler max_desc_len = 128 / kercn; 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int depth = query.depth(); 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cv::String opts; 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler opts = cv::format("-D T=%s -D TN=%s -D kercn=%d %s -D DIST_TYPE=%d -D BLOCK_SIZE=%d -D MAX_DESC_LEN=%d", 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::typeToStr(depth), ocl::typeToStr(CV_MAKETYPE(depth, kercn)), kercn, depth == CV_32F ? "-D T_FLOAT" : "", distType, block_size, max_desc_len); 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Kernel k("BruteForceMatch_knnMatch", ocl::features2d::brute_force_match_oclsrc, opts); 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(k.empty()) 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t globalSize[] = {(query_rows + block_size - 1) / block_size * block_size, block_size}; 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t localSize[] = {block_size, block_size}; 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int idx = 0; 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(uquery)); 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(utrain)); 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(trainIdx)); 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(distance)); 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.rows); 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.cols); 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.rows); 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.cols); 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, (int)(uquery.step / sizeof(float))); 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return k.run(2, globalSize, localSize, false); 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_knnMatchConvert(const Mat &trainIdx, const Mat &distance, std::vector< std::vector<DMatch> > &matches, bool compactResult) 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty()) 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(trainIdx.type() != CV_32SC2 && trainIdx.type() != CV_32SC1) return false; 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(distance.type() != CV_32FC2 && distance.type() != CV_32FC1)return false; 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(distance.size() != trainIdx.size()) return false; 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!trainIdx.isContinuous() || !distance.isContinuous()) return false; 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int nQuery = trainIdx.type() == CV_32SC2 ? trainIdx.cols : trainIdx.rows; 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int k = trainIdx.type() == CV_32SC2 ? 2 : trainIdx.cols; 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.reserve(nQuery); 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int *trainIdx_ptr = trainIdx.ptr<int>(); 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const float *distance_ptr = distance.ptr<float>(); 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (int queryIdx = 0; queryIdx < nQuery; ++queryIdx) 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back(std::vector<DMatch>()); 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch> &curMatches = matches.back(); 240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler curMatches.reserve(k); 241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (int i = 0; i < k; ++i, ++trainIdx_ptr, ++distance_ptr) 243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainIndex = *trainIdx_ptr; 245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIndex != -1) 247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float dst = *distance_ptr; 249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DMatch m(queryIdx, trainIndex, 0, dst); 251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler curMatches.push_back(m); 253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (compactResult && curMatches.empty()) 257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.pop_back(); 258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_knnMatchDownload(const UMat &trainIdx, const UMat &distance, std::vector< std::vector<DMatch> > &matches, bool compactResult) 263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty()) 265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat trainIdxCPU = trainIdx.getMat(ACCESS_READ); 268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat distanceCPU = distance.getMat(ACCESS_READ); 269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ocl_knnMatchConvert(trainIdxCPU, distanceCPU, matches, compactResult); 271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_radiusMatchSingle(InputArray query, InputArray train, 274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat &trainIdx, UMat &distance, UMat &nMatches, float maxDistance, int distType) 275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (query.empty() || train.empty()) 277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int query_rows = query.rows(); 280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int train_rows = train.rows(); 281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(1, query_rows, CV_32SC1, nMatches); 283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty()) 285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(query_rows, std::max((train_rows / 100), 10), CV_32SC1, trainIdx); 287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ensureSizeIsEnough(query_rows, std::max((train_rows / 100), 10), CV_32FC1, distance); 288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nMatches.setTo(Scalar::all(0)); 291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Device devDef = ocl::Device::getDefault(); 293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat uquery = query.getUMat(), utrain = train.getUMat(); 294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int kercn = 1; 295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (devDef.isIntel() && 296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (uquery.step % 4)) && (0 == (uquery.cols % 4)) && (0 == (uquery.offset % 4)) && 297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (0 == (utrain.step % 4)) && (0 == (utrain.cols % 4)) && (0 == (utrain.offset % 4))) 298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler kercn = 4; 299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int block_size = 16; 301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int depth = query.depth(); 302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler cv::String opts; 303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler opts = cv::format("-D T=%s -D TN=%s -D kercn=%d %s -D DIST_TYPE=%d -D BLOCK_SIZE=%d", 304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::typeToStr(depth), ocl::typeToStr(CV_MAKETYPE(depth, kercn)), kercn, depth == CV_32F ? "-D T_FLOAT" : "", distType, block_size); 305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ocl::Kernel k("BruteForceMatch_RadiusMatch", ocl::features2d::brute_force_match_oclsrc, opts); 306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (k.empty()) 307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t globalSize[] = {(train_rows + block_size - 1) / block_size * block_size, (query_rows + block_size - 1) / block_size * block_size}; 310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t localSize[] = {block_size, block_size}; 311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int idx = 0; 313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(uquery)); 314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrReadOnly(utrain)); 315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, maxDistance); 316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(trainIdx)); 317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(distance)); 318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, ocl::KernelArg::PtrWriteOnly(nMatches)); 319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.rows); 320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, uquery.cols); 321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.rows); 322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, utrain.cols); 323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, trainIdx.cols); 324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, (int)(uquery.step / sizeof(float))); 325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler idx = k.set(idx, (int)(trainIdx.step / sizeof(int))); 326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return k.run(2, globalSize, localSize, false); 328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_radiusMatchConvert(const Mat &trainIdx, const Mat &distance, const Mat &_nMatches, 331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector< std::vector<DMatch> > &matches, bool compactResult) 332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty() || _nMatches.empty()) 334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( (trainIdx.type() != CV_32SC1) || 337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (distance.type() != CV_32FC1 || distance.size() != trainIdx.size()) || 338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (_nMatches.type() != CV_32SC1 || _nMatches.cols != trainIdx.rows) ) 339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int nQuery = trainIdx.rows; 342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.reserve(nQuery); 345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int *nMatches_ptr = _nMatches.ptr<int>(); 347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (int queryIdx = 0; queryIdx < nQuery; ++queryIdx) 349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int *trainIdx_ptr = trainIdx.ptr<int>(queryIdx); 351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const float *distance_ptr = distance.ptr<float>(queryIdx); 352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int nMatches = std::min(nMatches_ptr[queryIdx], trainIdx.cols); 354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (nMatches == 0) 356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!compactResult) 358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back(std::vector<DMatch>()); 359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back(std::vector<DMatch>(nMatches)); 363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch> &curMatches = matches.back(); 364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (int i = 0; i < nMatches; ++i, ++trainIdx_ptr, ++distance_ptr) 366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainIndex = *trainIdx_ptr; 368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float dst = *distance_ptr; 370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DMatch m(queryIdx, trainIndex, 0, dst); 372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler curMatches[i] = m; 374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::sort(curMatches.begin(), curMatches.end()); 377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_radiusMatchDownload(const UMat &trainIdx, const UMat &distance, const UMat &nMatches, 382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector< std::vector<DMatch> > &matches, bool compactResult) 383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainIdx.empty() || distance.empty() || nMatches.empty()) 385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat trainIdxCPU = trainIdx.getMat(ACCESS_READ); 388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat distanceCPU = distance.getMat(ACCESS_READ); 389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat nMatchesCPU = nMatches.getMat(ACCESS_READ); 390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ocl_radiusMatchConvert(trainIdxCPU, distanceCPU, nMatchesCPU, matches, compactResult); 392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/****************************************************************************************\ 395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler* DescriptorMatcher * 396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler\****************************************************************************************/ 397793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDescriptorMatcher::DescriptorCollection::DescriptorCollection() 398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 400793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDescriptorMatcher::DescriptorCollection::DescriptorCollection( const DescriptorCollection& collection ) 401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mergedDescriptors = collection.mergedDescriptors.clone(); 403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::copy( collection.startIdxs.begin(), collection.startIdxs.begin(), startIdxs.begin() ); 404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 406793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDescriptorMatcher::DescriptorCollection::~DescriptorCollection() 407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::DescriptorCollection::set( const std::vector<Mat>& descriptors ) 410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler clear(); 412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t imageCount = descriptors.size(); 414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( imageCount > 0 ); 415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler startIdxs.resize( imageCount ); 417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int dim = -1; 419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int type = -1; 420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler startIdxs[0] = 0; 421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 1; i < imageCount; i++ ) 422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int s = 0; 424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !descriptors[i-1].empty() ) 425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dim = descriptors[i-1].cols; 427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler type = descriptors[i-1].type(); 428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler s = descriptors[i-1].rows; 429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler startIdxs[i] = startIdxs[i-1] + s; 431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( imageCount == 1 ) 433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( descriptors[0].empty() ) return; 435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dim = descriptors[0].cols; 437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler type = descriptors[0].type(); 438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( dim > 0 ); 440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int count = startIdxs[imageCount-1] + descriptors[imageCount-1].rows; 442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( count > 0 ) 444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mergedDescriptors.create( count, dim, type ); 446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 0; i < imageCount; i++ ) 447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !descriptors[i].empty() ) 449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( descriptors[i].cols == dim && descriptors[i].type() == type ); 451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat m = mergedDescriptors.rowRange( startIdxs[i], startIdxs[i] + descriptors[i].rows ); 452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler descriptors[i].copyTo(m); 453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::DescriptorCollection::clear() 459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler startIdxs.clear(); 461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mergedDescriptors.release(); 462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst Mat DescriptorMatcher::DescriptorCollection::getDescriptor( int imgIdx, int localDescIdx ) const 465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( imgIdx < (int)startIdxs.size() ); 467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int globalIdx = startIdxs[imgIdx] + localDescIdx; 468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( globalIdx < (int)size() ); 469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return getDescriptor( globalIdx ); 471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst Mat& DescriptorMatcher::DescriptorCollection::getDescriptors() const 474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return mergedDescriptors; 476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst Mat DescriptorMatcher::DescriptorCollection::getDescriptor( int globalDescIdx ) const 479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( globalDescIdx < size() ); 481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return mergedDescriptors.row( globalDescIdx ); 482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::DescriptorCollection::getLocalIdx( int globalDescIdx, int& imgIdx, int& localDescIdx ) const 485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( (globalDescIdx>=0) && (globalDescIdx < size()) ); 487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<int>::const_iterator img_it = std::upper_bound(startIdxs.begin(), startIdxs.end(), globalDescIdx); 488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler --img_it; 489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler imgIdx = (int)(img_it - startIdxs.begin()); 490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler localDescIdx = globalDescIdx - (*img_it); 491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint DescriptorMatcher::DescriptorCollection::size() const 494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return mergedDescriptors.rows; 496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * DescriptorMatcher 500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void convertMatches( const std::vector<std::vector<DMatch> >& knnMatches, std::vector<DMatch>& matches ) 502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.reserve( knnMatches.size() ); 505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 0; i < knnMatches.size(); i++ ) 506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( knnMatches[i].size() <= 1 ); 508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !knnMatches[i].empty() ) 509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back( knnMatches[i][0] ); 510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 513793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDescriptorMatcher::~DescriptorMatcher() 514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::add( InputArrayOfArrays _descriptors ) 517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(_descriptors.isUMatVector()) 519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<UMat> descriptors; 521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _descriptors.getUMatVector(descriptors); 522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.insert( utrainDescCollection.end(), descriptors.begin(), descriptors.end() ); 523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if(_descriptors.isUMat()) 525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<UMat> descriptors = std::vector<UMat>(1, _descriptors.getUMat()); 527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.insert( utrainDescCollection.end(), descriptors.begin(), descriptors.end() ); 528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if(_descriptors.isMatVector()) 530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> descriptors; 532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _descriptors.getMatVector(descriptors); 533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.insert( trainDescCollection.end(), descriptors.begin(), descriptors.end() ); 534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if(_descriptors.isMat()) 536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> descriptors = std::vector<Mat>(1, _descriptors.getMat()); 538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.insert( trainDescCollection.end(), descriptors.begin(), descriptors.end() ); 539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( _descriptors.isUMat() || _descriptors.isUMatVector() || _descriptors.isMat() || _descriptors.isMatVector() ); 542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst std::vector<Mat>& DescriptorMatcher::getTrainDescriptors() const 545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return trainDescCollection; 547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::clear() 550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.clear(); 552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.clear(); 553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool DescriptorMatcher::empty() const 556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return trainDescCollection.empty() && utrainDescCollection.empty(); 558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::train() 561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::match( InputArray queryDescriptors, InputArray trainDescriptors, 564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch>& matches, InputArray mask ) const 565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<DescriptorMatcher> tempMatcher = clone(true); 567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->add(trainDescriptors); 568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->match( queryDescriptors, matches, std::vector<Mat>(1, mask.getMat()) ); 569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::knnMatch( InputArray queryDescriptors, InputArray trainDescriptors, 572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<std::vector<DMatch> >& matches, int knn, 573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArray mask, bool compactResult ) const 574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<DescriptorMatcher> tempMatcher = clone(true); 576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->add(trainDescriptors); 577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->knnMatch( queryDescriptors, matches, knn, std::vector<Mat>(1, mask.getMat()), compactResult ); 578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::radiusMatch( InputArray queryDescriptors, InputArray trainDescriptors, 581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<std::vector<DMatch> >& matches, float maxDistance, InputArray mask, 582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bool compactResult ) const 583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<DescriptorMatcher> tempMatcher = clone(true); 585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->add(trainDescriptors); 586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler tempMatcher->radiusMatch( queryDescriptors, matches, maxDistance, std::vector<Mat>(1, mask.getMat()), compactResult ); 587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::match( InputArray queryDescriptors, std::vector<DMatch>& matches, InputArrayOfArrays masks ) 590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<std::vector<DMatch> > knnMatches; 592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler knnMatch( queryDescriptors, knnMatches, 1, masks, true /*compactResult*/ ); 593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler convertMatches( knnMatches, matches ); 594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::checkMasks( InputArrayOfArrays _masks, int queryDescriptorsCount ) const 597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> masks; 599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _masks.getMatVector(masks); 600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( isMaskSupported() && !masks.empty() ) 602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // Check masks 604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t imageCount = std::max(trainDescCollection.size(), utrainDescCollection.size() ); 605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( masks.size() == imageCount ); 606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 0; i < imageCount; i++ ) 607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !masks[i].empty() && (!trainDescCollection[i].empty() || !utrainDescCollection[i].empty() ) ) 609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int rows = trainDescCollection[i].empty() ? utrainDescCollection[i].rows : trainDescCollection[i].rows; 611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( masks[i].rows == queryDescriptorsCount && 612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (masks[i].cols == rows || masks[i].cols == rows) && 613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler masks[i].type() == CV_8UC1 ); 614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::knnMatch( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, int knn, 620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArrayOfArrays masks, bool compactResult ) 621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( empty() || queryDescriptors.empty() ) 623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( knn > 0 ); 626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler checkMasks( masks, queryDescriptors.size().height ); 628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler train(); 630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler knnMatchImpl( queryDescriptors, matches, knn, masks, compactResult ); 631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::radiusMatch( InputArray queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, 634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArrayOfArrays masks, bool compactResult ) 635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( empty() || queryDescriptors.empty() ) 638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( maxDistance > std::numeric_limits<float>::epsilon() ); 641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler checkMasks( masks, queryDescriptors.size().height ); 643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler train(); 645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler radiusMatchImpl( queryDescriptors, matches, maxDistance, masks, compactResult ); 646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::read( const FileNode& ) 649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid DescriptorMatcher::write( FileStorage& ) const 652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{} 653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool DescriptorMatcher::isPossibleMatch( InputArray _mask, int queryIdx, int trainIdx ) 655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat mask = _mask.getMat(); 657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return mask.empty() || mask.at<uchar>(queryIdx, trainIdx); 658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool DescriptorMatcher::isMaskedOut( InputArrayOfArrays _masks, int queryIdx ) 661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> masks; 663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _masks.getMatVector(masks); 664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size_t outCount = 0; 666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 0; i < masks.size(); i++ ) 667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !masks[i].empty() && (countNonZero(masks[i].row(queryIdx)) == 0) ) 669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler outCount++; 670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return !masks.empty() && outCount == masks.size() ; 673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler////////////////////////////////////////////////////// BruteForceMatcher ///////////////////////////////////////////////// 677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 678793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBFMatcher::BFMatcher( int _normType, bool _crossCheck ) 679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler normType = _normType; 681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler crossCheck = _crossCheck; 682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 684793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPtr<DescriptorMatcher> BFMatcher::clone( bool emptyTrainData ) const 685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<BFMatcher> matcher = makePtr<BFMatcher>(normType, crossCheck); 687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !emptyTrainData ) 688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matcher->trainDescCollection.resize(trainDescCollection.size()); 690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::transform( trainDescCollection.begin(), trainDescCollection.end(), 691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matcher->trainDescCollection.begin(), clone_op ); 692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return matcher; 694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_match(InputArray query, InputArray _train, std::vector< std::vector<DMatch> > &matches, int dstType) 697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat trainIdx, distance; 699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_matchSingle(query, _train, trainIdx, distance, dstType)) 700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_matchDownload(trainIdx, distance, matches)) 702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_knnMatch(InputArray query, InputArray _train, std::vector< std::vector<DMatch> > &matches, int k, int dstType, bool compactResult) 707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat trainIdx, distance; 709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (k != 2) 710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_knnMatchSingle(query, _train, trainIdx, distance, dstType)) 712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_knnMatchDownload(trainIdx, distance, matches, compactResult) ) 714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid BFMatcher::knnMatchImpl( InputArray _queryDescriptors, std::vector<std::vector<DMatch> >& matches, int knn, 719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArrayOfArrays _masks, bool compactResult ) 720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescType = trainDescCollection.empty() ? utrainDescCollection[0].type() : trainDescCollection[0].type(); 722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( _queryDescriptors.type() == trainDescType ); 723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int IMGIDX_SHIFT = 18; 725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int IMGIDX_ONE = (1 << IMGIDX_SHIFT); 726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( _queryDescriptors.empty() || (trainDescCollection.empty() && utrainDescCollection.empty())) 728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> masks; 734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _masks.getMatVector(masks); 735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!trainDescCollection.empty() && !utrainDescCollection.empty()) 737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)utrainDescCollection.size(); i++) 739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat tempMat; 741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection[i].copyTo(tempMat); 742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.push_back(tempMat); 743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.clear(); 745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescVectorSize = trainDescCollection.empty() ? (int)utrainDescCollection.size() : (int)trainDescCollection.size(); 748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Size trainDescSize = trainDescCollection.empty() ? utrainDescCollection[0].size() : trainDescCollection[0].size(); 749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescOffset = trainDescCollection.empty() ? (int)utrainDescCollection[0].offset : 0; 750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ( ocl::useOpenCL() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 && 752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _queryDescriptors.type() == CV_32FC1 && _queryDescriptors.offset() == 0 && trainDescOffset == 0 && 753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescSize.width == _queryDescriptors.size().width && masks.size() == 1 && masks[0].total() == 0 ) 754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(knn == 1) 756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(trainDescCollection.empty()) 758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(ocl_match(_queryDescriptors, utrainDescCollection[0], matches, normType)) 760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(ocl_match(_queryDescriptors, trainDescCollection[0], matches, normType)) 768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(trainDescCollection.empty()) 777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(ocl_knnMatch(_queryDescriptors, utrainDescCollection[0], matches, knn, normType, compactResult) ) 779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(ocl_knnMatch(_queryDescriptors, trainDescCollection[0], matches, knn, normType, compactResult) ) 787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat queryDescriptors = _queryDescriptors.getMat(); 796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(trainDescCollection.empty() && !utrainDescCollection.empty()) 797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)utrainDescCollection.size(); i++) 799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat tempMat; 801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection[i].copyTo(tempMat); 802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.push_back(tempMat); 803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.clear(); 805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.reserve(queryDescriptors.rows); 808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat dist, nidx; 810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int iIdx, imgCount = (int)trainDescCollection.size(), update = 0; 812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int dtype = normType == NORM_HAMMING || normType == NORM_HAMMING2 || 813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (normType == NORM_L1 && queryDescriptors.type() == CV_8U) ? CV_32S : CV_32F; 814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( (int64)imgCount*IMGIDX_ONE < INT_MAX ); 816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( iIdx = 0; iIdx < imgCount; iIdx++ ) 818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( trainDescCollection[iIdx].rows < IMGIDX_ONE ); 820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler batchDistance(queryDescriptors, trainDescCollection[iIdx], dist, dtype, nidx, 821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler normType, knn, masks.empty() ? Mat() : masks[iIdx], update, crossCheck); 822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler update += IMGIDX_ONE; 823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( dtype == CV_32S ) 826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat temp; 828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist.convertTo(temp, CV_32F); 829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist = temp; 830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ ) 833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const float* distptr = dist.ptr<float>(qIdx); 835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int* nidxptr = nidx.ptr<int>(qIdx); 836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.push_back( std::vector<DMatch>() ); 838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch>& mq = matches.back(); 839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mq.reserve(knn); 840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int k = 0; k < nidx.cols; k++ ) 842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( nidxptr[k] < 0 ) 844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mq.push_back( DMatch(qIdx, nidxptr[k] & (IMGIDX_ONE - 1), 846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler nidxptr[k] >> IMGIDX_SHIFT, distptr[k]) ); 847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( mq.empty() && compactResult ) 850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.pop_back(); 851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic bool ocl_radiusMatch(InputArray query, InputArray _train, std::vector< std::vector<DMatch> > &matches, 855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float maxDistance, int dstType, bool compactResult) 856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UMat trainIdx, distance, nMatches; 858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_radiusMatchSingle(query, _train, trainIdx, distance, nMatches, maxDistance, dstType)) 859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!ocl_radiusMatchDownload(trainIdx, distance, nMatches, matches, compactResult)) 861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return true; 863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid BFMatcher::radiusMatchImpl( InputArray _queryDescriptors, std::vector<std::vector<DMatch> >& matches, 866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float maxDistance, InputArrayOfArrays _masks, bool compactResult ) 867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescType = trainDescCollection.empty() ? utrainDescCollection[0].type() : trainDescCollection[0].type(); 869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( _queryDescriptors.type() == trainDescType ); 870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( _queryDescriptors.empty() || (trainDescCollection.empty() && utrainDescCollection.empty())) 872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.clear(); 874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<Mat> masks; 878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _masks.getMatVector(masks); 879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(!trainDescCollection.empty() && !utrainDescCollection.empty()) 881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)utrainDescCollection.size(); i++) 883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat tempMat; 885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection[i].copyTo(tempMat); 886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.push_back(tempMat); 887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.clear(); 889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescVectorSize = trainDescCollection.empty() ? (int)utrainDescCollection.size() : (int)trainDescCollection.size(); 892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Size trainDescSize = trainDescCollection.empty() ? utrainDescCollection[0].size() : trainDescCollection[0].size(); 893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int trainDescOffset = trainDescCollection.empty() ? (int)utrainDescCollection[0].offset : 0; 894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ( ocl::useOpenCL() && _queryDescriptors.isUMat() && _queryDescriptors.dims()<=2 && trainDescVectorSize == 1 && 896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _queryDescriptors.type() == CV_32FC1 && _queryDescriptors.offset() == 0 && trainDescOffset == 0 && 897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescSize.width == _queryDescriptors.size().width && masks.size() == 1 && masks[0].total() == 0 ) 898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (trainDescCollection.empty()) 900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(ocl_radiusMatch(_queryDescriptors, utrainDescCollection[0], matches, maxDistance, normType, compactResult) ) 902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ocl_radiusMatch(_queryDescriptors, trainDescCollection[0], matches, maxDistance, normType, compactResult) ) 910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_IMPL_ADD(CV_IMPL_OCL); 912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat queryDescriptors = _queryDescriptors.getMat(); 918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if(trainDescCollection.empty() && !utrainDescCollection.empty()) 919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)utrainDescCollection.size(); i++) 921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat tempMat; 923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection[i].copyTo(tempMat); 924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.push_back(tempMat); 925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler utrainDescCollection.clear(); 927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.resize(queryDescriptors.rows); 930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat dist, distf; 931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int iIdx, imgCount = (int)trainDescCollection.size(); 933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int dtype = normType == NORM_HAMMING || 934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (normType == NORM_L1 && queryDescriptors.type() == CV_8U) ? CV_32S : CV_32F; 935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( iIdx = 0; iIdx < imgCount; iIdx++ ) 937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler batchDistance(queryDescriptors, trainDescCollection[iIdx], dist, dtype, noArray(), 939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler normType, 0, masks.empty() ? Mat() : masks[iIdx], 0, false); 940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( dtype == CV_32S ) 941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist.convertTo(distf, CV_32F); 942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler distf = dist; 944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ ) 946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const float* distptr = distf.ptr<float>(qIdx); 948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<DMatch>& mq = matches[qIdx]; 950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int k = 0; k < distf.cols; k++ ) 951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( distptr[k] <= maxDistance ) 953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mq.push_back( DMatch(qIdx, k, iIdx, distptr[k]) ); 954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int qIdx0 = 0; 959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ ) 960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( matches[qIdx].empty() && compactResult ) 962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler continue; 963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( qIdx0 < qIdx ) 965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::swap(matches[qIdx], matches[qIdx0]); 966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::sort( matches[qIdx0].begin(), matches[qIdx0].end() ); 968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler qIdx0++; 969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/////////////////////////////////////////////////////////////////////////////////////////////////////// 973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Factory function for DescriptorMatcher creating 976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 977793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPtr<DescriptorMatcher> DescriptorMatcher::create( const String& descriptorMatcherType ) 978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<DescriptorMatcher> dm; 980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !descriptorMatcherType.compare( "FlannBased" ) ) 981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<FlannBasedMatcher>(); 983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( !descriptorMatcherType.compare( "BruteForce" ) ) // L2 985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<BFMatcher>(int(NORM_L2)); // anonymous enums can't be template parameters 987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( !descriptorMatcherType.compare( "BruteForce-SL2" ) ) // Squared L2 989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<BFMatcher>(int(NORM_L2SQR)); 991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( !descriptorMatcherType.compare( "BruteForce-L1" ) ) 993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<BFMatcher>(int(NORM_L1)); 995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( !descriptorMatcherType.compare("BruteForce-Hamming") || 997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler !descriptorMatcherType.compare("BruteForce-HammingLUT") ) 998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<BFMatcher>(int(NORM_HAMMING)); 1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if( !descriptorMatcherType.compare("BruteForce-Hamming(2)") ) 1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dm = makePtr<BFMatcher>(int(NORM_HAMMING2)); 1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Error( Error::StsBadArg, "Unknown matcher name" ); 1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return dm; 1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Flann based matcher 1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerFlannBasedMatcher::FlannBasedMatcher( const Ptr<flann::IndexParams>& _indexParams, const Ptr<flann::SearchParams>& _searchParams ) 1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler : indexParams(_indexParams), searchParams(_searchParams), addedDescCount(0) 1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( _indexParams ); 1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert( _searchParams ); 1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::add( InputArrayOfArrays _descriptors ) 1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DescriptorMatcher::add( _descriptors ); 1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<UMat> descriptors; 1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler _descriptors.getUMatVector(descriptors); 1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( size_t i = 0; i < descriptors.size(); i++ ) 1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler addedDescCount += descriptors[i].rows; 1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::clear() 1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DescriptorMatcher::clear(); 1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mergedDescriptors.clear(); 1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flannIndex.release(); 1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler addedDescCount = 0; 1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::train() 1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !flannIndex || mergedDescriptors.size() < addedDescCount ) 1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler // FIXIT: Workaround for 'utrainDescCollection' issue (PR #2142) 1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!utrainDescCollection.empty()) 1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert(trainDescCollection.size() == 0); 1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (size_t i = 0; i < utrainDescCollection.size(); ++i) 1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler trainDescCollection.push_back(utrainDescCollection[i].getMat(ACCESS_READ)); 1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler mergedDescriptors.set( trainDescCollection ); 1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flannIndex = makePtr<flann::Index>( mergedDescriptors.getDescriptors(), *indexParams ); 1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::read( const FileNode& fn) 1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!indexParams) 1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams = makePtr<flann::IndexParams>(); 1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler FileNode ip = fn["indexParams"]; 1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert(ip.type() == FileNode::SEQ); 1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)ip.size(); ++i) 1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert(ip[i].type() == FileNode::MAP); 1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler String _name = (String)ip[i]["name"]; 1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int type = (int)ip[i]["type"]; 1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(type) 1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8U: 1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8S: 1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16U: 1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16S: 1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32S: 1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setInt(_name, (int) ip[i]["value"]); 1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32F: 1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setFloat(_name, (float) ip[i]["value"]); 1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_64F: 1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setDouble(_name, (double) ip[i]["value"]); 1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_USRTYPE1: 1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setString(_name, (String) ip[i]["value"]); 1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,2): 1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setBool(_name, (int) ip[i]["value"] != 0); 1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,3): 1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->setAlgorithm((int) ip[i]["value"]); 1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler }; 1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!searchParams) 1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams = makePtr<flann::SearchParams>(); 1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler FileNode sp = fn["searchParams"]; 1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert(sp.type() == FileNode::SEQ); 1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(int i = 0; i < (int)sp.size(); ++i) 1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Assert(sp[i].type() == FileNode::MAP); 1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler String _name = (String)sp[i]["name"]; 1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int type = (int)sp[i]["type"]; 1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(type) 1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8U: 1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8S: 1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16U: 1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16S: 1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32S: 1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setInt(_name, (int) sp[i]["value"]); 1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32F: 1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setFloat(_name, (float) ip[i]["value"]); 1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_64F: 1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setDouble(_name, (double) ip[i]["value"]); 1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_USRTYPE1: 1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setString(_name, (String) ip[i]["value"]); 1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,2): 1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setBool(_name, (int) ip[i]["value"] != 0); 1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,3): 1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->setAlgorithm((int) ip[i]["value"]); 1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler }; 1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flannIndex.release(); 1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::write( FileStorage& fs) const 1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "indexParams" << "["; 1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (indexParams) 1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<String> names; 1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<int> types; 1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<String> strValues; 1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<double> numValues; 1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler indexParams->getAll(names, types, strValues, numValues); 1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(size_t i = 0; i < names.size(); ++i) 1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "{" << "name" << names[i] << "type" << types[i] << "value"; 1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(types[i]) 1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8U: 1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (uchar)numValues[i]; 1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8S: 1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (char)numValues[i]; 1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16U: 1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (ushort)numValues[i]; 1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16S: 1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (short)numValues[i]; 1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32S: 1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,2): 1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,3): 1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (int)numValues[i]; 1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32F: 1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (float)numValues[i]; 1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_64F: 1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (double)numValues[i]; 1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_USRTYPE1: 1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << strValues[i]; 1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (double)numValues[i]; 1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "typename" << strValues[i]; 1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "}"; 1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "]" << "searchParams" << "["; 1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (searchParams) 1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<String> names; 1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<int> types; 1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<String> strValues; 1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<double> numValues; 1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler searchParams->getAll(names, types, strValues, numValues); 1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for(size_t i = 0; i < names.size(); ++i) 1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "{" << "name" << names[i] << "type" << types[i] << "value"; 1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch(types[i]) 1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8U: 1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (uchar)numValues[i]; 1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_8S: 1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (char)numValues[i]; 1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16U: 1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (ushort)numValues[i]; 1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_16S: 1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (short)numValues[i]; 1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32S: 1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,2): 1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_MAKETYPE(CV_USRTYPE1,3): 1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (int)numValues[i]; 1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_32F: 1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (float)numValues[i]; 1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_64F: 1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (double)numValues[i]; 1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CV_USRTYPE1: 1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << strValues[i]; 1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << (double)numValues[i]; 1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "typename" << strValues[i]; 1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "}"; 1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fs << "]"; 1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerbool FlannBasedMatcher::isMaskSupported() const 1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return false; 1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPtr<DescriptorMatcher> FlannBasedMatcher::clone( bool emptyTrainData ) const 1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Ptr<FlannBasedMatcher> matcher = makePtr<FlannBasedMatcher>(indexParams, searchParams); 1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( !emptyTrainData ) 1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CV_Error( Error::StsNotImplemented, "deep clone functionality is not implemented, because " 1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "Flann::Index has not copy constructor or clone method "); 1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler //matcher->flannIndex; 1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matcher->addedDescCount = addedDescCount; 1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matcher->mergedDescriptors = DescriptorCollection( mergedDescriptors ); 1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::transform( trainDescCollection.begin(), trainDescCollection.end(), 1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matcher->trainDescCollection.begin(), clone_op ); 1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return matcher; 1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::convertToDMatches( const DescriptorCollection& collection, const Mat& indices, const Mat& dists, 1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler std::vector<std::vector<DMatch> >& matches ) 1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches.resize( indices.rows ); 1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int i = 0; i < indices.rows; i++ ) 1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int j = 0; j < indices.cols; j++ ) 1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int idx = indices.at<int>(i, j); 1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if( idx >= 0 ) 1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int imgIdx, trainIdx; 1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler collection.getLocalIdx( idx, imgIdx, trainIdx ); 1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler float dist = 0; 1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (dists.type() == CV_32S) 1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist = static_cast<float>( dists.at<int>(i,j) ); 1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist = std::sqrt(dists.at<float>(i,j)); 1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler matches[i].push_back( DMatch( i, trainIdx, imgIdx, dist ) ); 1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::knnMatchImpl( InputArray _queryDescriptors, std::vector<std::vector<DMatch> >& matches, int knn, 1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArrayOfArrays /*masks*/, bool /*compactResult*/ ) 1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat queryDescriptors = _queryDescriptors.getMat(); 1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat indices( queryDescriptors.rows, knn, CV_32SC1 ); 1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat dists( queryDescriptors.rows, knn, CV_32FC1); 1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flannIndex->knnSearch( queryDescriptors, indices, dists, knn, *searchParams ); 1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler convertToDMatches( mergedDescriptors, indices, dists, matches ); 1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid FlannBasedMatcher::radiusMatchImpl( InputArray _queryDescriptors, std::vector<std::vector<DMatch> >& matches, float maxDistance, 1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler InputArrayOfArrays /*masks*/, bool /*compactResult*/ ) 1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat queryDescriptors = _queryDescriptors.getMat(); 1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler const int count = mergedDescriptors.size(); // TODO do count as param? 1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat indices( queryDescriptors.rows, count, CV_32SC1, Scalar::all(-1) ); 1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat dists( queryDescriptors.rows, count, CV_32FC1, Scalar::all(-1) ); 1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for( int qIdx = 0; qIdx < queryDescriptors.rows; qIdx++ ) 1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat queryDescriptorsRow = queryDescriptors.row(qIdx); 1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat indicesRow = indices.row(qIdx); 1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Mat distsRow = dists.row(qIdx); 1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler flannIndex->radiusSearch( queryDescriptorsRow, indicesRow, distsRow, maxDistance*maxDistance, count, *searchParams ); 1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler convertToDMatches( mergedDescriptors, indices, dists, matches ); 1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1324