Skip to content

Commit 7df4dcd

Browse files
committed
FEAT/TEST/DOC: Adding wrap for CPU backend
- Added necessary tests and documentation
1 parent a958628 commit 7df4dcd

File tree

13 files changed

+648
-14
lines changed

13 files changed

+648
-14
lines changed

docs/details/image.dox

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -678,15 +678,15 @@ The output array of this function will have \f$ S(x, y) \f$ values at their corr
678678
=======================================================================
679679

680680
\defgroup image_func_unwrap unwrap
681-
\ingroup image_mod
681+
\ingroup image_mod_mat
682682

683-
Generate image with image windows as columns
683+
Generate an array with image windows as columns
684684

685685
unwrap takes in an input image along with the window sizes \p wx and \p
686686
wy, strides \p sx and \p sy, and padding \p px and \p py. This function then
687687
generates a matrix where each windows is an independent column.
688688

689-
The number of columns in the output array are govenered by the number of
689+
The number of columns (rows if is_column is true) in the output array are govenered by the number of
690690
windows that can be fit along x and y directions. Padding is applied along all
691691
4 sides of the matrix with \p px defining the height of the padding along dim
692692
0 and \p py defining the width of the padding along dim 1.
@@ -769,5 +769,15 @@ unwrap(A, 3, 3, 3, 3, 2, 2) [9 9 1 1]
769769
0 12 0 0 27 0 0 0 0
770770
10 13 0 25 28 0 0 0 0
771771
\endcode
772+
773+
774+
=======================================================================
775+
776+
\defgroup image_func_wrap wrap
777+
\ingroup image_mod_mat
778+
779+
Wrap takes an unwrapped image (see \ref unwrap) and converts it back to an image.
780+
781+
The inputs to this function should be the same as the inputs used to generate the unwrapped image.
772782
@}
773783
*/

include/af/image.h

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,8 @@ AFAPI array histEqual(const array& in, const array& hist);
411411
/**
412412
C++ Interface for generating gausian kernels
413413
414-
\param[in] rows number of kernel rows
415-
\param[in] cols number of kernel columns
414+
\param[in] rows number of rows of the kernel
415+
\param[in] cols number of columns of the kernel
416416
\param[in] sig_r (default 0) (calculated internally as 0.25 * rows + 0.75)
417417
\param[in] sig_c (default 0) (calculated internally as 0.25 * cols + 0.75)
418418
\return an array with values generated using gaussian function
@@ -476,22 +476,45 @@ AFAPI array dog(const array& in, const int radius1, const int radius2);
476476
/**
477477
C++ Interface wrapper for unwrap
478478
479-
\param[in] in is the input array
479+
\param[in] in is the input image (or set of images)
480480
\param[in] wx is the block window size along 0th-dimension between [1, input.dims[0] + px]
481481
\param[in] wy is the block window size along 1st-dimension between [1, input.dims[1] + py]
482482
\param[in] sx is the stride along 0th-dimension
483483
\param[in] sy is the stride along 1st-dimension
484484
\param[in] px is the padding along 0th-dimension between [0, wx). Padding is applied both before and after.
485485
\param[in] py is the padding along 1st-dimension between [0, wy). Padding is applied both before and after.
486486
\param[in] is_column specifies the layout for the unwrapped patch. If is_column is false, the unrapped patch is laid out as a row.
487-
\returns an array with the image blocks as columns
487+
\returns an array with the image blocks as rows or columns
488488
489489
\ingroup image_func_unwrap
490490
*/
491491
AFAPI array unwrap(const array& in, const dim_t wx, const dim_t wy,
492492
const dim_t sx, const dim_t sy, const dim_t px=0, const dim_t py=0,
493493
const bool is_column = true);
494494

495+
/**
496+
C++ Interface wrapper for wrap
497+
498+
\param[in] in is the input image (or set of images)
499+
\param[in] ox is the 0th-dimension of output
500+
\param[in] oy is the ist-dimension of output
501+
\param[in] wx is the block window size along 0th-dimension between
502+
\param[in] wy is the block window size along 1st-dimension between
503+
\param[in] sx is the stride along 0th-dimension
504+
\param[in] sy is the stride along 1st-dimension
505+
\param[in] px is the padding used along 0th-dimension between [0, wx).
506+
\param[in] py is the padding used along 1st-dimension between [0, wy).
507+
\param[in] is_column specifies the layout for the unwrapped patch. If is_column is false, the rows are treated as patches
508+
\returns an array of images after converting rows or columns into image windows
509+
510+
\ingroup image_func_wrap
511+
*/
512+
AFAPI array wrap(const array& in,
513+
const dim_t ox, const dim_t oy,
514+
const dim_t wx, const dim_t wy,
515+
const dim_t sx, const dim_t sy,
516+
const dim_t px = 0, const dim_t py = 0,
517+
const bool is_column = true);
495518

