[arrayfire] 185/248: Added homography unit tests

Ghislain Vaillant ghisvail-guest at moszumanska.debian.org
Tue Nov 17 15:54:25 UTC 2015


This is an automated email from the git hooks/post-receive script.

ghisvail-guest pushed a commit to branch dfsg-clean
in repository arrayfire.

commit b514aab50bc0dcd9859febbd32ca0ee872881604
Author: Peter Andreas Entschev <peter at arrayfire.com>
Date:   Tue Nov 3 14:40:01 2015 -0500

    Added homography unit tests
---
 test/homography.cpp | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 280 insertions(+)

diff --git a/test/homography.cpp b/test/homography.cpp
new file mode 100644
index 0000000..830a5aa
--- /dev/null
+++ b/test/homography.cpp
@@ -0,0 +1,280 @@
+/*******************************************************
+ * Copyright (c) 2014, 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 <gtest/gtest.h>
+#include <arrayfire.h>
+#include <af/dim4.hpp>
+#include <af/traits.hpp>
+#include <af/compatible.h>
+#include <string>
+#include <vector>
+#include <cmath>
+#include <testHelpers.hpp>
+#include <typeinfo>
+
+using std::string;
+using std::vector;
+using af::dim4;
+
+template<typename T>
+class Homography : public ::testing::Test
+{
+    public:
+        virtual void SetUp() {}
+};
+
+typedef ::testing::Types<float, double> TestTypes;
+
+TYPED_TEST_CASE(Homography, TestTypes);
+
+template<typename T>
+af::array perspectiveTransform(af::dim4 inDims, af::array H)
+{
+    T d0 = (T)inDims[0];
+    T d1 = (T)inDims[1];
+    af::dim4 dims(4, 3);
+    T h_in[4*3] = { (T)0, (T)0,  (T)d1, (T)d1,
+                    (T)0, (T)d0, (T)d0, (T)0,
+                    (T)1, (T)1,  (T)1,  (T)1 };
+
+    af::array in(dims, h_in);
+
+    af::array w = 1.f / af::matmul(in, H(af::span, 2));
+    af::array xt = af::matmul(in, H(af::span, 0)) * w;
+    af::array yt = af::matmul(in, H(af::span, 1)) * w;
+
+    af::array t = join(1, xt, yt);
+
+    return t;
+}
+
+template<typename T>
+void homographyTest(string pTestFile, const af_homography_type htype,
+                    const bool rotate, const float size_ratio)
+{
+    if (noDoubleTests<T>()) return;
+
+    vector<dim4>           inDims;
+    vector<string>         inFiles;
+    vector<vector<float> > gold;
+
+    readImageTests(pTestFile, inDims, inFiles, gold);
+
+    inFiles[0].insert(0,string(TEST_DIR"/homography/"));
+
+    af_array trainArray_f32   = 0;
+    af_array trainArray       = 0;
+    af_array train_desc       = 0;
+    af_array train_feat_x     = 0;
+    af_array train_feat_y     = 0;
+    af_features train_feat;
+
+    ASSERT_EQ(AF_SUCCESS, af_load_image(&trainArray_f32, inFiles[0].c_str(), false));
+    ASSERT_EQ(AF_SUCCESS, conv_image<T>(&trainArray, trainArray_f32));
+
+    ASSERT_EQ(AF_SUCCESS, af_orb(&train_feat, &train_desc, trainArray, 20.0f, 2000, 1.2f, 8, true));
+
+    ASSERT_EQ(AF_SUCCESS, af_get_features_xpos(&train_feat_x, train_feat));
+    ASSERT_EQ(AF_SUCCESS, af_get_features_ypos(&train_feat_y, train_feat));
+
+    af_array queryArray       = 0;
+    af_array query_desc       = 0;
+    af_array idx              = 0;
+    af_array dist             = 0;
+    af_array const_50         = 0;
+    af_array dist_thr         = 0;
+    af_array train_idx        = 0;
+    af_array query_idx        = 0;
+    af_array query_feat_x     = 0;
+    af_array query_feat_y     = 0;
+    af_array H                = 0;
+    af_array train_feat_x_idx = 0;
+    af_array train_feat_y_idx = 0;
+    af_array query_feat_x_idx = 0;
+    af_array query_feat_y_idx = 0;
+    af_features query_feat;
+
+    //ASSERT_EQ(AF_SUCCESS, af_load_image(&queryArray_f32, inFiles[testId].c_str(), false));
+    //ASSERT_EQ(AF_SUCCESS, conv_image<T>(&queryArray, queryArray_f32));
+    //const float theta = 0.0f;
+    const float theta = af::Pi * 0.5f;
+    const dim_t test_d0 = inDims[0][0] * size_ratio;
+    const dim_t test_d1 = inDims[0][1] * size_ratio;
+    if (rotate)
+        ASSERT_EQ(AF_SUCCESS, af_rotate(&queryArray, trainArray, theta, false, AF_INTERP_NEAREST));
+    else
+        ASSERT_EQ(AF_SUCCESS, af_resize(&queryArray, trainArray, test_d0, test_d1, AF_INTERP_BILINEAR));
+
+    ASSERT_EQ(AF_SUCCESS, af_orb(&query_feat, &query_desc, queryArray, 20.0f, 2000, 1.2f, 8, true));
+
+    ASSERT_EQ(AF_SUCCESS, af_hamming_matcher(&idx, &dist, train_desc, query_desc, 0, 1));
+
+    dim_t distDims[4];
+    ASSERT_EQ(AF_SUCCESS, af_get_dims(&distDims[0], &distDims[1], &distDims[2], &distDims[3], dist));
+
+    ASSERT_EQ(AF_SUCCESS, af_constant(&const_50, 50, 2, distDims, u32));
+    ASSERT_EQ(AF_SUCCESS, af_lt(&dist_thr, dist, const_50, false));
+    ASSERT_EQ(AF_SUCCESS, af_where(&train_idx, dist_thr));
+
+    dim_t tidxDims[4];
+    ASSERT_EQ(AF_SUCCESS, af_get_dims(&tidxDims[0], &tidxDims[1], &tidxDims[2], &tidxDims[3], train_idx));
+    af_index_t tindexs;
+    tindexs.isSeq = false;
+    tindexs.idx.seq = af_make_seq(0, tidxDims[0]-1, 1);
+    tindexs.idx.arr = train_idx;
+    ASSERT_EQ(AF_SUCCESS, af_index_gen(&query_idx, idx, 1, &tindexs));
+
+    ASSERT_EQ(AF_SUCCESS, af_get_features_xpos(&query_feat_x, query_feat));
+    ASSERT_EQ(AF_SUCCESS, af_get_features_ypos(&query_feat_y, query_feat));
+
+    dim_t qidxDims[4];
+    ASSERT_EQ(AF_SUCCESS, af_get_dims(&qidxDims[0], &qidxDims[1], &qidxDims[2], &qidxDims[3], query_idx));
+    af_index_t qindexs;
+    qindexs.isSeq = false;
+    qindexs.idx.seq = af_make_seq(0, qidxDims[0]-1, 1);
+    qindexs.idx.arr = query_idx;
+
+    ASSERT_EQ(AF_SUCCESS, af_index_gen(&train_feat_x_idx, train_feat_x, 1, &tindexs));
+    ASSERT_EQ(AF_SUCCESS, af_index_gen(&train_feat_y_idx, train_feat_y, 1, &tindexs));
+    ASSERT_EQ(AF_SUCCESS, af_index_gen(&query_feat_x_idx, query_feat_x, 1, &qindexs));
+    ASSERT_EQ(AF_SUCCESS, af_index_gen(&query_feat_y_idx, query_feat_y, 1, &qindexs));
+
+    int inliers = 0;
+    ASSERT_EQ(AF_SUCCESS, af_homography(&H, &inliers, train_feat_x_idx, train_feat_y_idx,
+                                        query_feat_x_idx, query_feat_y_idx, htype,
+                                        3.0f, 1000, (af_dtype) af::dtype_traits<T>::af_type));
+
+    af::array HH(H);
+
+    af::array t = perspectiveTransform<T>(inDims[0], HH);
+
+    T* gold_t = new T[8];
+    for (int i = 0; i < 8; i++)
+        gold_t[i] = (T)0;
+    if (rotate) {
+        gold_t[1] = test_d0;
+        gold_t[2] = test_d0;
+        gold_t[4] = test_d1;
+        gold_t[5] = test_d1;
+    } else {
+        gold_t[2] = test_d1;
+        gold_t[3] = test_d1;
+        gold_t[5] = test_d0;
+        gold_t[6] = test_d0;
+    }
+
+    T* out_t = new T[8];
+    t.host(out_t);
+
+    for (int elIter = 0; elIter < 8; elIter++)
+        ASSERT_LE(fabs(out_t[elIter] - gold_t[elIter]), 70.f) << "at: " << elIter << std::endl;
+
+    delete[] gold_t;
+    delete[] out_t;
+
+    ASSERT_EQ(AF_SUCCESS, af_release_array(queryArray));
+
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_desc));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(dist));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(const_50));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(dist_thr));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_feat_x));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_feat_y));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_feat_x_idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_feat_y_idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_feat_x_idx));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(query_feat_y_idx));
+
+    ASSERT_EQ(AF_SUCCESS, af_release_array(trainArray));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(trainArray_f32));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_desc));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_feat_x));
+    ASSERT_EQ(AF_SUCCESS, af_release_array(train_feat_y));
+}
+
+#define HOMOGRAPHY_INIT(desc, image, htype, rotate, size_ratio)                 \
+    TYPED_TEST(Homography, desc)                                                \
+    {                                                                           \
+        homographyTest<TypeParam>(string(TEST_DIR"/homography/"#image".test"),  \
+                                  htype, rotate, size_ratio);                   \
+    }
+
+    HOMOGRAPHY_INIT(Tux_RANSAC, tux, AF_RANSAC, false, 1.0f);
+    HOMOGRAPHY_INIT(Tux_RANSAC_90degrees, tux, AF_RANSAC, true, 1.0f);
+    HOMOGRAPHY_INIT(Tux_RANSAC_resize, tux, AF_RANSAC, false, 1.5f);
+    HOMOGRAPHY_INIT(Tux_LMedS, tux, AF_LMEDS, false, 1.0f);
+    HOMOGRAPHY_INIT(Tux_LMedS_90degrees, tux, AF_LMEDS, true, 1.0f);
+    HOMOGRAPHY_INIT(Tux_LMedS_resize, tux, AF_LMEDS, false, 1.5f);
+
+///////////////////////////////////// CPP ////////////////////////////////
+//
+TEST(Homography, CPP)
+{
+    vector<dim4>           inDims;
+    vector<string>         inFiles;
+    vector<vector<float> > gold;
+
+    readImageTests(string(TEST_DIR"/homography/tux.test"), inDims, inFiles, gold);
+
+    inFiles[0].insert(0,string(TEST_DIR"/homography/"));
+
+    const float size_ratio = 0.5f;
+
+    af::array train_img = af::loadImage(inFiles[0].c_str(), false);
+    af::array query_img = af::resize(size_ratio, train_img);
+    af::dim4 tDims = train_img.dims();
+
+    af::features feat_train, feat_query;
+    af::array desc_train, desc_query;
+    orb(feat_train, desc_train, train_img, 20, 2000, 1.2, 8, true);
+    orb(feat_query, desc_query, query_img, 20, 2000, 1.2, 8, true);
+
+    af::array idx, dist;
+    af::hammingMatcher(idx, dist, desc_train, desc_query, 0, 1); 
+
+    af::array train_idx = where(dist < 30);
+    af::array query_idx = idx(train_idx);
+
+    af::array feat_train_x = feat_train.getX()(train_idx);
+    af::array feat_train_y = feat_train.getY()(train_idx);
+    af::array feat_train_score = feat_train.getScore()(train_idx);
+    af::array feat_train_orientation = feat_train.getOrientation()(train_idx);
+    af::array feat_train_size = feat_train.getSize()(train_idx);
+    af::array feat_query_x = feat_query.getX()(query_idx);
+    af::array feat_query_y = feat_query.getY()(query_idx);
+    af::array feat_query_score = feat_query.getScore()(query_idx);
+    af::array feat_query_orientation = feat_query.getOrientation()(query_idx);
+    af::array feat_query_size = feat_query.getSize()(query_idx);
+
+    af::array H;
+    int inliers = 0;
+    af::homography(H, inliers, feat_train_x, feat_train_y, feat_query_x, feat_query_y, AF_RANSAC, 3.0f, 1000, f32);
+
+    float* gold_t = new float[8];
+    for (int i = 0; i < 8; i++)
+        gold_t[i] = 0.f;
+    gold_t[2] = tDims[1] * size_ratio;
+    gold_t[3] = tDims[1] * size_ratio;
+    gold_t[5] = tDims[0] * size_ratio;
+    gold_t[6] = tDims[0] * size_ratio;
+
+    af::array t = perspectiveTransform<float>(train_img.dims(), H);
+
+    float* out_t = new float[4*2];
+    t.host(out_t);
+
+    for (int elIter = 0; elIter < 8; elIter++)
+        ASSERT_LE(fabs(out_t[elIter] - gold_t[elIter]), 70.f) << "at: " << elIter << std::endl;
+
+    delete[] gold_t;
+    delete[] out_t;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/arrayfire.git



More information about the debian-science-commits mailing list