How To Make Line Detection Algorithm With C#

Line detection is a segmentation technique in image processing, with which we can extract thin lines with respect to each filter kernel.


Andraz Krzisnik
How To Make Line Detection Algorithm With C#

Line detection is a segmentation technique in image processing, with which we can extract lines from an image. In case you know point detection already, this post will serve as a next step in complexity for understanding segmentation.

Generally, segmentation is a process with which we detect abrupt local changes in intensities. However, we’re going to use different filter kernels for detecting lines as we did for point detection.

In the heart of these processes is convolution, because we’re using filter kernels. Therefore, I’m going to describe this process in a nutshell here as well.

So, filter kernels are basically small matrices, which hold some predefined values, depending on the purpose of the filter. We then take this filter and place it on top of the input image. Furthermore, we multiply pixel and kernel values that overlap and sum it all up.

This sum is the resulting pixel value, which we set on the resulting image at the position where the center of kernel is on input image. Therefore, to produce the whole resulting image, we need to slide the kernel across the input image pixel by pixel.

How does line detection work?

We already demonstrated a segmentation process, where we used Laplacian filter. Furthermore, it contains negative value, so we need to scale resulting values for display purposes. It is also an isotropic filter, which means that results it produces aren’t dependant on direction of the intensity changes.

However, with this process, we’re going to use multiple filters, each of which will detect edges – lines in different directions. As you can see from the following image of filters, preferred direction of each is weighted by positive and larger coefficients.

Line detection filters
Line detection filters

Resulting image is the combined results of convolutions with all filters. And as we did with point detection, we also need to use thresholding here as well. This way we can eliminate the noise from random variations around zero.

However, the shortcoming of this process is that it produces “zero valleys” for lines that are thicker than the filter. Basically, it extract only edges leaves the middle black. The reason for this is because when kernel coefficients sum to 0, it indicates an area of constant intensity.

Code

Because I already posted the code for convolution on point detection post, I’m not going to do it here again. In case you’re not familiar how it works in C#, I recommend you check it out. But you will also be able to download the demo project for this process.

public static Bitmap LineDetect(this Bitmap image)
     {
         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];
         byte[] result = new byte[bytes];

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

         int[][,] filters =
         {
             Filters.Horizontal,
             Filters.Diagonal1,
             Filters.Diagonal2,
             Filters.Vertical
         };

         for (int i = 0; i < filters.Length; i++)
         {
             //apply filter
             byte[] filtered = buffer.Convolute(image_data, filters[i]);

             //threshold
             for (int j = 0; j < bytes; j++)
             {
                 result[j] = (byte)(filtered[j] > 254 ? 255 : 0);
             }
         }

         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 in gaining you a better understanding of line detection in image segmentation processing.

As I mentioned above, you can download the demo project I made for this post and try it out yourself.

Show Comments (1)

Comments

  • David

    Hello!

    I’m working on line detection for engineering diagrams, and I was looking at your project to see how it worked. I noticed that it only would ever end up with horizontal lines within the result image– do you know how to fix that?

    Thank you, this post was a real lifesaver.

    • Article Author

Related Articles

Frequency Domain Filtering

How To Use Laplacian Filter – C# Guide

We use Laplacian filter to sharpen images. We are going to talk about the details how exactly this filter works. In essence, it’s one of the highpass filters, which...

Posted on by Andraz Krzisnik
C# Image Processing

How To Use Ideal Lowpass Filter With FFT – C# Guide

Ideal lowpass filter is a filter used to modify frequency values in the frequency domain, and for transforming an image into a frequency domain, we have to use Fourier transform....

Posted on by Andraz Krzisnik