fixed gpu::filter2D border interpolation for CV_32FC1 type

added additional tests for gpu filters
fixed gpu features2D tests
This commit is contained in:
Vladislav Vinogradov
2012-03-21 14:38:23 +00:00
parent c1a6cb6221
commit 059cef57e6
16 changed files with 1730 additions and 1515 deletions

View File

@@ -41,12 +41,74 @@
#include "precomp.hpp"
#ifdef HAVE_CUDA
namespace {
using namespace cvtest;
using namespace testing;
bool keyPointsEquals(const cv::KeyPoint& p1, const cv::KeyPoint& p2)
{
const double maxPtDif = 1.0;
const double maxSizeDif = 1.0;
const double maxAngleDif = 2.0;
const double maxResponseDif = 0.1;
int getValidMatchesCount(const std::vector<cv::KeyPoint>& keypoints1, const std::vector<cv::KeyPoint>& keypoints2, const std::vector<cv::DMatch>& matches)
double dist = cv::norm(p1.pt - p2.pt);
if (dist < maxPtDif &&
fabs(p1.size - p2.size) < maxSizeDif &&
abs(p1.angle - p2.angle) < maxAngleDif &&
abs(p1.response - p2.response) < maxResponseDif &&
p1.octave == p2.octave &&
p1.class_id == p2.class_id)
{
return true;
}
return false;
}
struct KeyPointLess : std::binary_function<cv::KeyPoint, cv::KeyPoint, bool>
{
bool operator()(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2) const
{
return kp1.pt.y < kp2.pt.y || (kp1.pt.y == kp2.pt.y && kp1.pt.x < kp2.pt.x);
}
};
testing::AssertionResult assertKeyPointsEquals(const char* gold_expr, const char* actual_expr, std::vector<cv::KeyPoint>& gold, std::vector<cv::KeyPoint>& actual)
{
if (gold.size() != actual.size())
{
return testing::AssertionFailure() << "KeyPoints size mistmach\n"
<< "\"" << gold_expr << "\" : " << gold.size() << "\n"
<< "\"" << actual_expr << "\" : " << actual.size();
}
std::sort(actual.begin(), actual.end(), KeyPointLess());
std::sort(gold.begin(), gold.end(), KeyPointLess());
for (size_t i; i < gold.size(); ++i)
{
const cv::KeyPoint& p1 = gold[i];
const cv::KeyPoint& p2 = actual[i];
if (!keyPointsEquals(p1, p2))
{
return testing::AssertionFailure() << "KeyPoints differ at " << i << "\n"
<< "\"" << gold_expr << "\" vs \"" << actual_expr << "\" : \n"
<< "pt : " << testing::PrintToString(p1.pt) << " vs " << testing::PrintToString(p2.pt) << "\n"
<< "size : " << p1.size << " vs " << p2.size << "\n"
<< "angle : " << p1.angle << " vs " << p2.angle << "\n"
<< "response : " << p1.response << " vs " << p2.response << "\n"
<< "octave : " << p1.octave << " vs " << p2.octave << "\n"
<< "class_id : " << p1.class_id << " vs " << p2.class_id;
}
}
return ::testing::AssertionSuccess();
}
#define ASSERT_KEYPOINTS_EQ(gold, actual) EXPECT_PRED_FORMAT2(assertKeyPointsEquals, gold, actual);
int getMatchedPointsCount(const std::vector<cv::KeyPoint>& keypoints1, const std::vector<cv::KeyPoint>& keypoints2, const std::vector<cv::DMatch>& matches)
{
int validCount = 0;
@@ -57,22 +119,8 @@ int getValidMatchesCount(const std::vector<cv::KeyPoint>& keypoints1, const std:
const cv::KeyPoint& p1 = keypoints1[m.queryIdx];
const cv::KeyPoint& p2 = keypoints2[m.trainIdx];
const float maxPtDif = 1.f;
const float maxSizeDif = 1.f;
const float maxAngleDif = 2.f;
const float maxResponseDif = 0.1f;
float dist = (float) cv::norm(p1.pt - p2.pt);
if (dist < maxPtDif &&
fabs(p1.size - p2.size) < maxSizeDif &&
abs(p1.angle - p2.angle) < maxAngleDif &&
abs(p1.response - p2.response) < maxResponseDif &&
p1.octave == p2.octave &&
p1.class_id == p2.class_id)
{
if (keyPointsEquals(p1, p2))
++validCount;
}
}
return validCount;
@@ -81,78 +129,280 @@ int getValidMatchesCount(const std::vector<cv::KeyPoint>& keypoints1, const std:
/////////////////////////////////////////////////////////////////////////////////////////////////
// SURF
struct SURF : TestWithParam<cv::gpu::DeviceInfo>
IMPLEMENT_PARAM_CLASS(SURF_HessianThreshold, double)
IMPLEMENT_PARAM_CLASS(SURF_Octaves, int)
IMPLEMENT_PARAM_CLASS(SURF_OctaveLayers, int)
IMPLEMENT_PARAM_CLASS(SURF_Extended, bool)
IMPLEMENT_PARAM_CLASS(SURF_Upright, bool)
PARAM_TEST_CASE(SURF, cv::gpu::DeviceInfo, SURF_HessianThreshold, SURF_Octaves, SURF_OctaveLayers, SURF_Extended, SURF_Upright)
{
cv::gpu::DeviceInfo devInfo;
cv::Mat image;
cv::Mat mask;
std::vector<cv::KeyPoint> keypoints_gold;
std::vector<float> descriptors_gold;
double hessianThreshold;
int nOctaves;
int nOctaveLayers;
bool extended;
bool upright;
virtual void SetUp()
{
devInfo = GetParam();
devInfo = GET_PARAM(0);
hessianThreshold = GET_PARAM(1);
nOctaves = GET_PARAM(2);
nOctaveLayers = GET_PARAM(3);
extended = GET_PARAM(4);
upright = GET_PARAM(5);
cv::gpu::setDevice(devInfo.deviceID());
image = readImage("features2d/aloe.png", CV_LOAD_IMAGE_GRAYSCALE);
ASSERT_FALSE(image.empty());
mask = cv::Mat(image.size(), CV_8UC1, cv::Scalar::all(1));
mask(cv::Range(0, image.rows / 2), cv::Range(0, image.cols / 2)).setTo(cv::Scalar::all(0));
cv::SURF fdetector_gold;
fdetector_gold.extended = false;
fdetector_gold(image, mask, keypoints_gold, descriptors_gold);
}
};
TEST_P(SURF, EmptyDataTest)
TEST_P(SURF, Detector)
{
cv::gpu::SURF_GPU fdetector;
cv::Mat image = readImage("features2d/aloe.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
cv::gpu::SURF_GPU surf;
surf.hessianThreshold = hessianThreshold;
surf.nOctaves = nOctaves;
surf.nOctaveLayers = nOctaveLayers;
surf.extended = extended;
surf.upright = upright;
surf.keypointsRatio = 0.05f;
cv::gpu::GpuMat image;
std::vector<cv::KeyPoint> keypoints;
std::vector<float> descriptors;
surf(loadMat(image), cv::gpu::GpuMat(), keypoints);
fdetector(image, cv::gpu::GpuMat(), keypoints, descriptors);
cv::SURF surf_gold;
surf_gold.hessianThreshold = hessianThreshold;
surf_gold.nOctaves = nOctaves;
surf_gold.nOctaveLayers = nOctaveLayers;
surf_gold.extended = extended;
surf_gold.upright = upright;
EXPECT_TRUE(keypoints.empty());
EXPECT_TRUE(descriptors.empty());
std::vector<cv::KeyPoint> keypoints_gold;
surf_gold(image, cv::noArray(), keypoints_gold);
ASSERT_KEYPOINTS_EQ(keypoints_gold, keypoints);
}
TEST_P(SURF, Accuracy)
TEST_P(SURF, Detector_Masked)
{
cv::Mat image = readImage("features2d/aloe.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
cv::Mat mask(image.size(), CV_8UC1, cv::Scalar::all(1));
mask(cv::Range(0, image.rows / 2), cv::Range(0, image.cols / 2)).setTo(cv::Scalar::all(0));
cv::gpu::SURF_GPU surf;
surf.hessianThreshold = hessianThreshold;
surf.nOctaves = nOctaves;
surf.nOctaveLayers = nOctaveLayers;
surf.extended = extended;
surf.upright = upright;
surf.keypointsRatio = 0.05f;
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
surf(loadMat(image), loadMat(mask), keypoints);
cv::gpu::GpuMat dev_descriptors;
cv::gpu::SURF_GPU fdetector; fdetector.extended = false;
cv::SURF surf_gold;
surf_gold.hessianThreshold = hessianThreshold;
surf_gold.nOctaves = nOctaves;
surf_gold.nOctaveLayers = nOctaveLayers;
surf_gold.extended = extended;
surf_gold.upright = upright;
fdetector(loadMat(image), loadMat(mask), keypoints, dev_descriptors);
std::vector<cv::KeyPoint> keypoints_gold;
surf_gold(image, mask, keypoints_gold);
dev_descriptors.download(descriptors);
ASSERT_KEYPOINTS_EQ(keypoints_gold, keypoints);
}
TEST_P(SURF, Descriptor)
{
cv::Mat image = readImage("features2d/aloe.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
cv::gpu::SURF_GPU surf;
surf.hessianThreshold = hessianThreshold;
surf.nOctaves = nOctaves;
surf.nOctaveLayers = nOctaveLayers;
surf.extended = extended;
surf.upright = upright;
surf.keypointsRatio = 0.05f;
cv::SURF surf_gold;
surf_gold.hessianThreshold = hessianThreshold;
surf_gold.nOctaves = nOctaves;
surf_gold.nOctaveLayers = nOctaveLayers;
surf_gold.extended = extended;
surf_gold.upright = upright;
std::vector<cv::KeyPoint> keypoints;
surf_gold(image, cv::noArray(), keypoints);
cv::gpu::GpuMat descriptors;
surf(loadMat(image), cv::gpu::GpuMat(), keypoints, descriptors, true);
cv::Mat descriptors_gold;
surf_gold(image, cv::noArray(), keypoints, descriptors_gold, true);
cv::BFMatcher matcher(cv::NORM_L2);
std::vector<cv::DMatch> matches;
matcher.match(descriptors_gold, cv::Mat(descriptors), matches);
matcher.match(cv::Mat(static_cast<int>(keypoints_gold.size()), 64, CV_32FC1, &descriptors_gold[0]), descriptors, matches);
int matchedCount = getMatchedPointsCount(keypoints, keypoints, matches);
double matchedRatio = static_cast<double>(matchedCount) / keypoints.size();
int validCount = getValidMatchesCount(keypoints_gold, keypoints, matches);
double validRatio = (double) validCount / matches.size();
EXPECT_GT(validRatio, 0.5);
EXPECT_GT(matchedRatio, 0.35);
}
INSTANTIATE_TEST_CASE_P(Features2D, SURF, DEVICES(cv::gpu::GLOBAL_ATOMICS));
INSTANTIATE_TEST_CASE_P(GPU_Features2D, SURF, testing::Combine(
ALL_DEVICES,
testing::Values(SURF_HessianThreshold(100.0), SURF_HessianThreshold(500.0), SURF_HessianThreshold(1000.0)),
testing::Values(SURF_Octaves(3), SURF_Octaves(4)),
testing::Values(SURF_OctaveLayers(2), SURF_OctaveLayers(3)),
testing::Values(SURF_Extended(false), SURF_Extended(true)),
testing::Values(SURF_Upright(false), SURF_Upright(true))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// FAST
IMPLEMENT_PARAM_CLASS(FAST_Threshold, int)
IMPLEMENT_PARAM_CLASS(FAST_NonmaxSupression, bool)
PARAM_TEST_CASE(FAST, cv::gpu::DeviceInfo, FAST_Threshold, FAST_NonmaxSupression)
{
cv::gpu::DeviceInfo devInfo;
int threshold;
bool nonmaxSupression;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
threshold = GET_PARAM(1);
nonmaxSupression = GET_PARAM(2);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(FAST, Accuracy)
{
cv::Mat image = readImage("features2d/aloe.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
cv::gpu::FAST_GPU fast(threshold);
fast.nonmaxSupression = nonmaxSupression;
std::vector<cv::KeyPoint> keypoints;
fast(loadMat(image), cv::gpu::GpuMat(), keypoints);
std::vector<cv::KeyPoint> keypoints_gold;
cv::FAST(image, keypoints_gold, threshold, nonmaxSupression);
ASSERT_KEYPOINTS_EQ(keypoints_gold, keypoints);
}
INSTANTIATE_TEST_CASE_P(GPU_Features2D, FAST, testing::Combine(
ALL_DEVICES,
testing::Values(FAST_Threshold(25), FAST_Threshold(50)),
testing::Values(FAST_NonmaxSupression(false), FAST_NonmaxSupression(true))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// ORB
IMPLEMENT_PARAM_CLASS(ORB_FeaturesCount, int)
IMPLEMENT_PARAM_CLASS(ORB_ScaleFactor, float)
IMPLEMENT_PARAM_CLASS(ORB_LevelsCount, int)
IMPLEMENT_PARAM_CLASS(ORB_EdgeThreshold, int)
IMPLEMENT_PARAM_CLASS(ORB_firstLevel, int)
IMPLEMENT_PARAM_CLASS(ORB_WTA_K, int)
IMPLEMENT_PARAM_CLASS(ORB_PatchSize, int)
IMPLEMENT_PARAM_CLASS(ORB_BlurForDescriptor, bool)
CV_ENUM(ORB_ScoreType, cv::ORB::HARRIS_SCORE, cv::ORB::FAST_SCORE)
PARAM_TEST_CASE(ORB, cv::gpu::DeviceInfo, ORB_FeaturesCount, ORB_ScaleFactor, ORB_LevelsCount, ORB_EdgeThreshold, ORB_firstLevel, ORB_WTA_K, ORB_ScoreType, ORB_PatchSize, ORB_BlurForDescriptor)
{
cv::gpu::DeviceInfo devInfo;
int nFeatures;
float scaleFactor;
int nLevels;
int edgeThreshold;
int firstLevel;
int WTA_K;
int scoreType;
int patchSize;
bool blurForDescriptor;
virtual void SetUp()
{
devInfo = GET_PARAM(0);
nFeatures = GET_PARAM(1);
scaleFactor = GET_PARAM(2);
nLevels = GET_PARAM(3);
edgeThreshold = GET_PARAM(4);
firstLevel = GET_PARAM(5);
WTA_K = GET_PARAM(6);
scoreType = GET_PARAM(7);
patchSize = GET_PARAM(8);
blurForDescriptor = GET_PARAM(9);
cv::gpu::setDevice(devInfo.deviceID());
}
};
TEST_P(ORB, Accuracy)
{
cv::Mat image = readImage("features2d/aloe.png", cv::IMREAD_GRAYSCALE);
ASSERT_FALSE(image.empty());
cv::Mat mask(image.size(), CV_8UC1, cv::Scalar::all(1));
mask(cv::Range(0, image.rows / 2), cv::Range(0, image.cols / 2)).setTo(cv::Scalar::all(0));
cv::gpu::ORB_GPU orb(nFeatures, scaleFactor, nLevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize);
orb.blurForDescriptor = blurForDescriptor;
std::vector<cv::KeyPoint> keypoints;
cv::gpu::GpuMat descriptors;
orb(loadMat(image), loadMat(mask), keypoints, descriptors);
cv::ORB orb_gold(nFeatures, scaleFactor, nLevels, edgeThreshold, firstLevel, WTA_K, scoreType, patchSize);
std::vector<cv::KeyPoint> keypoints_gold;
cv::Mat descriptors_gold;
orb_gold(image, mask, keypoints_gold, descriptors_gold);
cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;
matcher.match(descriptors_gold, cv::Mat(descriptors), matches);
int matchedCount = getMatchedPointsCount(keypoints_gold, keypoints, matches);
double matchedRatio = static_cast<double>(matchedCount) / keypoints.size();
EXPECT_GT(matchedRatio, 0.35);
}
INSTANTIATE_TEST_CASE_P(GPU_Features2D, ORB, testing::Combine(
ALL_DEVICES,
testing::Values(ORB_FeaturesCount(1000)),
testing::Values(ORB_ScaleFactor(1.2f)),
testing::Values(ORB_LevelsCount(4), ORB_LevelsCount(8)),
testing::Values(ORB_EdgeThreshold(31)),
testing::Values(ORB_firstLevel(0), ORB_firstLevel(2)),
testing::Values(ORB_WTA_K(2), ORB_WTA_K(3), ORB_WTA_K(4)),
testing::Values(ORB_ScoreType(cv::ORB::HARRIS_SCORE)),
testing::Values(ORB_PatchSize(31), ORB_PatchSize(29)),
testing::Values(ORB_BlurForDescriptor(false), ORB_BlurForDescriptor(true))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// BruteForceMatcher
PARAM_TEST_CASE(BruteForceMatcher, cv::gpu::DeviceInfo, DistType, int)
CV_ENUM(DistType, cv::gpu::BruteForceMatcher_GPU_base::L1Dist, cv::gpu::BruteForceMatcher_GPU_base::L2Dist, cv::gpu::BruteForceMatcher_GPU_base::HammingDist)
IMPLEMENT_PARAM_CLASS(DescriptorSize, int)
PARAM_TEST_CASE(BruteForceMatcher, cv::gpu::DeviceInfo, DistType, DescriptorSize)
{
cv::gpu::DeviceInfo devInfo;
cv::gpu::BruteForceMatcher_GPU_base::DistType distType;
@@ -212,10 +462,9 @@ PARAM_TEST_CASE(BruteForceMatcher, cv::gpu::DeviceInfo, DistType, int)
TEST_P(BruteForceMatcher, Match)
{
std::vector<cv::DMatch> matches;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
std::vector<cv::DMatch> matches;
matcher.match(loadMat(query), loadMat(train), matches);
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
@@ -234,17 +483,13 @@ TEST_P(BruteForceMatcher, Match)
TEST_P(BruteForceMatcher, MatchAdd)
{
std::vector<cv::DMatch> matches;
bool isMaskSupported;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
cv::gpu::GpuMat d_train(train);
// make add() twice to test such case
matcher.add(std::vector<cv::gpu::GpuMat>(1, d_train.rowRange(0, train.rows/2)));
matcher.add(std::vector<cv::gpu::GpuMat>(1, d_train.rowRange(train.rows/2, train.rows)));
matcher.add(std::vector<cv::gpu::GpuMat>(1, d_train.rowRange(0, train.rows / 2)));
matcher.add(std::vector<cv::gpu::GpuMat>(1, d_train.rowRange(train.rows / 2, train.rows)));
// prepare masks (make first nearest match illegal)
std::vector<cv::gpu::GpuMat> masks(2);
@@ -255,28 +500,26 @@ TEST_P(BruteForceMatcher, MatchAdd)
masks[mi].col(di * countFactor).setTo(cv::Scalar::all(0));
}
std::vector<cv::DMatch> matches;
matcher.match(cv::gpu::GpuMat(query), matches, masks);
isMaskSupported = matcher.isMaskSupported();
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
int badCount = 0;
int shift = matcher.isMaskSupported() ? 1 : 0;
for (size_t i = 0; i < matches.size(); i++)
{
cv::DMatch match = matches[i];
int shift = isMaskSupported ? 1 : 0;
if ((int)i < queryDescCount / 2)
{
if ((int)i < queryDescCount / 2)
{
if ((match.queryIdx != (int)i) || (match.trainIdx != (int)i * countFactor + shift) || (match.imgIdx != 0))
badCount++;
}
else
{
if ((match.queryIdx != (int)i) || (match.trainIdx != ((int)i - queryDescCount / 2) * countFactor + shift) || (match.imgIdx != 1))
badCount++;
}
if ((match.queryIdx != (int)i) || (match.trainIdx != (int)i * countFactor + shift) || (match.imgIdx != 0))
badCount++;
}
else
{
if ((match.queryIdx != (int)i) || (match.trainIdx != ((int)i - queryDescCount / 2) * countFactor + shift) || (match.imgIdx != 1))
badCount++;
}
}
@@ -287,9 +530,9 @@ TEST_P(BruteForceMatcher, KnnMatch2)
{
const int knn = 2;
std::vector< std::vector<cv::DMatch> > matches;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
std::vector< std::vector<cv::DMatch> > matches;
matcher.knnMatch(loadMat(query), loadMat(train), matches, knn);
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
@@ -317,11 +560,11 @@ TEST_P(BruteForceMatcher, KnnMatch2)
TEST_P(BruteForceMatcher, KnnMatch3)
{
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
const int knn = 3;
std::vector< std::vector<cv::DMatch> > matches;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
matcher.knnMatch(loadMat(query), loadMat(train), matches, knn);
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
@@ -350,9 +593,6 @@ TEST_P(BruteForceMatcher, KnnMatch3)
TEST_P(BruteForceMatcher, KnnMatchAdd2)
{
const int knn = 2;
std::vector< std::vector<cv::DMatch> > matches;
bool isMaskSupported;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
@@ -371,14 +611,14 @@ TEST_P(BruteForceMatcher, KnnMatchAdd2)
masks[mi].col(di * countFactor).setTo(cv::Scalar::all(0));
}
matcher.knnMatch(cv::gpu::GpuMat(query), matches, knn, masks);
std::vector< std::vector<cv::DMatch> > matches;
isMaskSupported = matcher.isMaskSupported();
matcher.knnMatch(cv::gpu::GpuMat(query), matches, knn, masks);
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
int badCount = 0;
int shift = isMaskSupported ? 1 : 0;
int shift = matcher.isMaskSupported() ? 1 : 0;
for (size_t i = 0; i < matches.size(); i++)
{
if ((int)matches[i].size() != knn)
@@ -412,9 +652,6 @@ TEST_P(BruteForceMatcher, KnnMatchAdd2)
TEST_P(BruteForceMatcher, KnnMatchAdd3)
{
const int knn = 3;
std::vector< std::vector<cv::DMatch> > matches;
bool isMaskSupported;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
@@ -433,14 +670,13 @@ TEST_P(BruteForceMatcher, KnnMatchAdd3)
masks[mi].col(di * countFactor).setTo(cv::Scalar::all(0));
}
std::vector< std::vector<cv::DMatch> > matches;
matcher.knnMatch(cv::gpu::GpuMat(query), matches, knn, masks);
isMaskSupported = matcher.isMaskSupported();
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
int badCount = 0;
int shift = isMaskSupported ? 1 : 0;
int shift = matcher.isMaskSupported() ? 1 : 0;
for (size_t i = 0; i < matches.size(); i++)
{
if ((int)matches[i].size() != knn)
@@ -473,16 +709,11 @@ TEST_P(BruteForceMatcher, KnnMatchAdd3)
TEST_P(BruteForceMatcher, RadiusMatch)
{
if (!supportFeature(devInfo, cv::gpu::SHARED_ATOMICS))
return;
const float radius = 1.f / countFactor;
std::vector< std::vector<cv::DMatch> > matches;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
std::vector< std::vector<cv::DMatch> > matches;
matcher.radiusMatch(loadMat(query), loadMat(train), matches, radius);
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
@@ -505,16 +736,9 @@ TEST_P(BruteForceMatcher, RadiusMatch)
TEST_P(BruteForceMatcher, RadiusMatchAdd)
{
if (!supportFeature(devInfo, cv::gpu::SHARED_ATOMICS))
return;
int n = 3;
const int n = 3;
const float radius = 1.f / countFactor * n;
std::vector< std::vector<cv::DMatch> > matches;
bool isMaskSupported;
cv::gpu::BruteForceMatcher_GPU_base matcher(distType);
cv::gpu::GpuMat d_train(train);
@@ -532,15 +756,14 @@ TEST_P(BruteForceMatcher, RadiusMatchAdd)
masks[mi].col(di * countFactor).setTo(cv::Scalar::all(0));
}
std::vector< std::vector<cv::DMatch> > matches;
matcher.radiusMatch(cv::gpu::GpuMat(query), matches, radius, masks);
isMaskSupported = matcher.isMaskSupported();
ASSERT_EQ(static_cast<size_t>(queryDescCount), matches.size());
int badCount = 0;
int shift = isMaskSupported ? 1 : 0;
int needMatchCount = isMaskSupported ? n-1 : n;
int shift = matcher.isMaskSupported() ? 1 : 0;
int needMatchCount = matcher.isMaskSupported() ? n-1 : n;
for (size_t i = 0; i < matches.size(); i++)
{
if ((int)matches[i].size() != needMatchCount)
@@ -571,141 +794,9 @@ TEST_P(BruteForceMatcher, RadiusMatchAdd)
ASSERT_EQ(0, badCount);
}
INSTANTIATE_TEST_CASE_P(Features2D, BruteForceMatcher, Combine(
ALL_DEVICES,
Values(cv::gpu::BruteForceMatcher_GPU_base::L1Dist, cv::gpu::BruteForceMatcher_GPU_base::L2Dist),
Values(57, 64, 83, 128, 179, 256, 304)));
INSTANTIATE_TEST_CASE_P(GPU_Features2D, BruteForceMatcher, testing::Combine(
ALL_DEVICES,
testing::Values(DistType(cv::gpu::BruteForceMatcher_GPU_base::L1Dist), DistType(cv::gpu::BruteForceMatcher_GPU_base::L2Dist)),
testing::Values(DescriptorSize(57), DescriptorSize(64), DescriptorSize(83), DescriptorSize(128), DescriptorSize(179), DescriptorSize(256), DescriptorSize(304))));
/////////////////////////////////////////////////////////////////////////////////////////////////
// FAST
struct FAST : TestWithParam<cv::gpu::DeviceInfo>
{
cv::gpu::DeviceInfo devInfo;
cv::Mat image;
int threshold;
std::vector<cv::KeyPoint> keypoints_gold;
virtual void SetUp()
{
devInfo = GetParam();
cv::gpu::setDevice(devInfo.deviceID());
image = readImage("features2d/aloe.png", CV_LOAD_IMAGE_GRAYSCALE);
ASSERT_FALSE(image.empty());
threshold = 30;
cv::FAST(image, keypoints_gold, threshold);
}
};
struct HashEq
{
size_t hash;
inline HashEq(size_t hash_) : hash(hash_) {}
inline bool operator ()(const cv::KeyPoint& kp) const
{
return kp.hash() == hash;
}
};
struct KeyPointCompare
{
inline bool operator ()(const cv::KeyPoint& kp1, const cv::KeyPoint& kp2) const
{
return kp1.pt.y < kp2.pt.y || (kp1.pt.y == kp2.pt.y && kp1.pt.x < kp2.pt.x);
}
};
TEST_P(FAST, Accuracy)
{
std::vector<cv::KeyPoint> keypoints;
cv::gpu::FAST_GPU fastGPU(threshold);
fastGPU(cv::gpu::GpuMat(image), cv::gpu::GpuMat(), keypoints);
ASSERT_EQ(keypoints.size(), keypoints_gold.size());
std::sort(keypoints.begin(), keypoints.end(), KeyPointCompare());
for (size_t i = 0; i < keypoints_gold.size(); ++i)
{
const cv::KeyPoint& kp1 = keypoints[i];
const cv::KeyPoint& kp2 = keypoints_gold[i];
size_t h1 = kp1.hash();
size_t h2 = kp2.hash();
ASSERT_EQ(h1, h2);
}
}
INSTANTIATE_TEST_CASE_P(Features2D, FAST, DEVICES(cv::gpu::GLOBAL_ATOMICS));
/////////////////////////////////////////////////////////////////////////////////////////////////
// ORB
struct ORB : TestWithParam<cv::gpu::DeviceInfo>
{
cv::gpu::DeviceInfo devInfo;
cv::Mat image;
cv::Mat mask;
int npoints;
std::vector<cv::KeyPoint> keypoints_gold;
cv::Mat descriptors_gold;
virtual void SetUp()
{
devInfo = GetParam();
cv::gpu::setDevice(devInfo.deviceID());
image = readImage("features2d/aloe.png", CV_LOAD_IMAGE_GRAYSCALE);
ASSERT_FALSE(image.empty());
mask = cv::Mat(image.size(), CV_8UC1, cv::Scalar::all(1));
mask(cv::Range(0, image.rows / 2), cv::Range(0, image.cols / 2)).setTo(cv::Scalar::all(0));
npoints = 1000;
cv::ORB orbCPU(npoints);
orbCPU(image, mask, keypoints_gold, descriptors_gold);
}
};
TEST_P(ORB, Accuracy)
{
std::vector<cv::KeyPoint> keypoints;
cv::Mat descriptors;
cv::gpu::ORB_GPU orbGPU(npoints);
cv::gpu::GpuMat d_descriptors;
orbGPU(cv::gpu::GpuMat(image), cv::gpu::GpuMat(mask), keypoints, d_descriptors);
d_descriptors.download(descriptors);
cv::BFMatcher matcher(cv::NORM_HAMMING);
std::vector<cv::DMatch> matches;
matcher.match(descriptors_gold, descriptors, matches);
int count = getValidMatchesCount(keypoints_gold, keypoints, matches);
double ratio = (double) count / matches.size();
ASSERT_GE(ratio, 0.65);
}
INSTANTIATE_TEST_CASE_P(Features2D, ORB, DEVICES(cv::gpu::GLOBAL_ATOMICS));
#endif // HAVE_CUDA
} // namespace