[arrayfire] 14/408: FEAT: Difference of Gaussians
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Mon Sep 21 19:11:05 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch debian/sid
in repository arrayfire.
commit f00a3966a2f3f8c0c19dd9ab193d03de8e16b413
Author: pradeep <pradeep at arrayfire.com>
Date: Thu Jun 18 15:31:22 2015 -0400
FEAT: Difference of Gaussians
* CPU, CUDA & OpenCL backends
* Unit tests for non-batched, batched & invalid inputs
* Documentation
---
docs/details/image.dox | 13 ++++++
examples/image_processing/filters.cpp | 6 +--
include/af/image.h | 26 ++++++++++++
src/api/c/dog.cpp | 69 ++++++++++++++++++++++++++++++++
src/api/cpp/dog.cpp | 24 +++++++++++
test/dog.cpp | 75 +++++++++++++++++++++++++++++++++++
6 files changed, 210 insertions(+), 3 deletions(-)
diff --git a/docs/details/image.dox b/docs/details/image.dox
index 7491d25..4707de7 100644
--- a/docs/details/image.dox
+++ b/docs/details/image.dox
@@ -570,5 +570,18 @@ Interpolation types of \ref AF_INTERP_NEAREST and \ref AF_INTERP_BILINEAR are al
Affine transforms can be used for various purposes. \ref af::translate, \ref af::scale and \ref af::skew
are specializations of the transform function.
+=======================================================================
+
+\defgroup image_func_dog DoG
+\ingroup imageflt_mat
+
+\brief Difference of Gaussians
+
+Given an image, this function computes two different versions of smoothed
+input image using the difference smoothing parameters and subtracts one
+from the other and returns the result.
+
+=======================================================================
+
@}
*/
diff --git a/examples/image_processing/filters.cpp b/examples/image_processing/filters.cpp
index e669620..1032043 100644
--- a/examples/image_processing/filters.cpp
+++ b/examples/image_processing/filters.cpp
@@ -130,7 +130,7 @@ void normalizeImage(array &in)
in = 255.0f*((in - min) / (max - min));
}
-array dog(const array &in, int window_radius1, int window_radius2)
+array DifferenceOfGaussian(const array &in, int window_radius1, int window_radius2)
{
array ret_val;
int w1 = 2 * window_radius1 + 1;
@@ -224,7 +224,7 @@ int main(int argc, char **argv)
array sprd = spread(lena, 3, 3);
array hrl = hurl(lena, 10, 1);
array pckng = pick(lena, 40, 2);
- array difog = dog(lena, 1, 2);
+ array difog = DifferenceOfGaussian(lena, 1, 2);
array bil = bilateral(hrl, 3.0f, 40.0f);
array mf = medianfilter(hrl, 5, 5);
array gb = gaussianblur(hrl, 3, 3, 0.8);
@@ -261,4 +261,4 @@ int main(int argc, char **argv)
}
#endif
return 0;
-}
\ No newline at end of file
+}
diff --git a/include/af/image.h b/include/af/image.h
index 67f5fc3..165def3 100644
--- a/include/af/image.h
+++ b/include/af/image.h
@@ -461,6 +461,18 @@ AFAPI array rgb2hsv(const array& in);
*/
AFAPI array colorSpace(const array& image, const CSpace to, const CSpace from);
+/**
+ C++ Interface wrapper for Difference of Gaussians
+
+ \param[in] in is input image
+ \param[in] radius1 is the radius of first gaussian kernel
+ \param[in] radius2 is the radius of second gaussian kernel
+ \return Difference of smoothed inputs
+
+ \ingroup image_func_dog
+ */
+AFAPI array dog(const array& in, const int radius1, const int radius2);
+
}
#endif
@@ -903,6 +915,20 @@ extern "C" {
*/
AFAPI af_err af_color_space(af_array *out, const af_array image, const af_cspace_t to, const af_cspace_t from);
+ /**
+ C Interface wrapper for Difference of Gaussians
+
+ \param[out] out is difference of smoothed inputs
+ \param[in] in is input image
+ \param[in] radius1 is the radius of first gaussian kernel
+ \param[in] radius2 is the radius of second gaussian kernel
+ \return \ref AF_SUCCESS if the computation is is successful,
+ otherwise an appropriate error code is returned.
+
+ \ingroup image_func_dog
+ */
+ AFAPI af_err af_dog(af_array *out, const af_array in, const int radius1, const int radius2);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/api/c/dog.cpp b/src/api/c/dog.cpp
new file mode 100644
index 0000000..16b0c53
--- /dev/null
+++ b/src/api/c/dog.cpp
@@ -0,0 +1,69 @@
+/*******************************************************
+ * 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 <af/dim4.hpp>
+#include <af/defines.h>
+#include <af/image.h>
+#include <err_common.hpp>
+#include <backend.hpp>
+#include <handle.hpp>
+#include <convolve.hpp>
+#include <arith.hpp>
+
+using af::dim4;
+using namespace detail;
+
+template<typename T, typename accT>
+static af_array dog(const af_array& in, const int radius1, const int radius2)
+{
+ af_array g1, g2;
+ g1 = g2 = 0;
+ AF_CHECK(af_gaussian_kernel(&g1, 2*radius1+1, 2*radius1+1, 0.0, 0.0));
+ AF_CHECK(af_gaussian_kernel(&g2, 2*radius2+1, 2*radius2+1, 0.0, 0.0));
+
+ Array<T> input = getArray<T>(in);
+ dim4 iDims = input.dims();
+
+ ConvolveBatchKind bkind = iDims[2] > 1 ? MANY2ONE : ONE2ONE;
+
+ Array<T> smth1 = convolve<T, accT, 2, false>(input, castArray<accT>(g1), bkind);
+ Array<T> smth2 = convolve<T, accT, 2, false>(input, castArray<accT>(g2), bkind);
+ Array<T> retVal= arithOp<T, af_sub_t>(smth1, smth2, iDims);
+
+ AF_CHECK(af_release_array(g1));
+ AF_CHECK(af_release_array(g2));
+
+ return getHandle<T>(retVal);
+}
+
+af_err af_dog(af_array *out, const af_array in, const int radius1, const int radius2)
+{
+ try {
+ ArrayInfo info = getInfo(in);
+ dim4 inDims = info.dims();
+ ARG_ASSERT(1, (inDims.ndims()>=2));
+ ARG_ASSERT(1, (inDims.ndims()<=3));
+
+ af_array output;
+ af_dtype type = info.getType();
+ switch(type) {
+ case f32: output = dog<float , float>(in, radius1, radius2); break;
+ case f64: output = dog<double,double>(in, radius1, radius2); break;
+ case b8 : output = dog<char , float>(in, radius1, radius2); break;
+ case s32: output = dog<int , float>(in, radius1, radius2); break;
+ case u32: output = dog<uint , float>(in, radius1, radius2); break;
+ case u8 : output = dog<uchar , float>(in, radius1, radius2); break;
+ default : TYPE_ERROR(1, type);
+ }
+ std::swap(*out, output);
+ }
+ CATCHALL;
+
+ return AF_SUCCESS;
+}
diff --git a/src/api/cpp/dog.cpp b/src/api/cpp/dog.cpp
new file mode 100644
index 0000000..6d8e138
--- /dev/null
+++ b/src/api/cpp/dog.cpp
@@ -0,0 +1,24 @@
+/*******************************************************
+ * 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 <af/array.h>
+#include <af/image.h>
+#include "error.hpp"
+
+namespace af
+{
+
+array dog(const array& in, const int radius1, const int radius2)
+{
+ af_array temp = 0;
+ AF_THROW(af_dog(&temp, in.get(), radius1, radius2));
+ return array(temp);
+}
+
+}
diff --git a/test/dog.cpp b/test/dog.cpp
new file mode 100644
index 0000000..aa85814
--- /dev/null
+++ b/test/dog.cpp
@@ -0,0 +1,75 @@
+/*******************************************************
+ * 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 <gtest/gtest.h>
+#include <arrayfire.h>
+#include <af/dim4.hpp>
+#include <af/traits.hpp>
+#include <string>
+#include <vector>
+#include <testHelpers.hpp>
+
+template<typename T>
+class DOG : public ::testing::Test
+{
+ public:
+ virtual void SetUp() {}
+};
+
+// create a list of types to be tested
+typedef ::testing::Types<float, double, int, uint, char, uchar> TestTypes;
+
+// register the type list
+TYPED_TEST_CASE(DOG, TestTypes);
+
+
+TYPED_TEST(DOG, Basic)
+{
+ if (noDoubleTests<TypeParam>()) return;
+
+ af::dim4 iDims(512, 512, 1, 1);
+ af::array in = af::constant<TypeParam>(1, iDims);
+ /* calculate DOG using ArrayFire functions */
+ af::array k1 = af::gaussianKernel(3, 3);
+ af::array k2 = af::gaussianKernel(2, 2);
+ af::array smth1 = af::convolve2(in, k1);
+ af::array smth2 = af::convolve2(in, k2);
+ af::array diff = smth1 - smth2;
+ /* calcuate DOG using new function */
+ af::array out= af::dog(in, 3, 2);
+ /* compare both the values */
+ float accumErr = af::sum<float>(out-diff);
+ EXPECT_EQ(true, accumErr<1.0e-2);
+}
+
+TYPED_TEST(DOG, Batch)
+{
+ if (noDoubleTests<TypeParam>()) return;
+
+ af::dim4 iDims(512, 512, 3, 1);
+ af::array in = af::constant<TypeParam>(1, iDims);
+ /* calculate DOG using ArrayFire functions */
+ af::array k1 = af::gaussianKernel(3, 3);
+ af::array k2 = af::gaussianKernel(2, 2);
+ af::array smth1 = af::convolve2(in, k1);
+ af::array smth2 = af::convolve2(in, k2);
+ af::array diff = smth1 - smth2;
+ /* calcuate DOG using new function */
+ af::array out= af::dog(in, 3, 2);
+ /* compare both the values */
+ float accumErr = af::sum<float>(out-diff);
+ EXPECT_EQ(true, accumErr<1.0e-2);
+}
+
+TYPED_TEST(DOG, InvalidArray)
+{
+ af::array in = af::randu(512);
+ EXPECT_THROW(af::dog(in, 3, 2),
+ af::exception);
+}
--
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