Image segmentation
Description
In digital image processing and computer vision, image segmentation is the process of partitioning a digital image into multiple segments. The goal of segmentation is to simplify and/or change the representation of an image into something that is more meaningful and easier to analyze
What is Image Segmentation?
Let’s understand image segmentation using a simple example. Consider the below image:
There’s only one object here – a dog. We can build a straightforward cat-dog classifier model and predict that there’s a dog in the given image. But what if we have both a cat and a dog in a single image?
We can train a multi-label classifier, in that instance. Now, there’s another caveat – we won’t know the location of either animal/object in the image.
That’s where image localization comes into the picture (no pun intended!). It helps us to identify the location of a single object in the given image. In case we have multiple objects present, we then rely on the concept of object detection (OD). We can predict the location along with the class for each object using OD.
Before detecting the objects and even before classifying the image, we need to understand what the image consists of. Enter – Image Segmentation.
So how does image segmentation work?
We can divide or partition the image into various parts called segments. It’s not a great idea to process the entire image at the same time as there will be regions in the image which do not contain any information. By dividing the image into segments, we can make use of the important segments for processing the image. That, in a nutshell, is how image segmentation works.
An image is a collection or set of different pixels. We group together the pixels that have similar attributes using image segmentation. Take a moment to go through the below visual (it’ll give you a practical idea of image segmentation):
Source : cs231n.stanford.edu
Object detection builds a bounding box corresponding to each class in the image. But it tells us nothing about the shape of the object. We only get the set of bounding box coordinates. We want to get more information – this is too vague for our purposes.
Image segmentation creates a pixel-wise mask for each object in the image. This technique gives us a far more granular understanding of the object(s) in the image.
Why do we need to go this deep? Can’t all image processing tasks be solved using simple bounding box coordinates? Let’s take a real-world example to answer this pertinent question.
Why do we need Image Segmentation?
Cancer has long been a deadly illness. Even in today’s age of technological advancements, cancer can be fatal if we don’t identify it at an early stage. Detecting cancerous cell(s) as quickly as possible can potentially save millions of lives.
The shape of the cancerous cells plays a vital role in determining the severity of the cancer. You might have put the pieces together – object detection will not be very useful here. We will only generate bounding boxes which will not help us in identifying the shape of the cells.
Image Segmentation techniques make a MASSIVE impact here. They help us approach this problem in a more granular manner and get more meaningful results. A win-win for everyone in the healthcare industry.
Source: Wikipedia
Here, we can clearly see the shapes of all the cancerous cells. There are many other applications where Image segmentation is transforming industries:
- Traffic Control Systems
- Self Driving Cars
- Locating objects in satellite images
There are even more applications where Image Segmentation is very useful. Feel free to share them with me in the comments section below this article – let’s see if we can build something together.
The Different Types of Image Segmentation
We can broadly divide image segmentation techniques into two types. Consider the below images:
Can you identify the difference between these two? Both the images are using image segmentation to identify and locate the people present.
- In image 1, every pixel belongs to a particular class (either background or person). Also, all the pixels belonging to a particular class are represented by the same color (background as black and person as pink). This is an example of semantic segmentation
- Image 2 has also assigned a particular class to each pixel of the image. However, different objects of the same class have different colors (Person 1 as red, Person 2 as green, background as black, etc.). This is an example of instance segmentation
Let me quickly summarize what we’ve learned. If there are 5 people in an image, semantic segmentation will focus on classifying all the people as a single instance. Instance segmentation, on the other hand. will identify each of these people individually.
So far, we have delved into the theoretical concepts of image processing and segmentation. Let’s mix things up a bit – we’ll combine learning concepts with implementing them in Python. I strongly believe that’s the best way to learn and remember any topic.
Region-based Segmentation
One simple way to segment different objects could be to use their pixel values. An important point to note – the pixel values will be different for the objects and the image’s background if there’s a sharp contrast between them.
In this case, we can set a threshold value. The pixel values falling below or above that threshold can be classified accordingly (as an object or the background). This technique is known as Threshold Segmentation.
If we want to divide the image into two regions (object and background), we define a single threshold value. This is known as the global threshold.
If we have multiple objects along with the background, we must define multiple thresholds. These thresholds are collectively known as the local threshold.
Let’s implement what we’ve learned in this section. Download this image and run the below code. It will give you a better understanding of how thresholding works (you can use any image of your choice if you feel like experimenting!).
First, we’ll import the required libraries.
from skimage.color import rgb2gray | |
import numpy as np | |
import cv2 | |
import matplotlib.pyplot as plt | |
%matplotlib inline | |
from scipy import ndimage |
Let’s read the downloaded image and plot it:
image = plt.imread(‘1.jpeg’) | |
image.shape | |
plt.imshow(image) |
It is a three-channel image (RGB). We need to convert it into grayscale so that we only have a single channel. Doing this will also help us get a better understanding of how the algorithm works.
gray = rgb2gray(image) | |
plt.imshow(gray, cmap=’gray’) |
Now, we want to apply a certain threshold to this image. This threshold should separate the image into two parts – the foreground and the background. Before we do that, let’s quickly check the shape of this image:
gray.shape
(192, 263)
The height and width of the image is 192 and 263 respectively. We will take the mean of the pixel values and use that as a threshold. If the pixel value is more than our threshold, we can say that it belongs to an object. If the pixel value is less than the threshold, it will be treated as the background. Let’s code this:
gray_r = gray.reshape(gray.shape[0]*gray.shape[1]) | |
for i in range(gray_r.shape[0]): | |
if gray_r[i] > gray_r.mean(): | |
gray_r[i] = 1 | |
else: | |
gray_r[i] = 0 | |
gray = gray_r.reshape(gray.shape[0],gray.shape[1]) | |
plt.imshow(gray, cmap=’gray’) |
Nice! The darker region (black) represents the background and the brighter (white) region is the foreground. We can define multiple thresholds as well to detect multiple objects:
gray = rgb2gray(image) | |
gray_r = gray.reshape(gray.shape[0]*gray.shape[1]) | |
for i in range(gray_r.shape[0]): | |
if gray_r[i] > gray_r.mean(): | |
gray_r[i] = 3 | |
elif gray_r[i] > 0.5: | |
gray_r[i] = 2 | |
elif gray_r[i] > 0.25: | |
gray_r[i] = 1 | |
else: | |
gray_r[i] = 0 | |
gray = gray_r.reshape(gray.shape[0],gray.shape[1]) | |
plt.imshow(gray, cmap=’gray’) |
There are four different segments in the above image. You can set different threshold values and check how the segments are made. Some of the advantages of this method are:
- Calculations are simpler
- Fast operation speed
- When the object and background have high contrast, this method performs really well
But there are some limitations to this approach. When we don’t have significant grayscale difference, or there is an overlap of the grayscale pixel values, it becomes very difficult to get accurate segments.
Edge Detection Segmentation
What divides two objects in an image? There is always an edge between two adjacent regions with different grayscale values (pixel values). The edges can be considered as the discontinuous local features of an image.
We can make use of this discontinuity to detect edges and hence define a boundary of the object. This helps us in detecting the shapes of multiple objects present in a given image. Now the question is how can we detect these edges? if you need to learn about these concepts.
The below visual will help you understand how a filter colvolves over an image :
Here’s the step-by-step process of how this works:
- Take the weight matrix
- Put it on top of the image
- Perform element-wise multiplication and get the output
- Move the weight matrix as per the stride chosen
- Convolve until all the pixels of the input are used
The values of the weight matrix define the output of the convolution. My advice – it helps to extract features from the input. Researchers have found that choosing some specific values for these weight matrices helps us to detect horizontal or vertical edges (or even the combination of horizontal and vertical edges).
One such weight matrix is the sobel operator. It is typically used to detect edges. The sobel operator has two weight matrices – one for detecting horizontal edges and the other for detecting vertical edges. Let me show how these operators look and we will then implement them in Python.
Sobel filter (horizontal) =
1 | 2 | 1 |
0 | 0 | 0 |
-1 | -2 | -1 |
Sobel filter (vertical) =
-1 | 0 | 1 |
-2 | 0 | 2 |
-1 | 0 | 1 |
Edge detection works by convolving these filters over the given image. Let’s visualize them on
image = plt.imread(‘index.png’) | |
plt.imshow(image) |
It should be fairly simple for us to understand how the edges are detected in this image. Let’s convert it into grayscale and define the sobel filter (both horizontal and vertical) that will be convolved over this image:
# converting to grayscale | |
gray = rgb2gray(image) | |
# defining the sobel filters | |
sobel_horizontal = np.array([np.array([1, 2, 1]), np.array([0, 0, 0]), np.array([-1, -2, -1])]) | |
print(sobel_horizontal, ‘is a kernel for detecting horizontal edges’) | |
sobel_vertical = np.array([np.array([-1, 0, 1]), np.array([-2, 0, 2]), np.array([-1, 0, 1])]) | |
print(sobel_vertical, ‘is a kernel for detecting vertical edges’) |
Now, convolve this filter over the image using the convolve function of the ndimage package from scipy.
out_h = ndimage.convolve(gray, sobel_horizontal, mode=’reflect’) | |
out_v = ndimage.convolve(gray, sobel_vertical, mode=’reflect’) | |
# here mode determines how the input array is extended when the filter overlaps a border. |
Let’s plot these results:
plt.imshow(out_h, cmap=’gray’) |
plt.imshow(out_v, cmap=’gray’) |
Here, we are able to identify the horizontal as well as the vertical edges. There is one more type of filter that can detect both horizontal and vertical edges at the same time. This is called the laplace operator:
1 | 1 | 1 |
1 | -8 | 1 |
1 | 1 | 1 |
Let’s define this filter in Python and convolve it on the same image:
kernel_laplace = np.array([np.array([1, 1, 1]), np.array([1, -8, 1]), np.array([1, 1, 1])]) | |
print(kernel_laplace, ‘is a laplacian kernel’) |
Next, convolve the filter and print the output:
out_l = ndimage.convolve(gray, kernel_laplace, mode=’reflect’) | |
plt.imshow(out_l, cmap=’gray’) |
Here, we can see that our method has detected both horizontal as well as vertical edges. I encourage you to try it on different images and share your results with me. Remember, the best way to learn is by practicing!
Image Segmentation based on Clustering
This idea might have come to you while reading about image segmentation. Can’t we use clustering techniques to divide images into segments? We certainly can!
In this section, we’ll get an an intuition of what clustering is (it’s always good to revise certain concepts!) and how we can use of it to segment images.
Clustering is the task of dividing the population (data points) into a number of groups, such that data points in the same groups are more similar to other data points in that same group than those in other groups. These groups are known as clusters.
One of the most commonly used clustering algorithms is k-means. Here, the k represents the number of clusters (not to be confused with k-nearest neighbor). Let’s understand how k-means works:
- First, randomly select k initial clusters
- Randomly assign each data point to any one of the k clusters
- Calculate the centers of these clusters
- Calculate the distance of all the points from the center of each cluster
- Depending on this distance, the points are reassigned to the nearest cluster
- Calculate the center of the newly formed clusters
- Finally, repeat steps (4), (5) and (6) until either the center of the clusters does not change or we reach the set number of iterations
The key advantage of using k-means algorithm is that it is simple and easy to understand. We are assigning the points to the clusters which are closest to them.
Let’s put our learning to the test and check how well k-means segments the objects in an image. We will be using this image, so download it, read it and and check its dimensions:
pic = plt.imread(‘1.jpeg’)/255 # dividing by 255 to bring the pixel values between 0 and 1 | |
print(pic.shape) | |
plt.imshow(pic) |
It’s a 3-dimensional image of shape (192, 263, 3). For clustering the image using k-means, we first need to convert it into a 2-dimensional array whose shape will be (length*width, channels). In our example, this will be (192*263, 3).
pic_n = pic.reshape(pic.shape[0]*pic.shape[1], pic.shape[2]) | |
pic_n.shape |
(50496, 3)
We can see that the image has been converted to a 2-dimensional array. Next, fit the k-means algorithm on this reshaped array and obtain the clusters. The cluster_centers_ function of k-means will return the cluster centers and labels_ function will give us the label for each pixel (it will tell us which pixel of the image belongs to which cluster).
from sklearn.cluster import KMeans | |
kmeans = KMeans(n_clusters=5, random_state=0).fit(pic_n) | |
pic2show = kmeans.cluster_centers_[kmeans.labels_] |
I have chosen 5 clusters for this article but you can play around with this number and check the results. Now, let’s bring back the clusters to their original shape, i.e. 3-dimensional image, and plot the results.
cluster_pic = pic2show.reshape(pic.shape[0], pic.shape[1], pic.shape[2]) | |
plt.imshow(cluster_pic) |
Amazing, isn’t it? We are able to segment the image pretty well using just 5 clusters. I’m sure you’ll be able to improve the segmentation by increasing the number of clusters.
k-means works really well when we have a small dataset. It can segment the objects in the image and give impressive results. But the algorithm hits a roadblock when applied on a large dataset (more number of images).
It looks at all the samples at every iteration, so the time taken is too high. Hence, it’s also too expensive to implement. And since k-means is a distance-based algorithm, it is only applicable to convex datasets and is not suitable for clustering non-convex clusters.
Finally, let’s look at a simple, flexible and general approach for image segmentation.
Mask R-CNN
Data scientists and researchers at Facebook AI Research (FAIR) pioneered a deep learning architecture, called Mask R-CNN, that can create a pixel-wise mask for each object in an image. This is a really cool concept so follow along closely!
Mask R-CNN is an extension of the popular Faster R-CNN object detection architecture. Mask R-CNN adds a branch to the already existing Faster R-CNN outputs. The Faster R-CNN method generates two things for each object in the image:
- Its class
- The bounding box coordinates
Mask R-CNN adds a third branch to this which outputs the object mask as well. Take a look at the below image to get an intuition of how Mask R-CNN works on the inside:
Source: arxiv.org
- We take an image as input and pass it to the ConvNet, which returns the feature map for that image
- Region proposal network (RPN) is applied on these feature maps. This returns the object proposals along with their objectness score
- A RoI pooling layer is applied on these proposals to bring down all the proposals to the same size
- Finally, the proposals are passed to a fully connected layer to classify and output the bounding boxes for objects. It also returns the mask for each proposal
Mask R-CNN is the current state-of-the-art for image segmentation and runs at 5 fps.
WHAT IS DEEP LEARNING?
Deep learning is part of a broader family of machine learning methods based on artificial neural networks with representation learning. Learning can be supervised, semi-supervised or unsupervised.
Deep Learning is a subfield of machine learning concerned with algorithms inspired by the structure and function of the brain called artificial neural networks.
Deep learning is an artificial intelligence (AI) function that imitates the workings of the human brain in processing data and creating patterns for use in decision making. … Also known as deep neural learning or deep neural network.
Deep learning is a subset of machine learning and artificial intelligence that has networks capable of learning unsupervised from data that is unstructured or unlabeled. Also known as deep neural learning or deep neural network.
KEY TAKEAWAYS
- Deep learning is an AI function that mimics the workings of the human brain in processing data for use in detecting objects, recognizing speech, translating languages, and making decisions.
- Deep learning AI is able to learn without human supervision, drawing from data that is both unstructured and unlabeled.
- Deep learning, a form of machine learning, can be used to help detect fraud or money laundering, among other functions.
How Deep Learning Works
Deep learning has evolved hand-in-hand with the digital era, which has brought about an explosion of data in all forms and from every region of the world. This data, known simply as big data is drawn from sources like social media, internet search engines, e-commerce platforms, and online cinemas, among others. This enormous amount of data is readily accessible and can be shared through fintech applications like cloud computing.
However, the data, which normally is unstructured, is so vast that it could take decades for humans to comprehend it and extract relevant information. Companies realize the incredible potential that can result from unraveling this wealth of information and are increasingly adapting to AI systems for automated support.
WHAT IS THE RELEVANCE OF IMAGE SEGMENTATION TO DEEP LEARNING?
What is image segmentation in deep learning?
Image segmentation results in more granular information about the shape of an image and thus an extension of the concept of Object Detection. We segment i.e. divide the images into regions of different colors which helps in distinguishing an object from the other at a finer level.
What is the purpose of image segmentation?
The goal of segmentation is to simplify and/or change the representation of an image into something that is more meaningful and easier to analyze. Image segmentation is typically used to locate objects and boundaries (lines, curves, etc.) in images.
Drop your comment