Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subpixel edge detection for almost vertical edges

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?

like image 702
Saania Avatar asked Feb 23 '15 12:02

Saania


People also ask

What is vertical edge detection?

Vertical edges can be detected by using a horizontal gradient operator followed by a threshold operation to detect the extreme values of the gradient. The gradient produces a doublet of extremes, positive-negative or negative-positive, depending on the direction of the transition.

What is subpixel edge detection?

The principle of sub-pixel edge detection is to subdivide the pixels near the edge to achieve accurate edge location. The commonly used methods are moment method, interpolation method, and fitting method. Among them, the interpolation method is relatively simple, but it is easily affected by noise.

Which is the best method among basic edge detection and why?

Canny edge detector is probably the most commonly used and most effective method, because it uses first a gaussian filter, it has more noise inmunity than other methods and you can stablish inferior and superior thresshold for edge detections in MATLAB.

Why it is difficult to detect edges in a noisy image?

Noise poses a significant challenge because it leads to variability in the local contrast along an edge. Moreover, at low signal to noise ratio (SNR), defined as the edge contrast divided by the noise level, it may even lead to local contrast reversals.


2 Answers

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,

like image 160
Ratbert Avatar answered Oct 12 '22 12:10

Ratbert


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='http://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.

like image 44
Agustín Trujillo Pino Avatar answered Oct 12 '22 12:10

Agustín Trujillo Pino