# bwlookup

Nonlinear filtering using lookup tables

## Syntax

• `A = bwlookup(BW,lut)` example
• `gpuarrayA = bwlookup(gpuarrayBW,lut)`

## Description

example

````A = bwlookup(BW,lut)` performs a 2-by-2 or 3-by-3 nonlinear neighborhood filtering operation on binary or grayscale image `BW` and returns the results in output image `A`. The neighborhood processing determines an integer index value used to access values in lookup table `lut`. The fetched `lut` value becomes the pixel value in output image A at the targeted position.`A` is the same size as `BW``A` is the same data type as `lut`This function supports code generation (see Tips).```
````gpuarrayA = bwlookup(gpuarrayBW,lut)` performs the filtering operation on a GPU. The input image and output image are `gpuArray`s. `lut` can be a numeric or `gpuArray` vector. This syntax requires the Parallel Computing Toolbox™.```

## Examples

collapse all

### 2-by-2 Neighborhood Erosion of Binary Image

Perform an erosion along the edges of a binary image using a 2-by-2 neighborhood. Vector `lut` is constructed such that the filtering operation places a 1 at the targeted pixel location in image `A` only when all 4 pixels in the 2-by-2 neighborhood of `BW` are set to `1`. For all other 2-by-2 neighborhood combinations in `BW`, the targeted pixel location in image `A` is set to `0`.

Construct `lut` so it is `true` only when all four 2-by-2 locations equal `1`.

```lutfun = @(x)(sum(x(:))==4); lut = makelut(lutfun,2) ```
```lut = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1```

```BW1 = imread('text.png'); ```

Perform 2-by-2 neighborhood processing with 16-element vector LUT.

```BW2 = bwlookup(BW1,lut); ```

Show zoomed before and after images.

```figure; h1 = subplot(1,2,1); imshow(BW1), axis off; title('BW1') h2 = subplot(1,2,2); imshow(BW2); axis off; title('BW2') % 16X zoom to see effects of erosion on text set(h1,'Ylim',[.5 64.5]); set(h1,'Xlim',[.5 64.5]); set(h2,'Ylim',[.5 64.5]); set(h2,'Xlim',[.5 64.5]); ```

### 2-by-2 Neighborhood Erosion of Binary Image Using GPU

Perform an erosion along the edges of a binary image using a 2-by-2 neighborhood, running the code on a graphics processing unit (GPU).

Construct `lut` so it is true only when all four 2-by-2 locations equal 1

```lut = makelut('sum(x(:))==4',2); ```

```BW1 = imread('text.png'); ```

Perform 2-by-2 neighborhood processing with 16-element vector LUT. To run the code on a GPU, create a `gpuArray` to contain the image.

```BW2 = bwlookup(gpuArray(BW1),lut); ```

Show zoomed before and after images.

```figure; h1 = subplot(1,2,1); imshow(BW1), axis off; title('BW1') h2 = subplot(1,2,2); imshow(BW2); axis off; title('BW2') % 16X zoom to see effects of erosion on text set(h1,'Ylim',[.5 64.5]); set(h1,'Xlim',[.5 64.5]); set(h2,'Ylim',[.5 64.5]); set(h2,'Xlim',[.5 64.5]); ```

## Input Arguments

collapse all

### `BW` — Input imagebinary image | grayscale image

Input image transformed by nonlinear neighborhood filtering operation, specified as either a grayscale or binary (logical) image. In the case of numeric values, non-zero pixels are considered `true` which is equivalent to logical 1.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `logical`

### `gpuarrayBW` — Input image for processing on a GPUA `gpuArray` containing a binary image

Input image for processing on a GPU, specified as a `gpuArray` containing a binary image.

### `lut` — Lookup table of output pixel values 16- or 512-element vector

Lookup table of output pixel values, specified as a 16- or 512-element vector. The size of `lut` determines which of the two neighborhood operations is performed.

• If `lut` contains 16 data elements, then the neighborhood matrix is 2-by-2.

• If `lut` contains 512 data elements, then the neighborhood matrix is 3-by-3.

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `logical`

## Output Arguments

