Home > Back-end >  Line detection through drawn line
Line detection through drawn line

Time:02-26

I'm need to detect lines by drawing a line across the lines :)

The number of lines are unknown and differs from image to image. The direction of the lines can also differ. But for my example below I have six vertical lines.

I then want to draw a line across the six lines and my drawn line should detect the lines and also pinpoint the found line by adding a circle in a color. The goal is to receive an int with the lines found so I can continue doing calculations.

I have an Image encapsuled within a canvas.

<Canvas x:Name="Cnv" Width="640" Height="480"
            PreviewMouseUp="Image_MouseLeftButtonUp"
            PreviewMouseMove="MapImg_MouseMove">
        <Image x:Name="MapImg" Width="640" Height="480" Source="/images/test.png"/>
</Canvas>

I've managed to create the function so I can draw a line but I've searched quite a lot trying to find a solution for the detection. I successfully detected shapes with AForge framework but that was for a whole image from my understanding.

Very grateful for you help if possible.

EDIT: The line that should detect the lines are drawn and the other lines comes from an image / bitmap. Is there anything that might detect the lines by contrast (detecting the white)?

EDIT 2: Replace the picture with a more accurate image trying to explain.

enter image description here

CodePudding user response:

To provide a somewhat high level overview of such a solution.

To start of you need access to the pixel-Values, how this is done depends on the type of image you have. For a bitmapSource the recommended way seem to be to use CopyPixels.

Then you need to process each pixel along the line. The simplest way to do this would be to convert the line to a start position and a normalized direction and use this to sample along the line. Assuming pixel coordinates, something like:

for(var d = 0; d < myLine.Length ; d  ){
    var samplePos = myLine.StartPosition   myLine.Direction * d;
    ...
}

This sample position can then be used to extract the value for that pixel, I will assume that the image is grayscale, otherwise you might want to convert the color value. This very simple method might sample a pixel multiple times, but that should not be a problem. You can then use a threshold value to determine if a pixel is part of a line or not. Once you have found a pixel value large enough you would save that position, and the next time you find a low value you can average the positions and return it as the center point of a line. I.e. you would find the transitions between "black" and "white", and average pairs of two such transitions.

Something like this pseudo code:

int previousValue = 0;
Point startPos ;
for(var d = 0; d < myLine.Length ; d  ){
    var samplePos = myLine.StartPosition   myLine.Direction * d;
    var pixelValue = myImage[samplePos];
    if(pixelValue > myThreshold && previousValue < myThreshold){
        startPos = samplePos;
    }
    if( pixelValue < myThreshold && previousValue > myThreshold){
        yield return (startPos   samplePos)/2;
    }    
    previousValue = pixelValue;
}

This leaves out details like how to sample a pixel value at some specific position, and that you have suitable classes to work with pixel coordinates and directions etc. It also assumes the first pixel will always be black, if that is not the case you might need some special handling depending on what you want to do.

This should work well for cases like a binary image. More advanced algorithms might be faster and/or handle problematic cases better.

  • Related