Texture Segmentation Using Texture Filters

This example shows how to identify and segment regions based on their texture.

Read and display a grayscale image of textured patterns on a bag.

```I = imread('bag.png'); imshow(I) title('Original Image')```

Create Texture Image

Use `entropyfilt` to create a texture image. The function `entropyfilt` returns an array where each output pixel contains the entropy value of the 9-by-9 neighborhood around the corresponding pixel in the input image `I`. Entropy is a statistical measure of randomness.

You can also use `stdfilt` and `rangefilt` to achieve similar segmentation results. For comparison to the texture image of local entropy, create texture images `S` and `R` showing the local standard deviation and local range, respectively.

```E = entropyfilt(I); S = stdfilt(I,ones(9)); R = rangefilt(I,ones(9));```

Use `rescale` to rescale the texture images `E` and `S` so that pixel values are in the range [0, 1] as expected of images of data type `double`.

```Eim = rescale(E); Sim = rescale(S);```

Display the three texture images in a montage.

```montage({Eim,Sim,R},'Size',[1 3],'BackgroundColor','w',"BorderSize",20) title('Texture Images Showing Local Entropy, Local Standard Deviation, and Local Range')```

This example continues by processing the entropy texture image `Eim`. You can repeat a similar process for the other two types of texture images with other morphological functions to achieve similar segmentation results.

Threshold the rescaled image `Eim` to segment the textures. A threshold value of 0.8 is selected because it is roughly the intensity value of pixels along the boundary between the textures.

```BW1 = imbinarize(Eim,0.8); imshow(BW1) title('Thresholded Texture Image')```

The segmented objects in the binary image `BW1` are white. If you compare `BW1` to `I`, you notice the top texture is overly segmented (multiple white objects) and the bottom texture is segmented almost in its entirety. Remove the objects in the top texture by using `bwareaopen`.

```BWao = bwareaopen(BW1,2000); imshow(BWao) title('Area-Opened Texture Image')```

Use `imclose` to smooth the edges and to close any open holes in the object in `BWao`. Specify the same 9-by-9 neighborhood that was used by `entropyfilt`.

```nhood = ones(9); closeBWao = imclose(BWao,nhood); imshow(closeBWao) title('Closed Texture Image')```

Use `imfill` to fill holes in the object in `closeBWao`. The mask for the bottom texture is not perfect because the mask does not extend to the bottom of the image. However, you can use the mask to segment the textures.

```mask = imfill(closeBWao,'holes'); imshow(mask); title('Mask of Bottom Texture')```

Separate the textures into two different images.

```textureTop = I; textureTop(mask) = 0; textureBottom = I; textureBottom(~mask) = 0; montage({textureTop,textureBottom},'Size',[1 2],'BackgroundColor','w',"BorderSize",20) title('Segmented Top Texture (Left) and Segmented Bottom Texture (Right)')```

Display Segmentation Results

Create a label matrix that has the label 1 where the mask is `false` and the label 2 where the mask is `true`. Overlay label matrix on the original image.

```L = mask+1; imshow(labeloverlay(I,L)) title('Labeled Segmentation Regions')```

Outline the boundary between the two textures in cyan.

```boundary = bwperim(mask); imshow(labeloverlay(I,boundary,"Colormap",[0 1 1])) title('Boundary Between Textures')```