/******************************************************* * Copyright (c) 2015, ArrayFire * All rights reserved. * * This file is distributed under 3-clause BSD license. * The complete license agreement can be obtained at: * http://arrayfire.com/licenses/BSD-3-Clause ********************************************************/ #include #include #include #include #include #include #include #include #include #include using std::string; using std::vector; using std::abs; using af::dim4; typedef struct { float f[5]; } feat_t; static bool feat_cmp(feat_t i, feat_t j) { for (int k = 0; k < 5; k++) if (i.f[k] != j.f[k]) return (i.f[k] < j.f[k]); return false; } static void array_to_feat(vector& feat, float *x, float *y, float *score, float *orientation, float *size, unsigned nfeat) { feat.resize(nfeat); for (unsigned i = 0; i < feat.size(); i++) { feat[i].f[0] = x[i]; feat[i].f[1] = y[i]; feat[i].f[2] = score[i]; feat[i].f[3] = orientation[i]; feat[i].f[4] = size[i]; } } template class Susan : public ::testing::Test { public: virtual void SetUp() {} }; typedef ::testing::Types TestTypes; TYPED_TEST_CASE(Susan, TestTypes); template void susanTest(string pTestFile, float t, float g) { if (noDoubleTests()) return; if (noImageIOTests()) return; vector inDims; vector inFiles; vector > gold; readImageTests(pTestFile, inDims, inFiles, gold); size_t testCount = inDims.size(); for (size_t testId=0; testId out_feat; array_to_feat(out_feat, outX, outY, outScore, outOrientation, outSize, out.getNumFeatures()); vector gold_feat; array_to_feat(gold_feat, &gold[0].front(), &gold[1].front(), &gold[2].front(), &gold[3].front(), &gold[4].front(), gold[0].size()); std::sort(out_feat.begin(), out_feat.end(), feat_cmp); std::sort(gold_feat.begin(), gold_feat.end(), feat_cmp); for (int elIter = 0; elIter < (int)out.getNumFeatures(); elIter++) { ASSERT_EQ(out_feat[elIter].f[0], gold_feat[elIter].f[0]) << "at: " << elIter << std::endl; ASSERT_EQ(out_feat[elIter].f[1], gold_feat[elIter].f[1]) << "at: " << elIter << std::endl; ASSERT_LE(fabs(out_feat[elIter].f[2] - gold_feat[elIter].f[2]), 1e2) << "at: " << elIter << std::endl; ASSERT_EQ(out_feat[elIter].f[3], gold_feat[elIter].f[3]) << "at: " << elIter << std::endl; ASSERT_EQ(out_feat[elIter].f[4], gold_feat[elIter].f[4]) << "at: " << elIter << std::endl; } delete [] outX; delete [] outY; delete [] outScore; delete [] outOrientation; delete [] outSize; } } #define SUSAN_TEST(image, tval, gval) \ TYPED_TEST(Susan, image) \ { \ susanTest(string(TEST_DIR "/susan/"#image".test"), tval, gval);\ } SUSAN_TEST(man_t32_g10, 32, 10); SUSAN_TEST(square_t32_g10, 32, 10); SUSAN_TEST(square_t32_g20, 32, 20); TEST(Susan, InvalidDims) { try { af::array a = af::randu(256); af::features out = af::susan(a); EXPECT_TRUE(false); } catch (af::exception &e) { EXPECT_TRUE(true); } } TEST(Susan, InvalidRadius) { try { af::array a = af::randu(256); af::features out = af::susan(a, 10); EXPECT_TRUE(false); } catch (af::exception &e) { EXPECT_TRUE(true); } } TEST(Susan, InvalidThreshold) { try { af::array a = af::randu(256); af::features out = af::susan(a, 3, -32, 10, 0.05f, 3); EXPECT_TRUE(false); } catch (af::exception &e) { EXPECT_TRUE(true); } } TEST(Susan, InvalidFeatureRatio) { try { af::array a = af::randu(256); af::features out = af::susan(a, 3, 32, 10, 1.3f, 3); EXPECT_TRUE(false); } catch (af::exception &e) { EXPECT_TRUE(true); } } TEST(Susan, InvalidEdge) { try { af::array a = af::randu(128, 128); af::features out = af::susan(a, 3, 32, 10, 1.3f, 129); EXPECT_TRUE(false); } catch (af::exception &e) { EXPECT_TRUE(true); } }