Mahotas – Closing Process on Image The closing process is reverse of the opening process. In this, first a dilation operation is performed, followed by an erosion operation. Dilation examines each pixel and its neighboring pixels. If any neighboring pixel is white, the center pixel is also turned white. This step helps expand or thicken the image and can fill in small gaps or holes. After dilation, erosion examines each pixel and its neighboring pixels. If any neighboring pixel is black, the center pixel is also turned black. This step helps shrink or remove unwanted details, such as thin protrusions and internal noise. The closing operation is effectively closes small holes or gaps in binary images, and smoothens or eliminates the small foreground regions. Closing Process on Image in Mahotas To perform the closing process in Mahotas, we use the mahotas.close() function. This method allows for the sequential application of dilation and erosion operations. Dilation expands the remaining structures while preserving their key features by replacing each pixel with the maximum value in its neighborhood. Subsequently, erosion reduces noise and eliminates small structures by considering each pixel”s neighborhood and replacing it with the minimum value. The mahotas.close() function The close() function in Mahotas takes two main arguments− the binary image and the structuring element (kernel). The function first applies a dilation operation to the input binary image. It then applies an erosion operation to the dilated image. The close() function returns the resulting closed image after the dilation and erosion operations have been performed. Syntax Following is the basic syntax of the close() function in mahotas − mahotas.close(f, Bc={3×3 cross}, out={np.empty_like(f)}) Where, f − It is the input binary image represented as a NumPy array. Bc − It is the structuring element used for both the dilation and erosion operations. Default is 3×3 cross-shaped structuring element. out − It is the output array. The result will be stored in a new array with the same shape and data type as the input image f. Example In the following example, we are performing the closing process on an image − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image = mh.imread(”sun.png”) closed_image = mh.close(image) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the closed image axes[1].imshow(closed_image, cmap=”gray”) axes[1].set_title(”Closed Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output After executing the above code, we get the following output − Using Random Binary Image We can also aperform closing process on an image by creating a random binary image. To achieve this, first we create a random binary image using NumPy, where the pixels are either 0 (background) or 1 (foreground). Once we have our binary image, we can proceed to perform morphological closing by using a structuring element. It will define the shape and size of the neighborhood for the dilation and erosion operations. Additionally, we create an empty array with the same shape as the input image to store the result. Finally, we get the resultant closed image. Example In here, we are trying to perform closing process on an image by creating a random binary image − import mahotas as mh import numpy as np from pylab import imshow, show # Create a random binary image image = np.random.randint(0, 2, size=(100, 50), dtype=np.bool_) Bc=np.ones((3,3)) # Perform morphological closing with a 3×3 cross structuring element result = mh.close(image, Bc, out=np.empty_like(image)) # Show the result imshow(result) show() Output The output produced is as shown below − Using a Grayscale Image We can also perform closing process on a grayscale image in mahotas. To achive this, we simply pass as_grey=True parameter while reading the image, ensuring that the image is loaded as a grayscale image. Next, we will perform morphological closing on the grayscale image. Example Now, we are performing the closing process on a grayscale image in mahotas − import mahotas as mh import numpy as np from pylab import imshow, show # Create a grayscale image image = mh.imread(”nature.jpeg”, as_grey = True).astype(np.uint8) Bc=np.ones((20,15)) # Perform morphological closing with a 3×3 cross structuring element result = mh.close(image, Bc, out=np.empty_like(image)) # Show the result imshow(result) show() Output Following is the output of the above code −
Category: mahotas
Mahotas – Overlaying Image Overlaying an image refers to placing one image on top of another image. It involves combining the pixel values of the two images to create a composite image. When overlaying an image, the top image is placed on the background image, allowing the pixels of the top image to partially or completely cover the pixels of the background image. This can be done with varying degrees of transparency, allowing the background image to show through to some extent. Overlaying Image in Mahotas We can overlay an image in mahotas using the overlay() function. This function ensures that the overlay image is aligned with the base image, taking into account their dimensions and pixel values. It automatically handles resizing or cropping the overlay image to match the size of the base image if necessary. To overlay an image in mahotas, we need to define the transparency or alpha value for the overlay image. This value determines how much the overlay image will cover the background image. The mahotas.overlay() function In mahotas we use mahotas.overlay() function to overlay an image. This function accepts a single channel image as an input and returns a resulting overlayed image. The mahotas.overlay() function selects the maximum pixel value for each pixel location, effectively combining the visual content of both images. This operation is particularly useful when the overlay image has transparency information (e.g., an alpha channel), as it allows the transparent parts of the overlay image to reveal the content of the base image. Syntax Following is the basic syntax of overlay() function in mahotas − mahotas.overlay(gray, red=None, green=None, blue=None, if_gray_dtype_not_uint8= ”stretch”) Parameters Following are the parameters accepted by the overlay() function in mahotas − gray − It is the grayscale image onto which the color channels will be superimposed. It acts as the canvas for overlaying. red, blue , green (optional) − These represents the individual color channels that will be overlayed on the grayscale image. They can be provided as separate arrays representing the intensity of each color channel. If any of these color channels are not specified (set to None), the resulting overlay image will only contain the grayscale information. if_gray_dtype_not_uint8 (optional) − It defines what to do if the input image is not of data type ”np.uint8”. Default is stretch. Example In the following example, we are trying to overlay an image with a binary mask (pixel values are either 0 (background) or 1 (foreground) − import numpy as np import mahotas as mh import matplotlib.pyplot as plt # Load the images image1 = mh.imread(”sea.bmp”) image2 = mh.imread(”tree.tiff”) image = mh.imread(”sea.bmp”, as_grey=True) # foreground image mask = mh.imread(”tree.tiff”, as_grey=True) > 0 overlay = mh.overlay(image, mask) # Display all three images in one plot plt.figure(figsize=(10, 5)) # Display image1 plt.subplot(1, 3, 1) plt.imshow(image1) plt.title(”Image 1”) plt.axis(”off”) # Display image2 plt.subplot(1, 3, 2) plt.imshow(image2) plt.title(”Image 2”) plt.axis(”off”) # Display the overlayed image plt.subplot(1, 3, 3) plt.imshow(overlay, cmap=”gray”) plt.title(”Overlayed Image”) plt.axis(”off”) plt.tight_layout() plt.show() Output The output obtained is as shown below − Overlaying a Transparent Image on another Image To overlay a transparent image on another image, we create a transparent overlay by creating an alpha channel, which determines the transparency of each pixel. We initialize an array of zeros with the same shape as the background image, representing the alpha channel. We set the transparency value as greater than 0 for pixels in the overlay image that are non−zero. Now, we can overlay the images by combining the background image, overlay image, and alpha channel. We multiply the background image by (1 − alpha) to reduce its intensity where the overlay image is present, and multiply the overlay image by the alpha channel to control its transparency. Finally, we add the two components together. Example Here, we are trying to overlay a transparent image on another image − import numpy as np import mahotas as mh from pylab import imshow, show # Load the images image = mh.imread(”tree.tiff”, as_grey=True) overlay = mh.imread(”sea.bmp”, as_grey=True) # Create a transparent overlay alpha = np.zeros(image.shape) alpha[overlay > 0] = 0.5 # Set transparency value for non-zero pixels in overlay # Overlay the images result = mh.stretch(mh.stretch(image) * (1 – alpha) + overlay * alpha) # Display the result imshow(result) show() Output Output of the above code is as follows − Overlaying an Image with a specified Transparency Level To overlay an image with a specified transparency level we need to first define the transparency level for the overlay image we desire. The transparency level is a value between 0.0 (fully transparent) and 1.0 (fully opaque). This value determines the blending ratio between the background image and the overlay image. Then using alpha blending, we can merge the images together based on the defined transparency level. Then we need to adjust the background image intensity by reducing the intensity of the background image in regions where the overlay image is present. To achieve this, we multiply the background image by (1 − alpha). We then control the transparency of the overlay image by multiplying it with the alpha value. The adjusted background image and the overlay image with controlled transparency are then added together to create the final overlayed image. Example Now, we are trying to overlay an image with a specified transparency level − import numpy as np import mahotas as mh from pylab import imshow, show # Load the images image = mh.imread(”tree.tiff”) overlay = mh.imread(”sea.bmp”) # Define the transparency level alpha = 0.5 # Blend the images using alpha blending and transparency level result = mh.stretch(mh.stretch(image) * (1 – alpha) + overlay * alpha) # Display the result imshow(result) show() Output Following is the output of the above code −
Mahotas – Resizing an Image When we refer to resizing an image, we mean changing the dimensions (width and height) of the image while maintaining its aspect ratio. Aspect ratio refers to the ratio of the width to the height of the image. Resizing can be done to either make the image larger or smaller. When you resize an image, you are altering the number of pixels in the image and potentially changing the visual representation of the content. Resizing an Image in Mahotas To resize an image in Mahotas, we can use the imresize() function provided by the library. This function resizes the image using an interpolation algorithm and returns the resized image as a new NumPy array. The interpolation algorithm is the method used to fill in the gaps between known pixel values when resizing or transforming an image. It estimates the missing pixel values by considering the values of neighboring pixels. Interpolation helps in creating a smooth transition between pixels, resulting in a continuous image. The imresiz() function The imresize() function in Mahotas takes two arguments − the image to be resized and the target size as a tuple (new_height, new_width). It resizes the image while maintaining the aspect ratio and returns the resized image as a new NumPy array. Syntax Following is the basic syntax of the imresize() function in mahotas − mahotas.imresize(image, nsize, order=3) Where, image − It is input image that you want to resize. nsize − It specifies the desired size of the output image. It should be a tuple (height, width) representing the target dimensions. order (optional) − It determines the interpolation order to beused during resizing. It has a default value of 3, which corresponds to bicubic interpolation. You can also choose other interpolation orders such as 0 (nearest−neighbor), 1 (bilinear), or 2 (quadratic). Example In the following example, we are trying to resize an image to a specific width and height using the imresize() function − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image = mh.imread(”sun.png”, as_grey = True) print(”Size before resizing :”+” ”+str(image.size)) print(”shape before resizing :”+” ”+str(image.shape)) resize=mh.imresize(image,[100,100]) print(”Size after resizing :”+” ”+str(resize.size)) print(”shape after resizing :”+” ”+str(resize.shape)) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the resized image axes[1].imshow(resize, cmap=”gray”) axes[1].set_title(”Resized Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output After executing the above code, we get the following output − Size before resizing : 1079040 shape before resizing : (1280, 843) Size after resizing : 10000 shape after resizing : (100, 100) The image obtained is as shown below − Using Bilinear Interpolation Bilinear interpolation is an interpolation algorithm commonly used for image resizing. It estimates the new pixel values by considering the weighted average of the four nearest neighboring pixels. These four pixels form a square around the target pixel, and their values contribute to determining the new pixel value. To resize an image using the bilinear interpolation in mahotas, we need to specify the interpolation order as 1 in the imresize() function. Example In here, we are trying to resize an image using the bilinear interpolation − import mahotas as mh image = mh.imread(“nature.jpeg”, as_grey = True) # Specifying the desired width and height new_width = 800 new_height = 600 # Resizing the image using nearest-neighbor interpolation resized_image = mh.imresize(image, [new_height, new_width], 1) print(resized_image) Output The output obtained is as follows − [[193.71 193.71 193.71 … 208.17 208.17 0. ] [193.71 193.71 193.71 … 208.17 208.17 0. ] [193.71 193.71 193.71 … 208.17 208.17 0. ] … [ 98.49 98.49 95.49 … 7.11 4.85 0. ] [ 90.05 90.05 94.12 … 5.33 5.07 0. ] [ 0. 0. 0. … 0. 0. 0. ]] Using Quadratic Interpolation Quadratic interpolation is also an interpolation algorithm commonly used for image resizing. It estimates the new pixel values by considering the weighted average of nearby pixels. Quadratic interpolation is particularly useful when working with curved or non−linear data. In simple terms, it involves fitting a parabolic curve through three neighboring pixel values to approximate the value at a desired position between them. To resize an image using the quadratic interpolation in mahotas, we need to specify the interpolation order as 2 in the imresize() function. Example Now, we are trying to resize an image using the quadratic interpolation in mahotas − import mahotas as mh image = mh.imread(“nature.jpeg”, as_grey = True) # Resizing the image using nearest-neighbor interpolation resized_image = mh.imresize(image, [700, 550], 2) print(resized_image) Output Following is the output of the above code − [[193.71 193.71 193.71 … 208.17 208.17 0. ] [193.71 193.71 193.71 … 208.17 208.17 0. ] [193.71 193.71 193.71 … 208.17 208.17 0. ] … [ 92.2 93.49 94.12 … 6.22 6.22 0. ] [ 92.27 98.05 92.42 … 6.33 4.85 0. ] [ 0. 0. 0. … 0. 0. 0. ]]
Mahotas – Conditional Eroding Image In our previous chapter, we explored the concept of image erosion, an operation used to shrink all the pixels to the boundaries of regions in an image. Conditional erosion on the other hand, shrinks (remove) the pixels of certain specific regions, based on some conditions. The condition can be based on the intensity values of the image pixels or some specific pattern in the image. For example, let”s consider a grayscale image. Instead of eroding all the foreground pixels, you could conditionally erode only those pixels that meet a certain intensity threshold. If a pixel”s intensity is below a predefined threshold, then erosion is applied; otherwise, the pixel remains unchanged. Conditional Eroding Image in Mahotas In mahotas, conditional erosion is an extension of the traditional erosion operation that comprises a condition based on a second image, often referred to as the “marker image.” It allows you to control the erosion process such that erosion only occurs at locations where the marker image has specific pixel values. We can perform the conditional erosion on an image in mahotas using the cerode() function. This function restricts the erosion process to specific regions based on the marker image”s pixel values. The mahotas.cerode() function The cerode() function in Mahotas takes two inputs− the input image and a mask (condition) array. It performs conditional erosion on the input image based on the provided condition, and it returns the resulting eroded image. Masks are used to identify specific regions within an image. They act as a filter that highlights certain areas while disregarding others. Syntax Following is the basic syntax of the cerode() function in mahotas − mahotas.cerode(f, g, Bc={3×3 cross}, out={np.empty_as(A)}) Where, f − It is the input image on which the conditional erosion is to be performed. g − It is the mask to be applied during conditional erosion. Bc={3×3 cross} (optional) − It is a structuring element used for dilation. Default is {3×3 cross}. out={np.empty_as(A)} (optional) − It provides an output array to store the result of the erosion operation Example In the following example, we are performing the conditional erosion on an image by scaling down its pixel intensity − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image= mh.imread(”nature.jpeg”) # Define the scaling factor scale_factor = 0.5 # Scale down the intensity by multiplying with the scale factor scaled_image = image * scale_factor # Convert the scaled image to the appropriate data type scaled_image = scaled_image.astype(np.uint8) conditional_eroded_image = mh.cerode(image, scaled_image) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the conditional eroded image axes[1].imshow(conditional_eroded_image, cmap=”gray”) axes[1].set_title(”Conditional Eroded Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output After executing the above code, we get the following output − Using Structuring Element To perform conditional erosion using structuring element in Mahotas, first, we need to define the condition based on which the erosion will be applied. For example, you can specify a condition based on pixel intensity or provide a binary mask. Next, choose a structuring element that defines the neighborhood for erosion. Mahotas provides several pre−defined structuring elements, such as disks and squares, which you can select based on the desired shape and size. Finally, retrieve the resulting image, which will contain the erosion effects only where the condition is satisfied. Example In here, we are trying to perform conditional erosion on an image using structuring elements − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image= mh.imread(”nature.jpeg”, as_grey = True).astype(np.uint8) # Define the condition based on pixel intensity condition = image > 0.5 # Define a structuring element for erosion structuring_element = mh.disk(5) conditional_eroded_image = mh.cerode(image, condition, structuring_element) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the conditional eroded image axes[1].imshow(conditional_eroded_image, cmap=”gray”) axes[1].set_title(”Conditional Eroded Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output The output obtained is as shown below − Using a Custom Condition Function We can also perform conditional erosion on an image using a custom condition function. To achieve this, we first define a custom condition function that determines which pixels should undergo erosion. Next, choose a structuring element to define the shape and size of erosion operation. Finally, perform the conditional erosion and retrieve the eroded image. Example Now, we are dilating an image using a custom condition function − import mahotas as mh import numpy as np import matplotlib.pyplot as plt # Load image image = mh.imread(”sea.bmp”, as_grey=True).astype(np.uint8) # Define a custom condition function def custom_condition(pixel_value): return pixel_value > 0.5 # Define a structuring element structuring_element = mh.disk(5) # Create a binary mask based on the custom condition function condition = custom_condition(image) # Perform conditional erosion conditional_eroded_image = mh.cerode(image, condition, structuring_element) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the conditional eroded image axes[1].imshow(conditional_eroded_image, cmap=”gray”) axes[1].set_title(”Conditional Eroded Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output Following is the output of the above code −
Mahotas – Displaying an Image Once you have loaded an image and performed various operations on it, you would need to display the final output image to view the results of your operations. Displaying an image refers to visually presenting the image data to a user or viewer on a screen. Displaying an Image in Mahotas We can display an image in Mahotas using the imshow() and show() functions from the mahotas.plotting module. It allows us to display images within a Python environment. This function internally uses the Matplotlib library to render the image. Let us discuss about the imshow() and show() function briefly. Using the imshow() Function The imshow() function is used to display an image in a separate window. It creates a new window and renders the image within it. This function provides various options to customize the display, such as adjusting the window size, colormap, and color range. Syntax Following is the basic syntax of imshow() function − imshow(image) Where, ”image” is the picture we want to display. Using the show() Function The show() function is used to display the current figure or image. It is a part of the matplotlib library from pylab module, which Mahotas uses for plotting and visualization. This function is particularly useful when you want to display multiple images or plots in the same window. Syntax Following is the basic syntax of show() function − show() Example In the following example, we are using the imshow() and show() functions to display an image file named “nature.jpeg” from the current directory − import mahotas as mh from pylab import imshow, show # Loading the image using Mahotas image = mh.imread(”nature.jpeg”) # displaying the original image imshow(image) show() Output Output of the above code is as follows − Displaying Multiple Images Mahotas also allows us to display multiple images simultaneously. This is useful when we want to compare or visualize different images side by side. Mahotas provides a wide range of image formats, including common formats like JPEG, PNG, BMP, TIFF, and GIF. Hence, we can display each image in different formats. The image formats refer to the different file formats used to store and encode images digitally. Each format has its own specifications, characteristics, and compression methods. Example In this example, we demonstrate the versatility of Mahotas by displaying images in different formats using imshow() and show() functions. Each loaded image is stored in a separate variable − import mahotas as ms import matplotlib.pyplot as mtplt # Loading JPEG image image_jpeg = ms.imread(”nature.jpeg”) # Loading PNG image image_png = ms.imread(”sun.png”) # Loading BMP image image_bmp = ms.imread(”sea.bmp”) # Loading TIFF image image_tiff = ms.imread(”tree.tiff”) # Creating a figure and subplots fig, axes = mtplt.subplots(2, 2) # Displaying JPEG image axes[0, 0].imshow(image_jpeg) axes[0, 0].axis(”off”) axes[0, 0].set_title(”JPEG Image”) # Displaying PNG image axes[0, 1].imshow(image_png) axes[0, 1].axis(”off”) axes[0, 1].set_title(”PNG Image”) # Displaying BMP image axes[1, 0].imshow(image_bmp) axes[1, 0].axis(”off”) axes[1, 0].set_title(”BMP Image”) # Displaying TIFF image axes[1, 1].imshow(image_tiff) axes[1, 1].axis(”off”) axes[1, 1].set_title(”TIFF Image”) # Adjusting the spacing and layout mtplt.tight_layout() # Showing the figure mtplt.show() Output The image displayed is as follows − Customizing Image Display When we talk about customizing image display in Mahotas, we are referring to the ability to modify various aspects of how the image is presented on the screen or in a plot. These customizations allow us to enhance the visual representation of the image and provide additional information to the viewer. Mahotas provides several options for customizing the image display. For instance, we can adjust the colormap, add titles, and modify the display size. Let us discuss each options for customizing the image display one by one. Applying Colormap Mahotas supports different color maps that can be applied to a grayscale or single−channel images to enhance their contrasts and visual appearance. Color maps determine how pixel values are mapped to colors. For example, the ”gray” color map is commonly used for grayscale images, while ”hot” or ”jet” color maps can be used to emphasize intensity variations in an image. By choosing an appropriate color map. To change the colormap used for displaying an image, we can pass the cmap argument to the imshow() function. The cmap argument accepts a string representing the name of the desired colormap. Example In the example below, we are passing the cmap argument to the imshow() function and setting it argument to ”gray” to display the grayscale image using a grayscale colormap − import mahotas as ms import matplotlib.pyplot as mtplt # Loading grayscale image grayscale_image = ms.imread(”nature.jpeg”, as_grey=True) # Displaying grayscale image mtplt.imshow(grayscale_image, cmap=”gray”) mtplt.axis(”off”) mtplt.show() Output After executing the above code, we get the output as shown below − Adding a Title We can also add a title or a caption to our image using the title argument passed to the imshow() function. Example In the code below, we are adding the title Nature Image” to the displayed image − import mahotas as ms import matplotlib.pyplot as mtplt # Loading the image image = ms.imread(”nature.jpeg”) # Displaying the image mtplt.imshow(image) mtplt.axis(”off”) mtplt.title(”Nature Image”) mtplt.show() Output Output of the above code is as follows − Figure Size Figure size in mahotas refers to the size of the plot or image display area where the image will be shown. We can also control the size of the displayed image by specifying the figsize argument of the imshow() function. The figsize argument expects a tuple representing the width and height of the figure in inches. Example In the example below, we are setting the figure size to (8, 6) inches − import mahotas as ms import matplotlib.pyplot as mtplt # Loading the image image = ms.imread(”nature.jpeg”) # Set the figure size using Matplotlib # Specify the width and height of the figure in inches fig = mtplt.figure(figsize=(8, 6)) # Displaying the image mtplt.imshow(image) mtplt.show() Output Output of the above code is as follows −
Mahotas – Threshold Adjacency Statistics Threshold adjacency statistics (TAS) is a technique used to extract any important information from an image. Before understanding how TAS works, let us understand thresholding in brief. Thresholding is a technique that separates an image into a foreground region and a background region based on a specific value (threshold value). The foreground region consists of pixels whose intensity value is greater than the threshold value. On the other hand, the background region consists of pixels whose intensity value is less than the threshold value. TAS work by counting the number of pixels whose intensity value exceeds the threshold value. Additionally, it considers a specified number of neighboring pixels whose intensity value also exceeds the threshold value. Threshold Adjacency Statistics in Mahotas In Mahotas, we can use the mahotas.tas() and mahotas.pftas() functions to calculate the threshold adjacency statistics of an image. The calculated statistics can then be used to locate and extract important information from the image. The only difference between the tas() function and the pftas() function is that in pftas() function, we can set any threshold value that is used to calculate TAS. In contrast, the tas() function does not use a threshold value to calculate TAS. The mahotas.tas() function The mahotas.tas() function takes an image as input and returns a list having the threshold adjacency statistics. Syntax Following is the basic syntax of the tas() function in mahotas − mahotas.features.tas(img) where, img − It is the input image. Example In the example mentioned below, we are calculating the TAS values of an image using the mh.tas() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the images image = mh.imread(”sun.png”) # Computing TAS tas = mh.features.tas(image) # Printing the TAS value print(tas) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 1) # Displaying the original image axes.imshow(image, cmap=”gray”) axes.set_title(”Original Image”) axes.set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Output of the above code is as follows − [8.37835351e-01 1.15467657e-02 1.39075269e-02 9.92426122e-03 1.03643093e-02 6.76089647e-03 1.09572672e-02 6.88336269e-03 8.17548510e-03 6.01115411e-02 6.08145111e-03 5.10483489e-03 4.16108390e-03 2.81568522e-03 1.77506830e-03 1.46786490e-03 6.81867008e-04 6.12677053e-04 2.44932441e-04 2.76759821e-04 . . . 4.27349413e-03 7.01932689e-03 4.50541370e-03 5.45604649e-03 6.41356563e-02 4.43892481e-03 4.80936290e-03 4.46979465e-03 3.91413752e-03 2.33898410e-03 3.27299467e-03 1.12872803e-03 2.06353013e-03 4.92334385e-04 1.22371215e-03 1.14772485e-04 6.03149199e-04 3.32444440e-05 3.26112165e-04 1.18730157e-05 1.28228570e-04 0.00000000e+00] We get the below image as output − The mahotas.pftas() function The mahotas.pftas() function takes an image and a threshold value as inputs. It returns a list having the threshold adjacency statistics. Syntax Following is the basic syntax of the pftas() function in mahotas − mahotas.features.pftas(img, T={mahotas.threshold.otsu(img)}) where, img − It is the input image. T (optional) − It defines the threshold algorithm used in TAS (by default it uses Otsu”s method). Example In the following example, we are computing the TAS of an image using the mh.pftas() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the images image = mh.imread(”nature.jpeg”) # Converting it to grayscale image = mh.colors.rgb2gray(image).astype(np.uint8) # Computing parameter free TAS pftas = mh.features.pftas(image) # Printing the parameter free TAS value print(pftas) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 1) # Displaying the original image axes.imshow(image, cmap=”gray”) axes.set_title(”Original Image”) axes.set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Following is the output of the above code − [9.57767091e-01 1.48210628e-02 8.58153775e-03 1.18217967e-02 3.89970314e-03 1.86659948e-03 7.82131473e-04 3.19863291e-04 1.40214046e-04 9.73817262e-01 1.23385295e-02 5.89271152e-03 4.39412383e-03 1.90987201e-03 8.34387151e-04 4.60922081e-04 2.31642892e-04 1.20548852e-04 9.77691695e-01 8.29460231e-03 3.91949031e-03 7.21369229e-03 1.68522833e-03 7.53014919e-04 3.10737802e-04 1.12475646e-04 1.90636688e-05 9.47186804e-01 1.14563743e-02 9.65510102e-03 1.76918166e-02 5.35205921e-03 3.38515157e-03 2.13944340e-03 1.88754119e-03 1.24570817e-03 9.80623501e-01 3.72244140e-03 2.75392589e-03 4.22681210e-03 2.28359248e-03 1.92155953e-03 1.72971300e-03 1.63378974e-03 1.10466466e-03 9.59139669e-01 7.94832237e-03 7.15439233e-03 1.68349257e-02 3.75312384e-03 1.74123294e-03 9.83390623e-04 1.06007705e-03 1.38486661e-03] The image obtained is as follows − Using Mean Threshold Value We can also calculate the threshold adjacency statistics of an image using the mean threshold value. Mean threshold value refers to a threshold value calculated by taking the average pixel intensity value of an image. In simple terms, the threshold value is calculated by adding up the intensity values of all the pixels in an image and then dividing that sum by the total number of pixels in the image. In mahotas, we first calculate the mean threshold value using the mean() function. Then, we set this value in the T parameter of the pftas() function to calculate TAS using mean threshold value. Example In here, we are getting the TAS of an image using the mean threshold value. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the images image = mh.imread(”tree.tiff”) # Converting it to grayscale image = mh.colors.rgb2gray(image).astype(np.uint8) # Calculating threshold value threshold = image > np.mean(image) # Computing parameter free TAS using mean threshold pftas = mh.features.pftas(image, threshold) # Printing the parameter free TAS value print(pftas) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 1) # Displaying the original image axes.imshow(image, cmap=”gray”) axes.set_title(”Original Image”) axes.set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output After executing the above code, we get the following output − [0.63528106 0.07587514 0.06969174 0.07046435 0.05301355 0.0396411 0.0278772 0.0187047 0.00945114 0.51355051 0.10530301 0.0960256 0.08990634 0.06852526 0.05097649 0.03778379 0.02519265 0.01273634 0.69524747 0.0985423 0.07691423 0.05862548 0.03432296 0.01936853 0.01058033 0.00482901 0.00156968 0.46277808 0.17663377 0.13243407 0.10085554 0.06345864 0.03523172 0.01735837 0.00835911 0.00289069 0.78372479 0.0746143 0.04885744 0.03739208 0.02555628 0.01563048 0.00822543 0.00436208 0.00163713 0.70661663 0.07079426 0.05897885 0.06033083 0.04280415 0.02972053 0.01632203 0.01043743 0.00399529] The output image is as follows −
Mahotas – Opening Process on Image Opening is a two−step process used in image processing. First, an erosion operation is performed, followed by a dilation operation. Erosion shrinks or removes unwanted details by examining each pixel and its neighboring pixels. If any neighboring pixel is black, the center pixel is also turned black. This step helps eliminate thin protrusions and internal noise. Protrusions are thin or elongated structures that extend outward from a surface. After erosion, dilation is performed to expand or thicken the image. It looks at each pixel and its neighbors, and if any neighboring pixel is white, the center pixel is turned white. Opening effectively removes small details and noise while preserving the main structures of the image. Opening Process on Image in Mahotas To perform the opening process in Mahotas, we use the mahotas.open() function. This method allows for the sequential application of erosion and dilation operations. Erosion reduces noise and eliminates small structures by considering each pixel”s neighborhood and replacing it with the minimum value. Subsequently, dilation expands the remaining structures while preserving their key features by replacing each pixel with the maximum value in its neighborhood. The mahotas.open() function The open() function in Mahotas takes two main arguments − the binary image and the structuring element (kernel). The function first applies an erosion operation to the input binary image. It then applies a dilation operation to the eroded image. The open() function returns the resulting opened image after the erosion and dilation operations have been performed. Syntax Following is the basic syntax of the open() function in mahotas − mahotas.open(f, Bc={3×3 cross}, out={np.empty_like(f)}) Where, f − It is the input binary image represented as a NumPy array. Bc − It is the structuring element used for both the erosion and dilation operations. Default is 3×3 cross-shaped structuring element. out − It is the output array. The result will be stored in a new array with the same shape and data type as the input image f. Example In the following example, we are performing the opening process on an image − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image = mh.imread(”sun.png”) opened_image = mh.open(image) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the opened image axes[1].imshow(opened_image, cmap=”gray”) axes[1].set_title(”Opened Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output After executing the above code, we get the following output − Using Random Binary Image We can also perform opening process on an image by creating a random binary image. To achieve this, first we create a random binary image using NumPy, where the pixels are either 0 (background) or 1 (foreground). Once we have our binary image, we can proceed to perform morphological opening by using a structuring element. It will define the shape and size of the neighborhood for the erosion and dilation operations. Additionally, we create an empty array with the same shape as the input image to store the result. Finally, we get the resultant opened image. Example In here, we are trying to perform opening process on an image by creating a random binary image − import mahotas as mh import numpy as np from pylab import imshow, show # Create a random binary image image = np.random.randint(0, 2, size=(100, 50), dtype=np.bool_) Bc=np.ones((3,3)) # Perform morphological opening with a 3×3 cross structuring element result = mh.open(image, Bc, out=np.empty_like(image)) # Show the result imshow(result) show() Output The output produced is as shown below − Using a Grayscale Image We can also perform opening process on a grayscale image in mahotas. To achive this, we simply pass as_grey=True parameter while reading the image, ensuring that the image is loaded as a grayscale image. Next, we will perform morphological opening on the grayscale image. Example Now, we are performing the opening process on a grayscale image in mahotas − import mahotas as mh import numpy as np from pylab import imshow, show # Create a grayscale image image = mh.imread(”nature.jpeg”, as_grey = True).astype(np.uint8) Bc=np.ones((20,15)) # Perform morphological opening with a 3×3 cross structuring element result = mh.open(image, Bc, out=np.empty_like(image)) # Show the result imshow(result) show() Output Following is the output of the above code −
Mahotas – Closing Holes in an Image Closing holes in an image refers to removing small gaps or holes in the foreground regions of an image. In the closing process, first a dilation operation is performed, followed by an erosion operation. Dilation expands the boundaries of the foreground regions. For each pixel, the dilation operation examines its neighbors according to the structuring element. If any neighboring pixel is white, the center pixel is also turned white. This process helps to fill in gaps or holes within the foreground regions. After dilation, erosion shrinks the boundaries of the foreground regions. Again, using the structuring element, erosion examines each pixel and its neighbors. If any neighboring pixel is black, the center pixel is turned black. This step helps to refine and smooth the contours of the foreground regions while preserving the main structures. Closing Holes in an Image in Mahotas To perform the closing holes process in Mahotas, we use the mahotas.close_holes() function. This method allows for the sequential application of dilation and erosion operations. By applying the dilation operation first (to expand the regions) and then the erosion operation (to refine the boundaries), the closing operation effectively closes small holes or gaps in the foreground regions of the binary image. The mahotas.close_holes() function The close_holes() function in Mahotas takes the binary image as an input and returns the resulting image with the holes closed. The close_holes() function automatically detects and closes the holes without the need for explicitly defining a structuring element. Syntax Following is the basic syntax of the close_holes() function in mahotas − mahotas.close_holes(ref, Bc=None) Where, ref − It is the input binary image. Bc − It specifies the structuring element or kernel used for the closing operation. If not provided (set to None), a default structuring element will be used. Example In the following example, we are closing the holes in an image − import mahotas as mh import numpy as np import matplotlib.pyplot as plt image = mh.imread(”pic.jpg”,as_grey = True) closed_holes_image = mh.close_holes(image) # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the closed holes image axes[1].imshow(closed_holes_image, cmap=”gray”) axes[1].set_title(”Closed Holes Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output After executing the above code, we get the following output − Using Random Binary Image We can also perform closing holes’ process in an image by creating a random binary image. To achieve this, first we create a random binary image using NumPy, where the pixels are either 0 (background) or 1 (foreground). Once we have our binary image, we can proceed to perform morphological closing by using a structuring element. It will define the shape and size of the neighborhood for the dilation and erosion operations. Finally, we get the resultant closed holes in an image. Example In here, we are trying to perform closing holes’ process in an image by creating a random binary image − import mahotas as mh import numpy as np from pylab import imshow, show # Create a random binary image image = np.random.randint(0, 2, size=(100, 50), dtype=np.bool_) Bc=np.ones((3,3)) # Perform morphological closing holes with a 3×3 cross structuring element result = mh.close_holes(image, Bc) # Show the result imshow(result) show() Output The output produced is as shown below − Closing Holes with Multiple Iterations For closing holes with multiple iterations, we aim to gradually fill in smaller holes and refine the result repeatedly. We start by creating a copy of the original binary image. This copy will serve as the starting point for each iteration of the hole closing process. Then, using a for loop, we iterate a specified number of times. During each iteration, the mahotas.close_holes() function is applied to the current version of the image. The function identifies holes in the image and fills them, gradually improving the connectivity and continuity of the foreground regions. Example Now, we are closing the holes in an image with multiple iterations − import mahotas import numpy as np import matplotlib.pyplot as plt image = mahotas.imread(”pic.jpg”, as_grey = True) # Close the holes in the binary image with multiple iterations closed_image = image.copy() for i in range(3): closed_image = mahotas.close_holes(closed_image) # Display the original and closed images fig, axes = plt.subplots(1, 2, figsize=(10, 5)) axes[0].imshow(image, cmap=”gray”) axes[0].set_title(”Original Image”) axes[1].imshow(closed_image, cmap=”gray”) axes[1].set_title(”Closed Image”) plt.tight_layout() plt.show() Output Following is the output of the above code −
Mahotas – Image Thresholding Image thresholding is the technique of separating regions of interest from the background based on pixel intensities. It involves setting a threshold value, which divides the image between the foreground and the background. Pixels with intensities above the threshold are classified as the foreground, while those below the threshold are classified as the background. This binary separation allows for further analysis, such as object detection, segmentation, or feature extraction. Image thresholding can be applied to various types of images, including grayscale and color images, to simplify subsequent processing and analysis tasks. The use of image thresholding involves selecting an appropriate threshold value and applying it to the image. The threshold value can be calculated using various thresholding techniques. The choice of the thresholding method depends on factors such as image properties, noise levels, and desired results. Here, we have discussed each technique in brief. In−depth information is discussed in the later chapters. Let us look at each thresholding technique which can be done in mahotas − Bernsen Thresholding Bernsen thresholding is a thresholding technique that separates the foreground from the background in grayscale images. It calculates a local threshold value based on the maximum and minimum pixel intensities within a neighborhood around each pixel. If the pixel”s intensity is closer to the maximum value, it is considered part of the foreground; otherwise, it is considered as part of the background. Let’s see the Bernsen threshold image below − Generalized Bernsen Thresholding Generalized Bernsen thresholding is an improvement of the Bernsen thresholding method. It considers a wider range of pixel intensities within the neighborhood, instead of only the maximum and minimum intensity values. The following images show generalized Bernsen threshold image − Otsu Thresholding Otsu thresholding technique automatically determines the optimal threshold value to separate the foreground from the background. Otsu”s method iteratively examines all possible threshold values and selects the threshold value that maximizes the betweenclass variance. Let”s look at Otsu threshold image below − Riddler-Calvard Thresholding Riddler−Calvard thresholding also automatically determines the optimal threshold value. It is based on the minimization of the weighted sum of the foreground and the background variances. Let us look at the Riddler−Calvard threshold image below − Soft Thresholding Soft thresholding is a technique used in image denoising. It sets pixels with intensity value less than a certain threshold to zero. Soft thresholding preserves the important structural information of the image while reducing noise. The following image shows soft thresholding − Example In the following example, we are trying to perform all the above explained thresholding techniques − import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt image = mh.imread(”sea.bmp”, as_grey=True) # Bernsen thresholding bernsen = mh.thresholding.bernsen(image, 5, 5) mtplt.imshow(bernsen) mtplt.title(”Bernsen Thresholding”) mtplt.axis(”off”) mtplt.show() # Generalized Bernsen thresholding gbernsen = mh.thresholding.gbernsen(image, mh.disk(3), 10, 109) mtplt.imshow(gbernsen) mtplt.title(”Generalized Bernsen Thresholding”) mtplt.axis(”off”) mtplt.show() # Otsu threshold int_image_otsu = image.astype(np.uint8) otsu = mh.otsu(int_image_otsu) result_image = image > otsu mtplt.imshow(result_image) mtplt.title(”Otsu Thresholding”) mtplt.axis(”off”) mtplt.show() # Riddler-Calvard threshold int_image_rc = image.astype(np.uint8) rc = mh.thresholding.rc(int_image_rc) final_image = image > rc mtplt.imshow(final_image) mtplt.title(”RC Thresholding”) mtplt.axis(”off”) mtplt.show() # Soft threshold soft = mh.thresholding.soft_threshold(image, np.mean(image)) mtplt.imshow(soft) mtplt.title(”Soft Thresholding”) mtplt.axis(”off”) mtplt.show() Output The output obtained is as shown below − Bernsen Thresholding: Generalized Bernsen Thresholding: Otsu Thresholding: Riddler−Calvard Thresholding: Soft Thresholding: We will discuss about all the thresholding techniques in detail in the remaining chapters.
Mahotas – Watershed In image processing, a watershed algorithm is used for image segmentation, which is the process of dividing an image into distinct regions. The watershed algorithm is particularly useful for segmenting images with uneven regions or regions with unclear boundaries. The watershed algorithm is inspired by the concept of a watershed in hydrology, where water flows from high to low areas along ridges until it reaches the lowest points, forming basins. Similarly, in image processing, the algorithm treats the grayscale values of an image as a topographic surface, where high intensity values represent the peaks and low intensity values represent the valleys. Working of Watershed Algorithm Here”s a general overview of how the watershed algorithm works in image processing − Image Preprocessing : Convert the input image to a grayscale image (if it is not in grayscale). Perform any necessary preprocessing steps, such as noise removal or smoothing, to improve the results. Gradient Calculation : Calculate the gradient of the image to identify the intensity transitions. This can be done by using gradient operators, such as the Sobel operator, to highlight the edges. Marker Generation : Identify the markers that will be used to initiate the watershed algorithm. These markers generally correspond to the regions of interest in the image. They can be manually specified by the user or automatically generated based on certain criteria, such as local minima or a clustering algorithm. Marker Labeling : Label the markers in the image with different integer values, representing different regions. Watershed Transformation : Calculate the watershed transformation of the image using the labeled markers. This is done by simulating a flooding process, where the intensity values propagate from the markers and fill the image until they meet at the boundaries of different regions. The result is a grayscale image where the boundaries between regions are highlighted. Post−processing : The watershed transform may produce over−segmented regions. Post−processing steps, such as merging or smoothing, can be applied to refine the segmentation results and obtain the final segmented image. Watershed in Mahotas The Mahotas library does not have a direct function for applying traditional watershed algorithm on an image. However, Mahotas does offer a similar technique called , which we will explore and discuss in more detail in our further chapter. To have a better understanding on traditional watershed algorithm, let us see an example of performing image segmentation using watershed algorithm with the help of the cv2 library. Example In the following example, we are applying Otsu”s thresholding, morphological operations, and distance transform to preprocess the image and obtain the foreground and background regions. We are then using marker−based watershed segmentation to label the regions and mark the boundaries as red in the segmented image. import cv2 import numpy as np from matplotlib import pyplot as plt image = cv2.imread(”tree.tiff”) # Convert the image to grayscale gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # Apply Otsu”s thresholding _, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # Perform morphological opening for noise removal kernel = np.ones((3, 3), np.uint8) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) # Perform distance transform dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5) # Threshold the distance transform to obtain sure foreground _, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0) sure_fg = np.uint8(sure_fg) # Determine the sure background region sure_bg = cv2.dilate(opening, kernel, iterations=3) # Determine the unknown region unknown = cv2.subtract(sure_bg, sure_fg) # Label the markers for watershed _, markers = cv2.connectedComponents(sure_fg) markers = markers + 1 markers[unknown == 255] = 0 # Apply watershed algorithm markers = cv2.watershed(image, markers) image[markers == -1] = [255, 0, 0] # Create a figure with subplots fig, axes = plt.subplots(1, 2, figsize=(7,5 )) # Display the original image axes[0].imshow(image) axes[0].set_title(”Original Image”) axes[0].axis(”off”) # Display the watershed image axes[1].imshow(markers) axes[1].set_title(”Watershed Image”) axes[1].axis(”off”) # Adjust the layout and display the plot plt.tight_layout() plt.show() Output Following is the output of the above code −