5

I want to detect edges (with sub-pixel accuracy) in images like the one displayed:

enter image description here

The resolution would be around 600 X 1000.

I came across a comment by Mark Ransom here, which mentions about edge detection algorithms for vertical edges. I haven't come across any yet. Will it be useful in my case (since the edge isn't strictly a straight line)? It will always be a vertical edge though. I want it to be accurate till 1/100th of a pixel at least. I also want to have access to these sub-pixel co-ordinate values.

I have tried "Accurate subpixel edge location" by Agustin Trujillo-Pino. But this does not give me a continuous edge.

Are there any other algorithms available? I will be using MATLAB for this.

I have attached another similar image which the algorithm has to work on:

enter image description here

Any inputs will be appreciated.

Thank you.

Edit:

I was wondering if I could do this: Apply Canny / Sobel in MATLAB and get the edges of this image (note that it won't be a continuous line). Then, somehow interpolate this Sobel edges and get the co-ordinates in subpixel. Is it possible?

Community
  • 1
  • 1
Saania
  • 625
  • 1
  • 6
  • 26

2 Answers2

4

A simple approach would be to project your image vertically and fit the projected profile with an appropriate function.

Here is a try, with an atan shape:

% Load image
Img = double(imread('bQsu5.png'));

% Project
x = 1:size(Img,2);
y = mean(Img,1);

% Fit
f = fit(x', y', 'a+b*atan((x0-x)/w)', 'Startpoint', [150 50 10 150])

% Display
figure
hold on
plot(x, y);
plot(f);
legend('Projected profile', 'atan fit');

And the result:

enter image description here

I get x_0 = 149.6 pix for your first image.

However, I doubt you will be able to achieve a subpixel accuracy of 1/100th of pixel with those images, for several reasons:

  1. As you can see on the profile, your whites are saturated (grey levels at 255). As you cut the real atan profile, the fit is biased. If you have control over the experiments, I suggest you do it again again with a smaller exposure time for instance.

  2. There are not so many points on the transition, so there is not so many information on where the transition is. Typically, your resolution will be the square root of the width of the atan (or whatever shape you prefer). In you case this limits the subpixel resolution at 1/5th of a pixel, at best.

Finally, your edges are not stricly vertical, they are slightly titled. If you choose to use this projection method, to increase the accuracy you should look for a way to correct this tilt before projecting. This won't increase your accuracy by several orders of magnitude, though.

Best,

Ratbert
  • 5,463
  • 2
  • 18
  • 37
  • Thanks for the detailed explanation. But isn't there a simpler method? I mean my image has high contrast, so it should be simple to just trace the edge, right? And Sobel / Canny (MATLAB) gives me good results, except that it's not at subpixel level. Please see the last part of my edited question. – Saania Feb 24 '15 at 05:26
  • I don't really see why edge detection would be a simpler method than a fit. Anyway yes, indeed, you can perform edge detection, but as you noticed it's not giving you subpixel resolution. And unfortunately it won't because edge detection reduces the information. And again, if you are interested in precision, you should start by unsaturate your images because this shifts the real position of the edge. – Ratbert Feb 24 '15 at 07:16
  • Umm......the unsaturation part actually wouldn't be possible. The dark region is an object (one of the edges of a cylinder) in front of light (this light is the white saturated region). I just have to know at what pixel co-ordinates the edge of this object starts. No other information is required. – Saania Feb 24 '15 at 09:49
  • By unsaturate I mean play on the parameters of the acquisition itself, like the exposure time or the intensity of the light. This implies that you take a new set of data. With the present data, the saturation can shift the actual position of the edge of a few pixels, which is very bad with respect to the resolution you want. – Ratbert Feb 24 '15 at 10:12
  • Oh I understand your point. You are right, if the intensity is too high, the edge pixel shifts (as per my observations earlier). I have tried that. I have tried varying the back light's intensity and lens's exposure time. This is the optimum in image shown above. Btw, it works perfectly fine with pixel level accuracy (i.e., +/- 1 pixel), I get the desired edges on all sides well. Also, if I decrease the lighting it's more prone to noise. – Saania Feb 24 '15 at 12:03
2

There is a problem with your image. At pixel level, it seems like there are four interlaced subimages (odd and even rows and columns). Look at this zoomed area close to the edge.

In order to avoid this artifact, I just have taken the even rows and columns of your image, and compute subpixel edges. And finally, I look for the best fitting straight line, using the function clsq whose code is in this page:

%load image
url='https://i.stack.imgur.com/bQsu5.png';
image = imread(url);
imageEvenEven = image(1:2:end,1:2:end);
imshow(imageEvenEven, 'InitialMagnification', 'fit');

% subpixel detection
threshold = 25;
edges = subpixelEdges(imageEvenEven, threshold); 
visEdges(edges);

% compute fit line
A = [ones(size(edges.x)) edges.x edges.y];
[c n] = clsq(A,2);
y = [1,200];
x = -(n(2)*y+c) / n(1);
hold on;
plot(x,y,'g');   

When executing this code, you can see the green line that best aproximate all the edge points. The line is given by the equation c + n(1)*x + n(2)*y = 0

Take into account that this image has been scaled by 1/2 when taking only even rows and columns, so the right coordinates must be scaled.

Besides, you can try with the other tree subimages (imageEvenOdd, imageOddEven and imageOddOdd) and combine the four straigh lines to obtain the best solution.