How to rewrite a default line detection filter to work on any pixel width rather than one pixel wide objects

StackOverflow https://stackoverflow.com/questions/20975947

Question

I'm trying to detect horizontal lines using built in Matlab functions. Ive read that the filter: w = [-1 -1 -1;2 2 2;-1 -1 -1] when applied to an image will detect horizontal lines 1 pixel wide. As its response will be higher in the horizontal direction and in other cases its response will be zero.

My problem is that the lines I want to detect are more than 1 pixel wide. For example I want to detect the white lines in this image:

enter image description here

Now if I apply the above filter on this image using:

lines = imfilter(img, w);
imshow(lines)

It produces the following result:

enter image description here

It has worked as expected i.e it has detected horizontal lines 1 pixel thick and I guess that is why it has only detected the edges or boundaries of the lines. I want it to detect the full white line.

So how do I accomplish this? How do I only make the lines my region of interest and then work on them alone?

One way I think for this to work is that I somehow find out the pixel width of the white lines and then make a new kernel to work on those dimensions but how do I find the pixel width? how do I make a new kernel for said width?

or am I on a completely wrong path?

Was it helpful?

Solution

You can try to use the bwmorph function.

Example:

skel=bwmorph(bwmorph(YourImage,'erode', 6),'skel', Inf);
imshow(skel)

Result:

skeleton of lines

Edit If you are after the position and length of the lines, you can use regionprops, like this:

Framed = padarray(YourImage,[3 3],0,'both'); 

(This adds a black frame around the image to isolate the individual lines).

props=regionprops(Framed, 'Centroid', 'BoundingBox');
centroids={props.Centroid};
BBoxes={props.BoundingBox};

The positions of the lines are in the second element of each vector in centroids, the length of the lines can be deduced from the bounding boxes in BBoxes.

You can plot the results like this:

imshow(Framed)
hold on;
for k=1:length(centroids)
    line([1 BBoxes{k}(3)],[centroids{k}(2) centroids{k}(2)])
end
hold off;

Result:

Lines drawn on top of image

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top