496519
/**
497520
C++ Interface wrapper for summed area tables
@@ -913,8 +936,8 @@ extern "C" {
913936
C Interface generating gaussian kernels
914937
915938
\param[out] out is an array with values generated using gaussian function
916-
\param[in] rows number of kernel rows
917-
\param[in] cols number of kernel columns
939+
\param[in] rows number of rows of the gaussian kernel
940+
\param[in] cols number of columns of the gaussian kernel
918941
\param[in] sigma_r (default 0) (calculated internally as 0.25 * rows + 0.75)
919942
\param[in] sigma_c (default 0) (calculated internally as 0.25 * cols + 0.75)
920943
\return \ref AF_SUCCESS if gaussian distribution values are generated successfully,
@@ -990,8 +1013,8 @@ extern "C" {
9901013
/**
9911014
C Interface wrapper for unwrap
9921015
993-
\param[out] out is an array with image blocks as columns.
994-
\param[in] in is the input array
1016+
\param[out] out is an array with image blocks as rows or columns.
1017+
\param[in] in is the input image (or set of images)
9951018
\param[in] wx is the block window size along 0th-dimension between [1, input.dims[0] + px]
9961019
\param[in] wy is the block window size along 1st-dimension between [1, input.dims[1] + py]
9971020
\param[in] sx is the stride along 0th-dimension
@@ -1008,6 +1031,35 @@ extern "C" {
10081031
const dim_t sx, const dim_t sy, const dim_t px, const dim_t py,
10091032
const bool is_column);
10101033

1034+
/**
1035+
C Interface wrapper for wrap
1036+
1037+
\param[out] out is an array after converting
1038+
\param[in] in is the input array
1039+
\param[in] ox is the 0th-dimension of \p out
1040+
\param[in] oy is the ist-dimension of \p out
1041+
\param[in] wx is the block window size along 0th-dimension between
1042+
\param[in] wy is the block window size along 1st-dimension between
1043+
\param[in] sx is the stride along 0th-dimension
1044+
\param[in] sy is the stride along 1st-dimension
1045+
\param[in] px is the padding used along 0th-dimension between [0, wx).
1046+
\param[in] py is the padding used along 1st-dimension between [0, wy).
1047+
\param[in] is_column specifies the layout for the unwrapped patch. If is_column is false, the rows are treated as the patches
1048+
\return \ref AF_SUCCESS if the color transformation is successful,
1049+
otherwise an appropriate error code is returned.
1050+
1051+
\note The padding used in \ref af_unwrap is calculated from the provided parameters
1052+
1053+
\ingroup image_func_wrap
1054+
*/
1055+
AFAPI af_err af_wrap(af_array *out,
1056+
const af_array in,
1057+
const dim_t ox, const dim_t oy,
1058+
const dim_t wx, const dim_t wy,
1059+
const dim_t sx, const dim_t sy,
1060+
const dim_t px, const dim_t py,
1061+
const bool is_column);
1062+
10111063
/**
10121064
C Interface wrapper for summed area tables
10131065

include/arrayfire.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@
138138
@defgroup connected_comps_mat Connected Components & Labeling
139139
regions
140140
141+
@defgroup image_mod_mat Wrapping and unwrapping image windows
142+
wrap, unwrap, etc.
143+
141144
@defgroup utility_mat Utility Functions
142145
loadImage, saveImage, gaussianKernel
143146
@}

src/api/c/wrap.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*******************************************************
2+
* Copyright (c) 2015, ArrayFire
3+
* All rights reserved.
4+
*
5+
* This file is distributed under 3-clause BSD license.
6+
* The complete license agreement can be obtained at:
7+
* http://arrayfire.com/licenses/BSD-3-Clause
8+
********************************************************/
9+
10+
#include <af/image.h>
11+
#include <af/defines.h>
12+
#include <err_common.hpp>
13+
#include <handle.hpp>
14+
#include <backend.hpp>
15+
#include <ArrayInfo.hpp>
16+
#include <wrap.hpp>
17+
18+
using af::dim4;
19+
using namespace detail;
20+
21+
template<typename T>
22+
static inline af_array wrap(const af_array in,
23+
const dim_t ox, const dim_t oy,
24+
const dim_t wx, const dim_t wy,
25+
const dim_t sx, const dim_t sy,
26+
const dim_t px, const dim_t py,
27+
const bool is_column)
28+
{
29+
return getHandle(wrap<T>(getArray<T>(in), ox, oy, wx, wy, sx, sy, px, py, is_column));
30+
}
31+
32+
af_err af_wrap(af_array *out, const af_array in,
33+
const dim_t ox, const dim_t oy,
34+
const dim_t wx, const dim_t wy,
35+
const dim_t sx, const dim_t sy,
36+
const dim_t px, const dim_t py,
37+
const bool is_column)
38+
{
39+
try {
40+
ArrayInfo info = getInfo(in);
41+
af_dtype type = info.getType();
42+
af::dim4 idims = info.dims();
43+
44+
ARG_ASSERT(2, wx > 0);
45+
ARG_ASSERT(3, wx > 0);
46+
ARG_ASSERT(4, sx > 0);
47+
ARG_ASSERT(5, sy > 0);
48+
49+
dim_t nx = (ox + 2 * px - wx) / sx + 1;
50+
dim_t ny = (oy + 2 * py - wy) / sy + 1;
51+
52+
dim_t patch_size = is_column ? idims[0] : idims[1];
53+
dim_t num_patches = is_column ? idims[1] : idims[0];
54+
55+
DIM_ASSERT(1, patch_size == wx * wy);
56+
DIM_ASSERT(1, num_patches == nx * ny);
57+
58+
af_array output;
59+
60+
switch(type) {
61+
case f32: output = wrap<float >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
62+
case f64: output = wrap<double >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
63+
case c32: output = wrap<cfloat >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
64+
case c64: output = wrap<cdouble>(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
65+
case s32: output = wrap<int >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
66+
case u32: output = wrap<uint >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
67+
case s64: output = wrap<intl >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
68+
case u64: output = wrap<uintl >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
69+
case u8: output = wrap<uchar >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
70+
case b8: output = wrap<char >(in, ox, oy, wx, wy, sx, sy, px, py, is_column); break;
71+
default: TYPE_ERROR(1, type);
72+
}
73+
std::swap(*out,output);
74+
}
75+
CATCHALL;
76+
77+
return AF_SUCCESS;
78+
}

src/api/cpp/wrap.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*******************************************************
2+
* Copyright (c) 2015, ArrayFire
3+
* All rights reserved.
4+
*
5+
* This file is distributed under 3-clause BSD license.
6+
* The complete license agreement can be obtained at:
7+
* http://arrayfire.com/licenses/BSD-3-Clause
8+
********************************************************/
9+
10+
#include <af/array.h>
11+
#include <af/image.h>
12+
#include "error.hpp"
13+
14+
namespace af
15+
{
16+
array wrap(const array& in,
17+
const dim_t ox, const dim_t oy,
18+
const dim_t wx, const dim_t wy,
19+
const dim_t sx, const dim_t sy,
20+
const dim_t px, const dim_t py,
21+
const bool is_column)
22+
{
23+
af_array out = 0;
24+
AF_THROW(af_wrap(&out, in.get(), ox, oy, wx, wy, sx, sy, px, py, is_column));
25+
return array(out);
26+
}
27+
}

src/backend/cpu/unwrap.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ namespace cpu
4747
dim_t spy = starty - py;
4848

4949
// Short cut condition ensuring all values within input dimensions
50-
bool cond = false;
51-
if(spx >= 0 && spx + wx < idims[0] && spy >= 0 && spy + wy < idims[1])
52-
cond = true;
50+
bool cond = (spx >= 0 && spx + wx < idims[0] && spy >= 0 && spy + wy < idims[1]);
5351

5452
for(dim_t y = 0; y < wy; y++) {
5553
for(dim_t x = 0; x < wx; x++) {

0 commit comments

Comments
 (0)