Rearrange windowed sections of an array into columns (or rows) More...
Functions | |
AFAPI array | unwrap (const array &in, const dim_t wx, const dim_t wy, const dim_t sx, const dim_t sy, const dim_t px=0, const dim_t py=0, const bool is_column=true) |
C++ Interface for rearranging windowed sections of an input into columns (or rows) More... | |
AFAPI af_err | af_unwrap (af_array *out, const af_array in, const dim_t wx, const dim_t wy, const dim_t sx, const dim_t sy, const dim_t px, const dim_t py, const bool is_column) |
C Interface for rearranging windowed sections of an input into columns (or rows) More... | |
Rearrange windowed sections of an array into columns (or rows)
The figure below illustrates how unwrap works. A moving window (marked by orange boxes in the figure) of size wx
\(\times \) wy
captures sections of the input array, and flattens them into columns (or rows if is_column
is false) of the output array (illustrated in the right image). It starts at the top-left section of the input array and moves in column-major order, each time moving in strides of sx
units along the column and sy
units along the row, whenever it exhausts a column (stride size illustrated as the white arrows in the left image, and window movement illustrated as the progression of the small yellow numbers on the corner of each window). When the remainder of the column or row is not big enough to accomodate the window, that remainder is skipped and the window moves on (in the figure, the last row is not captured in any of the windows).
Optionally, one can specify that the input image's border be padded (with zeros, represented as the gray boxes in the figure) before the moving window starts capturing sections. The width of the padding is defined by px
for the top and bottom and py
for the left and right sides, with maximum values of wx
-1 and wy
-1, respectively. The moving window then captures sections as if the padding is part of the input image, and thus the padding also becomes part of the output array's columns (illustrated in the bottom of the right image).
In the figure, the stride is set to be equally large as the window size (both 2x2), and thus the sections that the window captures are distinct. However, when the stride is set to the minimum (1x1) and is smaller than the window size, the sections overlap (which in turn makes the output's columns overlap as well). The window then acts as a perfect "sliding window" in this case (see the first code example below). In general, there will be some overlap as long as the stride is smaller than the window size (though the overlap decreases as the stride approaches the window size), and when the stride is equal or greater than the window size, each section (and output column) will be distinct.
For inputs that have more than two dimensions, the unwrap operation will be applied to each 2D slice of the input. This is especially useful for independently processing each channel of an image (or set of images) - each channel (along the third dimension) on the input corresponds to the same channel on the output, and each image (along the fourth dimension) on the input corresponds to the same image on the output.
The size of the output is shown below. nsections_dim0
and nsections_dim1
denote how many windows can fit along the column and row, given the padded image size, window size, strides, and skips (if any):
Here are some code examples that demonstrate unwrap's usage:
One context where unwrap can be used is pre-processing an array or image for making window operations efficient (i.e. convolutions, computing the average pixel intensity around a point in an image, etc). Since each window capture is laid out as a column in an unwrapped array, vectorized operations can be executed efficiently on it (as opposed to strided access of each row in a window in the original array).
Note that the actual implementation of unwrap may not match the way the operation is described above, but the effect should be the same.
AFAPI af_err af_unwrap | ( | af_array * | out, |
const af_array | in, | ||
const dim_t | wx, | ||
const dim_t | wy, | ||
const dim_t | sx, | ||
const dim_t | sy, | ||
const dim_t | px, | ||
const dim_t | py, | ||
const bool | is_column | ||
) |
C Interface for rearranging windowed sections of an input into columns (or rows)
[out] | out | is an array with the input's sections rearraged as columns (or rows) |
[in] | in | is the input array |
[in] | wx | is the window size along dimension 0 |
[in] | wy | is the window size along dimension 1 |
[in] | sx | is the stride along dimension 0 |
[in] | sy | is the stride along dimension 1 |
[in] | px | is the padding along dimension 0 |
[in] | py | is the padding along dimension 1 |
[in] | is_column | determines whether the section becomes a column (if true) or a row (if false) |
in
can hold multiple images for processing if it is three or four-dimensional wx
and wy
must be between [1, input.dims(0 (1)) + px (py)] sx
and sy
must be greater than 1 px
and py
must be between [0, wx (wy) - 1]. Padding becomes part of the input image prior to the windowing AFAPI array unwrap | ( | const array & | in, |
const dim_t | wx, | ||
const dim_t | wy, | ||
const dim_t | sx, | ||
const dim_t | sy, | ||
const dim_t | px = 0 , |
||
const dim_t | py = 0 , |
||
const bool | is_column = true |
||
) |
C++ Interface for rearranging windowed sections of an input into columns (or rows)
[in] | in | is the input array |
[in] | wx | is the window size along dimension 0 |
[in] | wy | is the window size along dimension 1 |
[in] | sx | is the stride along dimension 0 |
[in] | sy | is the stride along dimension 1 |
[in] | px | is the padding along dimension 0 |
[in] | py | is the padding along dimension 1 |
[in] | is_column | determines whether the section becomes a column (if true) or a row (if false) |
in
can hold multiple images for processing if it is three or four-dimensional wx
and wy
must be between [1, input.dims(0 (1)) + px (py)] sx
and sy
must be greater than 1 px
and py
must be between [0, wx (wy) - 1]. Padding becomes part of the input image prior to the windowing