asys
asys

Reputation: 731

Autonomous seam detection in Images on matlab

I'm trying to detect seams in welding images for an autonomous welding process. enter image description here I want to find pixel positions of the detected line (the red line in the desired image) in the original image.

I used the following code and finally removed noise from the image to reach the result below.

clc,clear,clf;
im = imread('https://i.sstatic.net/UJcKA.png');
imshow(im);title('Original image'); pause(0.5);
sim = edge(im, 'sobel');
imshow(sim);title('after Sobel'); pause(0.5);
mask = im > 5;
se = strel('square', 5);
mask_s = imerode(mask, se);
mask(mask_s) = false;
mask = imdilate(mask, se);
sim(mask) = false;
imshow(sim);title('after mask');pause(0.5);
sim= medfilt2(sim);
imshow(sim);title('after noise removal')

enter image description here

Unfortunately there is nothing remaining in the image to find the seam perfectly.

Any help would be appreciated.

Download Original image.

Upvotes: 4

Views: 558

Answers (2)

Cecilia
Cecilia

Reputation: 4741

Shai gives a great answer, but I wanted to add a bit more context about why your noise filtering doesn't work.

Why median filtering doesn't work

Wikipedia suggests that median filtering removes noise while preserving edges, which is why you might have chosen to use it. However, in your case it will almost certainly not work, here's why:

Median filtering slides a window across the image. In each area, it replaces the central pixel with the median value from the surrounding window. medfilt2 uses a 3x3 window by default. Let's look at a 3x3 block near your line,

Location of window

A 3x3 block around [212 157] looks like this

 [0 0 0
  1 1 1
  0 0 0]

The median value is 0! So even though we're in the middle of a line segment, the pixel will be filtered out.

The alternative to median filtering

Shai's method for removing noise instead finds the largest connected group of pixels and ignores smaller groups of pixels. If you also wanted to remove these small groups from your image, Matlab provides a filter bwareaopen which removes small objects from binary images.

For example, if you replace your line

sim= medfilt2(sim);

with

sim= bwareaopen(sim, 4);

The result is much better

after noise removal

Alternative edge detectors

One last note, Shai uses a horizontal gradient filter to find horizontal edges in your image. It works great because your edge is horizontal. If you edge will not always be horizontal, you might want to use another edge detection method. In your original code, you use Sobel, but Matlab provides many options, all of which perform better if you tune their thresholds. As an example, in the following image, I've highlighted the pixels selected by your code (with bwareaopen modification) using four different edge detectors.

Detector comparison

Upvotes: 3

Shai
Shai

Reputation: 114926

You need to make your filter more robust to noise. This can be done by giving it a larger support:

filter = [ones(2,9);zeros(1,9);-ones(2,9)];
msk = imerode(im > 0, ones(11));  % only object pixels, discarding BG
fim =imfilter(im,filter); 
robust = bwmorph((fim>0.75).*msk,'skel',inf); % get only strong pixels

The robust mask looks like:

enter image description here

As you can see, the seam line is well detected, we just need to pick it as the largest connected component:

st = regionprops(bwlabel(robust,8), 'Area', 'PixelList');
[ma mxi] = max([st.Area]); % select the region with the largest area

Now we can fit a polygon (2nd degree) to the seem:

pp=polyfit(st(mxi).PixelList(:,1), st(mxi).PixelList(:,2), 2);

And here it is over the image:

imshow(im, 'border','tight');hold on;
xx=1:size(im,2);plot(xx,polyval(pp,xx)+2,'r');

enter image description here

Note the +2 Y offset due to filter width.


PS,
You might find this thread relevant.

Upvotes: 3

Related Questions