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 −
Category: mahotas
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 – Morphological Operators Morphological operators are a set of image processing techniques that help modify the shape, size, and spatial relationships of objects in an image. They are like tools used to reshape or manipulate the objects within an image. Imagine you have a picture with various objects like circles, squares, and lines. Morphological operators allow you to change the appearance of these objects in different ways. For example, you can make them bigger or smaller, smooth their edges, remove tiny details, or fill in gaps. To achieve these transformations, morphological operators use mathematical operations that involve scanning the image with a special pattern called a structuring element. This structuring element defines the shape and size of the neighborhood around each pixel that will be considered during the operation. Mahotas and Morphological Operators Mahotas provides a comprehensive set of morphological operators that can be applied to binary, grayscale, or multichannel images. These operators are implemented efficiently using optimized algorithms, making them suitable for real−world applications with largescale datasets. Let us look at few morphological operations which can be done in mahotas − Dilation Dilation is a morphological operation that expands the pixels on the boundaries of objects in an image. It involves scanning the image with a structuring element and replacing each pixel with the maximum value within the corresponding neighborhood defined by the structuring element. Let us look at the dilated image along with the original image below − Erosion Erosion is a basic morphological operator that shrinks or erodes the pixels on boundaries of objects in an image. Following is the eroded image along with its original image − Opening Opening is a combination of erosion followed by dilation. It removes small objects and fills in small holes in the foreground while preserving the overall shape and connectivity of larger objects. Let us look at the opened image in mahotas − Closing Closing is the reverse of opening, consisting of dilation followed by erosion. It fills small gaps and holes within the foreground, ensuring the connectivity of objects. Now, let us look at the closed image in mahotas − Conditional Erosion Conditional erosion is a morphological operation that preserves structures in an image based on a user−defined condition. It selectively erodes regions of an image based on the condition specified by a second image called the marker image. The operation erodes the image only where the marker image has non−zero values. Following image shows conditional erosion − Conditional Dilation Conditional dilation is similar to conditional erosion but operates in the opposite way. It selectively dilates regions of an image based on the condition specified by the marker image. The operation dilates the image only where the marker image has non−zero values. Following image shows conditional dilation − Regional Maxima Regional maxima are points in an image that have the highest intensity within their neighborhood. They represent local peaks or salient features in the image. The regional maxima operator in Mahotas identifies these local maxima and marks them as foreground pixels. Following image represents regional maxima − Regional Minima Regional minima are points in an image that have the lowest intensity within their neighborhood. They represent local basins or depressions in the image. The regional minima operator in Mahotas identifies these local minima and marks them as background pixels. Following image represents regional minima − Example In the following example, we are trying to perform all the above explained morphological operations − import mahotas as mh import matplotlib.pyplot as plt import numpy as np image = mh.imread(”nature.jpeg”, as_grey=True).astype(np.uint8) # Dilation dilated_image = mh.dilate(image, Bc=mh.disk(8)) plt.title(“Dilated Image”) plt.imshow(dilated_image) plt.show() # Erosion plt.title(“Eroded Image”) eroded_image = mh.erode(image, Bc=mh.disk(8)) plt.imshow(eroded_image) plt.show() # Opening plt.title(“Opened Image”) opened_image = mh.open(image) plt.imshow(opened_image) plt.show() # Closing plt.title(“Closed Image”) closed_image = mh.close(image) plt.imshow(closed_image) plt.show() # Conditional Dilation plt.title(“Conditional Dilation”) g = image * 6 cdilated_image = mh.cdilate(image, g) plt.imshow(cdilated_image) plt.show() # Conditional Erosion plt.title(“Conditional Erosion”) scaled_image = image * 0.5 scaled_image = scaled_image.astype(np.uint8) ceroded_image = mh.cerode(image, scaled_image) plt.imshow(ceroded_image) plt.show() # Regional Maxima plt.title(“Regional Maxima”) regional_maxima = mh.regmax(image) plt.imshow(regional_maxima) plt.show() # Regional Minima plt.title(“Regional Minima”) regional_minima = mh.regmin(image) plt.imshow(regional_minima) plt.show() Output The output obtained is as shown below − Dilation: Erosion: Opened Image: Closed Image: Conditional Dilation: Conditional Erosion: Regional Maxima: Regional Minima: We will discuss about all the morphological operators in detail in the remaining chapters of this section.
Mahotas – Border Pixels Border pixels are the pixels lying on the boundaries or edges of an image. A border pixel has at least one neighboring pixel that belongs to a different region or has a different value, indicating the transition between regions of interest and the background. For example, in a binary image where objects are represented by white pixels and the background is represented by black pixels, the border pixels would be those white pixels that are adjacent to black pixels. Border Pixels in Mahotas In Mahotas, we can extract border pixels using the labeled.border() and labeled.borders() functions. These functions detect borders by examining neighboring pixels that have different labels while also considering the connectivity specified by the structuring element. Using the mahotas.labeled.border() Function The mahotas.labeled.border() function take a labeled image as input and return a binary image of the same size showing the border pixels. This function extracts border pixels between two specified regions of a labeled image. In the resultant image, the border pixels are marked as True (or 1) and non−border pixels as False (or 0). Syntax Following is the basic syntax of the border() function in mahotas − mahotas.labeled.border(labeled, i, j, Bc={3×3 cross}, out={np.zeros(labeled.shape, bool)}, always_return=True) where, labeled − It is the input array. i − It is the label of the first region. j − It is the label of the second region. Bc (optional) − It is the structuring element used for connectivity. out (optional) − It is the output array (defaults to new array of same shape as labeled). always_return (optional) − It is a flag to indicate whether to return an output if no border pixels are present (defaults to True). Example In the following example, we are extracting the border pixels of labeled region 1 using the mh.labeled.border() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”sea.bmp”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Converting it to a labeled image labeled, num_objects = mh.label(image) # Getting border pixels border_pixels = mh.labeled.border(labeled, 0, 1) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the border pixels axes[1].imshow(border_pixels) axes[1].set_title(”Border Pixels”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Show the figure mtplt.show() Output Following is the output of the above code − Using the mahotas.labeled.borders() Function The mahotas.labeled.borders() function extracts all the border pixels from a labeled image. It is similar to mahotas.labeled.border() function in that it examines neighboring pixels that have different labels to detect borders. It also produces a binary image where the border pixels are marked as True (or 1) and non−border pixels as False (or 0). Syntax Following is the basic syntax of the borders() function in mahotas − mahotas.labeled.borders(labeled, Bc={3×3 cross}, out={np.zeros(labeled.shape, bool)}) where, labeled − It is the input array. Bc (optional) − It is the structuring element used for connectivity. out (optional) − It is the output array (defaults to new array of same shape as labeled). Example In here, we are extracting all the border pixels of a labeled image using the mh.labeled.borders() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”nature.jpeg”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Converting it to a labeled image labeled, num_objects = mh.label(image) # Get border pixels border_pixels = mh.labeled.borders(labeled) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the border pixels axes[1].imshow(border_pixels) axes[1].set_title(”Border Pixels”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Output of the above code is as follows − Using Custom Structuring Element We can also use a custom structuring element to detect border pixels more accurately. A structuring element is a binary array of odd dimensions consisting of ones and zeroes. It defines the connectivity pattern of the neighborhood pixels when identifying border pixels.We can define a custom structuring element by using the array() function in the numpy library. For example let”s consider the binary array: [[0, 1, 0],[0, 1, 0],[0, 1, 0]] as the structuring element. This structuring element implies vertical connectivity, meaning that for each pixel only the pixels directly above and below it (in the same column) are considered as its neighbors. By default, both mahotas.labeled.border() and mahotas.labeled.borders() uses a 3×3 cross−shaped structuring element. This structuring element considers the four immediate neighbors (top, bottom, left, and right) of each pixel when determining connectivity. Example The following example shows the extraction of border pixels using a custom structuring element. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”sun.png”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Converting to a labeled image labeled, num_objects = mh.label(image) # Creating a custom structuring element binary_closure = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]]) # Getting border pixels border_pixels = mh.labeled.borders(labeled, Bc=binary_closure) # Create a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the border pixels axes[1].imshow(border_pixels) axes[1].set_title(”Border Pixels”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output The output produced is as shown below −
Mahotas – Labeling Images Labeling images refers to assigning categories (labels) to different regions of an image. The labels are generally represented as integer values, where each value corresponds to a specific category or region. For example, let”s consider an image with various objects or regions. Each region is assigned a unique value (integer) to differentiate it from other regions. The background region is labeled with a value of 0. Labeling Images in Mahotas In Mahotas, we can label images using label() or labeled.label() functions. These functions segment an image into distinct regions by assigning unique labels or identifiers to different connected components within an image. Each connected component is a group of adjacent pixels that share a common property, such as intensity or color. The labeling process creates an image where pixels belonging to the same region are assigned the same label value. Using the mahotas.label() Function The mahotas.label() function takes an image as input, where regions of interest are represented by foreground (non−zero) values and the background is represented by zero. The function returns the labeled array, where each connected component or region is assigned a unique integer label. The label() function performs labeling using 8−connectivity, which refers to the relationship between pixels in an image, where each pixel is connected to its eight surrounding neighbors, including the diagonals. Syntax Following is the basic syntax of the label() function in mahotas − mahotas.label(array, Bc={3×3 cross}, output={new array}) where, array − It is the input array. Bc (optional) − It is the structuring element used for connectivity. output (optional) − It is the output array (defaults to new array of same shape as array). Example In the following example, we are labeling an image using the mh.label() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”sun.png”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Converting it to a labeled image labeled, num_objects = mh.label(image) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the labeled image axes[1].imshow(labeled) axes[1].set_title(”Labeled Image”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Following is the output of the above code − Using the mahotas.labeled.label() Function The mahotas.labeled.label() function assigns consecutive labels starting from 1 to different regions of an image. It works similar to mahotas.label() function to segment an image into distinct regions. If you have a labeled image with non−sequential label values, the labeled.label() function updates the label values to be in sequential order. For example, let’s say we have a labeled image with four regions having labels 2, 4, 7, and 9. The labeled.label() function will transform the image into a new labeled image with consecutive labels 1, 2, 3, and 4 respectively. Syntax Following is the basic syntax of the labeled.label() function in mahotas − mahotas.labeled.label(array, Bc={3×3 cross}, output={new array}) where, array − It is the input array. Bc (optional) − It is the structuring element used for connectivity. output (optional) − It is the output array (defaults to new array of same shape as array). Example The following example shows conversion of an image to a labeled image using mh.labeled.label() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”sea.bmp”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Converting it to a labeled image labeled, num_objects = mh.labeled.label(image) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the labeled image axes[1].imshow(labeled) axes[1].set_title(”Labeled Image”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Following is the output of the above code − Using Custom Structuring Element We can use a custom structuring element with the label functions to segment an image as per the requirement. A structuring element is a binary array of odd dimensions consisting of ones and zeroes that defines the connectivity pattern of the neighborhood pixels during image labeling. The ones indicate the neighboring pixels that are included in the connectivity analysis, while the zeros represent the neighbors that are excluded or ignored. For example, let”s consider the custom structuring element: [[1, 0, 0], [0, 1, 0], [0, 0,1]]. This structuring element implies diagonal connectivity. It means that for each pixel in the image, only the pixels diagonally above and below it is considered its neighbors during the labeling or segmentation process. Example Here, we have defined a custom structuring element to label an image. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image_rgb = mh.imread(”sea.bmp”) image = image_rgb[:,:,0] # Applying gaussian filtering image = mh.gaussian_filter(image, 4) image = (image > image.mean()) # Creating a custom structuring element binary_closure = np.array([[0, 1, 0], [0, 1, 0], [0, 1, 0]]) # Converting it to a labeled image labeled, num_objects = mh.labeled.label(image, Bc=binary_closure) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original RGB image axes[0].imshow(image_rgb) axes[0].set_title(”RGB Image”) axes[0].set_axis_off() # Displaying the labeled image axes[1].imshow(labeled) axes[1].set_title(”Labeled Image”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figure mtplt.show() Output After executing the above code, we get the following output −
Mahotas – Finding Image Mean When we talk about finding the image mean, we are referring to the calculation of the average intensity value across all the pixels in an image. Each pixel in a digital image is represented by a numerical value that corresponds to its intensity or color information. The range of intensity values depends on the image”s color depth, such as 8−bit (0−255) for grayscale images or 24−bit (0−255 for each color channel) for color images. Finding the image mean involves summing up the intensity values of all the pixels in the image and dividing it by the total number of pixels. This process provides a single value that represents the average intensity of the image. It can be interpreted as the overall brightness or intensity level of the image. Finding Image Mean in Mahotas We can find the image mean in Mahotas using the mahotas.mean() function. This function accepts an image array and returns its mean value. As we know that Mahotas can find the mean of only one channel at a time, therefore we need to convert our colored image to a single channel to find the mean of that channel. The mean function returns a scalar value representing the mean of all the pixels in the image. Syntax Following is the basic syntax of the mean function − Image_name.mean() Example In the following example, we are finding the mean of an image and displaying the image with mean intensity − import mahotas as mh import numpy as np from pylab import imshow, show import matplotlib.pyplot as plt image = mh.imread(”nature.jpeg”, as_grey = True) find_mean = image.mean() print(“Mean of the image is:”, find_mean) imshow(image,cmap=”gray”) show() Output Mean of the image is: 134.99541438411237 The image displayed is as shown below − Image Mean of each Channel Individually We can also find the mean of each channel in an RGB image using Mahotas. Firstly, calculate the mean for the entire image, and then calculate the mean for each channel individually using array slicing. The slice image[:, :, 0] corresponds to Channel 0 (Red), image[:, :, 1] corresponds to Channel 1 (Green), and image[:, :, 2] corresponds to Channel 2 (Blue). It calculates the mean for each channel using the mean() function and prints the results. Example In this example, we are trying to find the mean value of an image for individual channels − import mahotas as mh import numpy as np image = mh.imread(”sun.png”) # Calculating the mean of the entire image print(“Mean of the image: {0}”.format(image.mean())) # Calculating the mean of Channel 0 (Red) img0 = image[:, :, 0] print(”Mean of channel 0: {0}”.format(img0.mean())) # Calculating the mean of Channel 1 (Green) img1 = image[:, :, 1] print(”Mean of channel 1: {0}”.format(img1.mean())) # Calculating the mean of Channel 2 (Blue) img2 = image[:, :, 2] print(”Mean of channel 2: {0}”.format(img2.mean())) Output After executing the above code, we get the output as shown below − Mean of the image: 105.32921300415184 Mean of channel 0: 126.04734671559905 Mean of channel 1: 106.04269535883749 Mean of channel 2: 83.89759693801898 Finding the Mean of an ROI in an Image We can find the mean of a Region of Interest (ROI) within the image using the slice operations on the image array. After that, the mean value of all channels (if the image is in color) or the mean value of the grayscale values (if the image is in grayscale) within the ROI is calculated. Following is the syntax to define an ROI of an image − image[start_row:end_row, start_column:end_column] Where, ”start_row” and ”end_row” represent the range of rows, and ”start_column” and ”end_column” represent the range of columns that define the ROI. Hence, to specify the region of interest within the image, we select a subset of rows and columns. Example Here, we are fining the mean of a region of interet of an image − import mahotas as mh import numpy as np image = mh.imread(”tree.tiff”) # Defining a specific region of interest roi = image[100:300, 200:400] roi_mean = np.mean(roi) print(“Mean of the image is:”, roi_mean) Output Output of the above code is as follows − Mean of the image is: 98.556925
Mahotas – Histogram of Image A histogram of an image refers to a graphical representation that shows the distribution of pixel intensities within the image. It provides information about the frequency of occurrence of different intensity values in the image. The horizontal axis (X−aixs) of a histogram represents the range of possible intensity values in an image, while the vertical axis (Y−axis) represents the frequency or number of pixels that have a particular intensity value. Histogram of Image in Mahotas To compute the histogram of an image in Mahotas, we can use the fullhistogram() function provided by the library. This function will return an array representing the histogram values. A histogram array contains bins representing possible pixel values in an image. Each bin corresponds to a specific intensity level, indicating the frequency or count of pixels with that particular value. For example, in an 8−bit grayscale image, the histogram array has 256 bins representing intensity levels from 0 to 255. The mahotas.fullhistogram() function The mahotas.fullhistogram() function in Mahotas takes an image as input and returns an array representing the histogram. This function calculates the histogram by counting the number of pixels at each intensity level or bin. Syntax Following is the basic syntax of the fullhistogram() function in mahotas − mahotas.fullhistogram(image) Where, ”image” is the input image of an unsigned type. Mahotas can handle only unsigned integer arrays in this function Example In the following example, we are trying to display the histogram of a colored image using the fullhistogram() function − import mahotas as mh import numpy as np from pylab import imshow, show import matplotlib.pyplot as plt image = mh.imread(”sun.png”) hist = mh.fullhistogram(image) plt.hist(hist) plt.show() Output After executing the above code, we get the following output − Grayscale Image Histogram The grayscale image histogram in mahotas refers to a representation of the distribution of pixel intensities in a grayscale image. The grayscale images generally have pixel intensities ranging from 0 (black) to 255 (white). By default, Mahotas considers the full range of pixel intensities when calculating the histogram. This means that all intensities from 0 to 255 are included in the histogram calculation. By considering 256 bins and the full range of pixel intensities, Mahotas provides a comprehensive representation of the distribution of pixel intensities in the grayscale image. Example In here, we are trying to display the grayscale image histogram using mahotas − import mahotas as mh import numpy as np import matplotlib.pyplot as plt # Convert image array to uint8 type image = mh.imread(”sun.png”, as_grey=True).astype(np.uint8) hist = mh.fullhistogram(image) plt.hist(hist) plt.show() Output The output produced is as shown below − Blue Channel RGB Image Histogram The blue channel contains the information about the blue color component of each pixel. We will use the mahotas library in conjunction with numpy and matplotlib to extract the blue channel from an RGB image. We can extract the blue channel from the RGB image by selecting the third (index 2) channel using array slicing. This gives us a grayscale image representing the blue component intensities. Then, using numpy, we calculate the histogram of the blue channel. We flatten the blue channel array to create a 1D array, ensuring that the histogram is computed over all the pixels in the image. Finally, we use matplotlib to visualize the histogram. Example Now, we are trying to display the RGB image histogram of blue channel − import mahotas as mh import numpy as np import matplotlib.pyplot as plt # Loading RGB image image = mh.imread(”sea.bmp”) # Extracting the blue channel blue_channel = image[:, :, 2] # Calculating the histogram using numpy hist, bins = np.histogram(blue_channel.flatten(), bins=256, range=[0, 256]) # Plot histogram plt.bar(range(len(hist)), hist) plt.xlabel(”Pixel Value”) plt.ylabel(”Frequency”) plt.title(”Histogram of Blue Channel”) plt.show() Output Following is the output of the above code −
Mahotas – Labeled Image Functions Image labeling is a data labeling process that involves identifying specific features or objects in an image, adding meaningful information to select and classify those objects. It is commonly used to generate training data for machine learning models, particularly in the field of computer vision. Image labeling is used in a wide range of applications, including object detection, image classification, scene understanding, autonomous driving, medical imaging, and more. It allows machine learning algorithms to learn from labeled data and make accurate predictions or identifications based on the provided annotations. Functions for Labeling Images Following are the different functions used to label images in mahotas − S.No Function & Description 1 label() This function performs connected component labeling on a binary image, assigning unique labels to connected regions in one line. 2 labeled.label() This function assigns consecutive labels starting from 1 to different regions of an image. 3 labeled.filter_labeled() This function applies filters to the selected regions of an image while leaving other regions unchanged. Now, lets us see examples of some of these functions. The label() Function The mahotas.label() function is used to label the array, which is interpreted as a binary array. This is also known as connected component labeled, where the connectivity is defined by the structuring element. Example Following is the basic example to label an image using the label() function − import mahotas as mh import numpy as np from pylab import imshow, show # Create a binary image image = np.array([[0, 0, 1, 1, 0], [0, 1, 1, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 1], [0, 1, 1, 1, 1]], dtype=np.uint8) # Perform connected component labeling labeled_image, num_labels = mh.label(image) # Print the labeled image and number of labels print(“Labeled Image:”) print(labeled_image) print(“Number of labels:”, num_labels) imshow(labeled_image) show() Output After executing the above code, we get the following output − Labeled Image: [[0 0 1 1 0] [0 1 1 0 0] [0 0 0 2 2] [0 0 0 0 2] [0 2 2 2 2]] Number of labels: 2 The image obtained is as shown below − The labeled.label() Function The mahotas.labeled.label() function is used to update the label values to be in sequential order. The resulting sequential labels will be a new labeled image with labels assigned consecutively starting from 1. In this example, we start with a labeled image represented by a NumPy array where the labels are non−sequential. Example Following is the basic example to label an image using the labeled.label() function − import mahotas as mh import numpy as np from pylab import imshow, show # Create a labeled image with non-sequential labels labeled_image = np.array([[0, 0, 1, 1, 0], [0, 2, 2, 0, 0], [0, 0, 0, 3, 3], [0, 0, 0, 0, 4], [0, 5, 5, 5, 5]], dtype=np.uint8) # Update label values to be sequential sequential_labels, num_labels = mh.labeled.label(labeled_image) # Print the updated labeled image print(“Sequential Labels:”) print(sequential_labels) imshow(sequential_labels) show() Output The output obtained is as follows − Sequential Labels: [[0 0 1 1 0] [0 1 1 0 0] [0 0 0 2 2] [0 0 0 0 2] [0 2 2 2 2]] Following is the image produced − We have discussed these functions in detail in the remaining chapters of this section.
Mahotas – Regional Minima of Image Regional minima in an image refer to a point where the intensity value of pixels is the lowest. In an image, regions which form the regional minima are the darkest amongst all other regions. Regional minima are also known as global minima. Regional minima consider the entire image, while local minima only consider a local neighborhood, to find the pixels with lowest intensity. Regional minima are a subset of local minima, so all regional minima are a local minima but not all local minima are regional minima. An image can contain multiple regional minima but all regional minima will be of equal intensity. This happens because only the lowest intensity value is considered for regional minima. Regional Minima of Image in Mahotas In Mahotas, we can use the mahotas.regmin() function to find the regional maxima in an image. Regional minima are identified through intensity valleys within an image because they represent low intensity regions. The regional minima points are highlighted as white against black background, which represents normal points. The mahotas.regmin() function The mahotas.regmax() function gets regional minima from an input grayscale image. It outputs an image where the 1”s represent presence of regional minima points and 0”s represent normal points. The regmin() function uses a morphological reconstruction−based approach to find the regional minima. Here, the intensity value of each local minima region is compared with its neighboring local minima regions. If a neighbor is found to have a lower intensity, it becomes the new regional minima. This process continues until no region of lower intensity is left, indicating that the regional minima has been identified. Syntax Following is the basic syntax of the regmin() function in mahotas − mahotas.regmin(f, Bc={3×3 cross}, out={np.empty(f.shape, bool)}) Where, f − It is the input grayscale image. Bc (optional) − It is the structuring element used for connectivity. out(optional) − It is the output array of Boolean data type (defaults to new array of same size as f). Example In the following example, we are getting the regional minima of an image using mh.regmin() function. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image = mh.imread(”sea.bmp”) # Converting it to grayscale image = mh.colors.rgb2gray(image) # Getting the regional minima regional_minima = mh.regmin(image) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original image axes[0].imshow(image, cmap=”gray”) axes[0].set_title(”Original Image”) axes[0].set_axis_off() # Displaying the regional minima axes[1].imshow(regional_minima, cmap=”gray”) axes[1].set_title(”Regional Minima”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Following is the output of the above code − Using Custom Structuring Element We can also use a custom structuring element to get the regional minima from an image. In mahotas, while getting regional minima from an image we can use a custom structuring element to define how neighboring pixels are connected. We can use this to get a resultant image as per our need. It can by done by passing the structuring element to the Bc parameter in the regmin() function. For example, let”s consider the custom structuring element: [[1, 1, 1, 1, 0], [1, 1, 0, 1,1], [0, 1, 1, 1, 1], [1, 1, 1, 0, 1], [1, 0, 1, 1, 1]]. This structuring element implies horizontal and vertical connectivity. This means that only the pixels horizontally left or right and vertically above or below another pixel are considered its neighbors. Example Here, we are using a custom structuring element to get the regional minima of an image. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image = mh.imread(”tree.tiff”) # Converting it to grayscale image = mh.colors.rgb2gray(image) # Setting custom structuring element struct_element = np.array([[1, 1, 1, 1, 0],[1, 1, 0, 1, 1], [0, 1, 1, 1, 1],[1, 1, 1, 0, 1],[1, 0, 1, 1, 1]]) # Getting the regional minima regional_minima = mh.regmin(image, Bc=struct_element) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original image axes[0].imshow(image, cmap=”gray”) axes[0].set_title(”Original Image”) axes[0].set_axis_off() # Displaying the regional minima axes[1].imshow(regional_minima, cmap=”gray”) axes[1].set_title(”Regional Minima”) axes[1].set_axis_off() # Adjusting spacing between subplots mtplt.tight_layout() # Showing the figures mtplt.show() Output Output of the above code is as follows − Using a Specific Region of an Image We can also find the regional minima of a specific region of an image. A specific region of an image refers to a small part of a larger image. The specific region can be extracted by cropping the original image to remove unnecessary areas. In mahotas, we can use a portion of an image and get its regional minima. First, we get the specific area from the original image by providing dimensions of the x and y axis. Then we use the cropped image and get the regional minima using the regmin() function. For example, let’s say we specify [:900, :800] as the dimensions of x and y axis respectively. Then, the specific region will be in range of 0 to 900 pixels for x−axis and 0 to 800 pixels for y−axis. Example In the example mentioned below, we are getting the regional minima within a specific region of an image. import mahotas as mh import numpy as np import matplotlib.pyplot as mtplt # Loading the image image = mh.imread(”sun.png”) # Converting it to grayscale image = mh.colors.rgb2gray(image) # Using specific regions of the image image = image[:900, :800] # Getting the regional minima regional_minima = mh.regmin(image) # Creating a figure and axes for subplots fig, axes = mtplt.subplots(1, 2) # Displaying the original image axes[0].imshow(image, cmap=”gray”) axes[0].set_title(”Original Image”) axes[0].set_axis_off() # Displaying the regional minima axes[1].imshow(regional_minima, cmap=”gray”) axes[1].set_title(”Regional Minima”) axes[1].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 −
Mahotas – Dilating an Image Dilating an image in image processing refers to expanding the pixels of an image. The dilation process will add pixels around the edges of an image. This happens because the algorithm looks at each pixel in the image and checks its neighboring pixels. If any of the neighboring pixels are part of an object, it adds those pixels to the object”s boundary. Dilating an Image in Mahotas By dilating an image in Mahotas, we refer to adding the number of pixels to the boundaries of regions in an image. This operation is commonly used to enhance or modify the shapes and structures in an image. We can dilate an image in mahotas using the dilate() function. It is used to expand an element A by using structuring element B. A structuring element is a small matrix or shape that defines the neighborhood around each pixel. It is used to determine which pixels should be considered during the dilation process. The mahotas.dilate() function The mahotas.dilate() function takes the input image and the structuring element as arguments, and returns a new Numpy array. The value of the output pixel is determined as the maximum value of all the pixels in the neighborhood. If any neighboring pixels have a value of 1, the output pixel is set to 1. The dilate() function scans the image, pixel by pixel, and checks the neighborhood defined by the structuring element. If any neighboring pixels are part of an object, the dilation operation adds those pixels to the object”s boundary, making it larger. Syntax Following is the basic syntax of the dilate() function in mahotas − mahotas.dilate(A, Bc=None, out=None, output=None) where, A − It is the input image on which dilation will be performed. It can be a 2D or 3D NumPy array representing grayscale or binary image data. Bc (optional) − It is the structuring element used for dilation. Default is None. out (deprecated) / output (optional) − It specifies the output array to store the result. If not provided, a new array is created and returned as the output. Example Following is the basic example to dilate an image in mahotas using the dilate() function − import mahotas as mh import matplotlib.pyplot as plt import numpy as np image = mh.imread(”nature.jpeg”, as_grey=True).astype(np.uint8) # Performing dilation with a square kernel of size 3×3 dilated_image = mh.dilate(image, Bc=mh.disk(3)) # 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 dilated image axes[1].imshow(dilated_image, cmap=”gray”) axes[1].set_title(”Dilated 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 output as follows − Dilation with Varying Structuring Element Sizes We can also dilate an image using different structuring element sizes to enhance different aspects of the image. These elements are created with different sizes using the Mahotas disk() function. By choosing different radii or sizes for the structuring elements, we can achieve diverse effects. To begin, we perform the dilation using the largest structuring element. Then, we continue with additional dilations using smaller structuring elements. This approach allows us to modify the image in multiple ways, enhancing specific features and achieving the desired visual effects. Example In here, we are trying to dilate an image with varying structuring element sizes − import mahotas as mh import numpy as np from pylab import imshow, show image = mh.imread(”nature.jpeg”, as_grey=True).astype(np.uint8) # Performing dilation with the largest structuring element largest_se = mh.disk(8) dilated_image = mh.dilate(image, Bc=largest_se) # Performing additional dilations with smaller structuring elements smaller_se_1 = mh.disk(2) smaller_se_2 = mh.disk(5) dilated_image = mh.dilate(dilated_image, Bc=smaller_se_1) dilated_image = mh.dilate(dilated_image, Bc=smaller_se_2) # Displaying the dilated image imshow(dilated_image) show() Output The output obtained is as shown below − Dilation with a Circular-shaped Kernel To create a circular−shaped kernel, we can use the disk() function from Mahotas. By specifying the desired radius, this function generates a NumPy array representing the circular kernel. Once we have the image and circular kernel ready, we can proceed to perform dilation. This operation applies the circular kernel to each pixel of the image, expanding the white regions accordingly. In simpler terms, it enhances the bright areas in the image, making them larger. Example Now, we are dilating an image with a circular−shaped kernel − import mahotas as mh import numpy as np from pylab import imshow, show # Load image image = mh.imread(”sun.png”, as_grey=True).astype(np.uint8) # Circular kernel with radius 5 radius = 5 kernel = mh.disk(radius) dilated_image = mh.dilate(image, kernel) # Display the dilated image imshow(dilated_image) show() Output Following is the output of the above code −