collapse all

### `A` — Output imagebinary image | grayscale image

Output image, returned as a grayscale or binary image whose size matches`BW`, and whose distribution of pixel values are determined by the content of `lut`.

• `A` is the same size as `BW`

• `A` is the same data type as `lut`

Data Types: `single` | `double` | `int8` | `int16` | `int32` | `int64` | `uint8` | `uint16` | `uint32` | `uint64` | `logical`

### `gpuarrayA` — Output image`gpuArray` containing a grayscale or binary image

Output image, returned as a`gpuArray` containing a grayscale or binary image.

collapse all

### Tips

• This function supports the generation of C code using MATLAB® Coder™. Note that if you choose the generic `MATLAB Host Computer` target platform, the function generates code that uses a precompiled, platform-specific shared library. Use of a shared library preserves performance optimizations but limits the target platforms for which code can be generated. For more information, see Understanding Code Generation with Image Processing Toolbox.

When generating code, specify an input image of class `logical`.

### Algorithms

The first step in each iteration of the filtering operation performed by `bwlookup` entails computing the `index` into vector `lut` based on the binary pixel pattern of the neighborhood matrix on image `BW`. The value in `lut` accessed at `index`, `lut(index)`, is inserted into output image `A` at the targeted pixel location. This results in image `A` being the same data type as vector `lut`.

Since there is a 1-to-1 correspondence in targeted pixel locations, image A is the same size as image `BW`. If the targeted pixel location is on an edge of image `BW` and if any part of the 2-by-2 or 3-by-3 neighborhood matrix extends beyond the image edge, then these non-image locations are padded with 0 in order to perform the filtering operation.

The following figures show the mapping from binary 0 and 1 patterns in the neighborhood matrices to its binary representation. Adding 1 to the binary representation yields `index` which is used to access `lut`.

For 2-by-2 neighborhoods, `length(lut)` is 16. There are four pixels in each neighborhood, and two possible states for each pixel, so the total number of permutations is 24 = 16.

To illustrate, this example shows how the pixel pattern in a 2-by-2 matrix determines which entry in `lut` is placed in the targeted pixel location.

1. Create random 16-element `lut` vector containing `uint8` data.

```scurr = rng; % save current random number generator seed state rng('default') % always generate same set of random numbers lut = uint8( round( 255*rand(16,1) ) ) % generate lut rng(scurr); % restore```
```lut = 208 231 32 233 161 25 71 139 244 246 40 248 244 124 204 36```
2. Create a 2-by-2 image and assume for this example that the targeted pixel location is location `BW(1,1)`.

`BW = [1 0; 0 1]`
```BW = 1 0 0 1```
3. By referring to the color coded mapping figure above, the binary representation for this 2-by-2 neighborhood can be computed as shown in the code snippet below. The logical 1 at `BW(1,1)` corresponds to blue in the figure which maps to the Least Signficant Bit (LSB) at position 0 in the 4-bit binary representation (,20= 1). The logical 1 at `BW(2,2)` is red which maps to the Most Significant Bit (MSB) at position 3 in the 4-bit binary representation (23= 8) .

```% BW(1,1): blue square; sets bit position 0 on right % BW(2,2): red square; sets bit position 3 on left binNot = '1 0 0 1'; % binary representation of 2x2 neighborhood matrix X = bin2dec( binNot ); % convert from binary to decimal index = X + 1 % add 1 to compute index value for uint8 vector lut A11 = lut(index) % value at A(1,1)```
```index = 10 A11 = 246```
4. The above calculation predicts that output image A should contain the value 246 at targeted position `A(1,1)`.

`A = bwlookup(BW,lut) % perform filtering`
```A = 246 32 161 231```

`A(1,1)` does in fact equal 246.

 Note:   For a more robust way to perform image erosion, see function `imerode`.

For 3-by-3 neighborhoods, `length(lut)` is 512. There are nine pixels in each neighborhood, and two possible states for each pixel, so the total number of permutations is 29 = 512.

The process for computing the binary representation of 3-by-3 neighborhood processing is the same as shown above for 2-by-2 neighborhoods.