A high-performance general-purpose compute library

- Main Page
- Tutorials
- Release Notes
- Examples

Functions
unwrap
ArrayFire Functions | ArrayFire Functions by Category » Image Processing » Wrapping and unwrapping image windows

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)
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)

## Detailed Description

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).

Unwrap on a 3x4 input array, using a 2x2 window, 2x2 stride, 1x1 padding

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):

dim4(
wx * wy, // No. of rows (column height)
nsections_dim0 * nsections_dim1, // No. of columns per channel
input.dims(2), // No. of channels
input.dims(3) // No. of images
)

Here are some code examples that demonstrate unwrap's usage:

float hA[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
array A(dim4(3, 3), hA);
// 1. 4. 7.
// 2. 5. 8.
// 3. 6. 9.
array A_simple = unwrap(A, 2, 2, // window size
1, 1); // stride (sliding window)
// 1. 2. 4. 5.
// 2. 3. 5. 6.
// 4. 5. 7. 8.
// 5. 6. 8. 9.
array A_padded = unwrap(A, 2, 2, // window size
2, 2, // stride (distinct)
1, 1); // padding
// 0. 0. 0. 5.
// 0. 0. 4. 6.
// 0. 2. 0. 8.
// 1. 3. 7. 9.

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.

## Function Documentation

## ◆ af_unwrap()

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)

Parameters

  [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)

Returns
  AF_SUCCESS if unwrap is successful, otherwise an appropriate error code is returned.

Note
  `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

## ◆ unwrap()

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)

Parameters

  [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)

Returns
  an array with the input's sections rearraged as columns (or rows)

Note
  `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