Navigation

Related Articles

Back to Latest Articles

How To Make Extraction Of Connected Components In C#

Extraction of connected components in image processing is a morphological process, where we isolate object to a separate image.


Andraz Krzisnik
How To Make Extraction Of Connected...

Extraction of connected components is a morphological operation in image processing. As its name might suggests, we use it to extract a particular object from an image. It is also one of the most important processes to many automated image analysis applications.

We’ll work with binary images in this guide, with which we’ll gain better understanding of morphological operations in general. However, this doesn’t mean we can’t perform these operations on images with more intensity information, like grayscale or color images.

We can view binary images as a two dimensional array of image data. Therefore if we wanted to work with grayscale or color images, we would have 3 or more dimensional arrays of image data. However there is a downside to piling on more image data to process, which is longer computational time.

How does extraction of connected components in image processing work?

It actually works very similar to hole filling process. However, the difference between the two is that we seek foreground pixels here while hole filling seeks background pixels.

If you’re not familiar what I mean by foreground and background pixels, it’s just another way of calling white and black pixels. This only applies for binary images, since they only have these two intensities.

Morphological operations are non-linear operations, where we separate pixels into sets. So when we apply a certain operation, it works for the entire pixel set in the image. In other words, if we want to apply an operation on a specific object, like we’re want to do with this extraction, we need to isolate it on a separate image.

Furthermore, extraction of connected components is based on dilation process. All that we need is the location of one pixel, which is a part of the object we’re trying to extract. We then iterate dilation from that pixel and limit it to the borders of the object.

extraction of connected components dilation iteration process
Extraction of connected components dilation iteration

This process stops when we have all the connected pixels of an object on a separate image.

Code

public static Bitmap Extract(this Bitmap image, int start_x, int start_y)
     {
         int w = image.Width;
         int h = image.Height;

         BitmapData image_data = image.LockBits(
             new Rectangle(0, 0, w, h),
             ImageLockMode.ReadOnly,
             PixelFormat.Format24bppRgb);

         int bytes = image_data.Stride * image_data.Height;
         byte[] buffer = new byte[bytes];

         Marshal.Copy(image_data.Scan0, buffer, 0, bytes);
         image.UnlockBits(image_data);

         byte[] temp = new byte[bytes];
         byte[] result = new byte[bytes];
         //seed point
         for (int c = 0; c < 3; c++)
         {
             temp[start_x * 3 + start_y * image_data.Stride + c] = 255;
         }

         while (true)
         {
             //iterate across the image with structuring element
             for (int i = 1; i < w - 1; i++)
             {
                 for (int j = 1; j < h - 1; j++)
                 {
                     //position of the structuring element center
                     int position = i * 3 + j * image_data.Stride;
                     //set up structuring element
                     for (int k = -1; k < 2; k++)
                     {
                         for (int l = -1; l < 2; l++)
                         {
                             //position of pixel overlaped by structuring element
                             int se_pos = position + k * 3 + l * image_data.Stride;
                             if (Structuring_Element.Vals[k + 1, l + 1] == 1 && buffer[se_pos] > 0)
                             {
                                 for (int c = 0; c < 3; c++)
                                 {
                                     result[se_pos + c] = Math.Max(temp[position], result[se_pos]);
                                 }
                             }
                         }
                     }
                 }
             }

             int difference = 0;
             for (int i = 0; i < bytes; i++)
             {
                 if (result[i] != temp[i])
                 {
                     temp[i] = result[i];
                     difference++;
                 }
             }

             if (difference == 0)
             {
                 break;
             }
         }

         Bitmap res_img = new Bitmap(w, h);
         BitmapData res_data = res_img.LockBits(
             new Rectangle(0, 0, w, h),
             ImageLockMode.WriteOnly,
             PixelFormat.Format24bppRgb);
         Marshal.Copy(result, 0, res_data.Scan0, bytes);
         res_img.UnlockBits(res_data);
         return res_img;
     }

Conclusion

I hope this tutorial was helpful making things about extracting objects from image understandable.

You can also download the demo project and try it out yourself. But beware, it takes a little time to process the image. The bigger the input image and larger the object, more time it will take.

Related Articles

Edge Detection

How To Make Marr Hildreth Edge Detection Algorithm In C#

Marr hildreth edge detection process is one of the earliest sophisticated edge detection based segmentation operations in image processing.

Posted on by Andraz Krzisnik
Morphological Processes

How To Make Image Erosion Work With C#

Image erosion is one of the fundamental morphological operations and this tutorial explains how it works and demonstrates it in C#.

Posted on by Andraz Krzisnik