Detect Edge in picture with low contrast

16 次查看(过去 30 天)
Hi, i need to detect a specific edge in a variaty of pictures which follow the same pattern.
i have tried using an averaging and then a sobel and laplacian filter but didnt get satisfying results. please use attached file as example. The edge that i am looking for is the dark one from the top more or less in the middle of the picture. Thanks for answers in advance
  1 个评论
Oliver Stilz
Oliver Stilz 2017-9-27
Added an example for a bad scenario. in this example the housing device is smaller, so there is not much "clean" space over the edge and pixel values can vary under the "edge-minimum". The size of the sleeve is always the same. i want to follow the idea of cedric wannaz and try detecting another edge that belongs to the sleeve to just use an offset from there.

请先登录,再进行评论。

采纳的回答

Cedric
Cedric 2017-9-27
编辑:Cedric 2017-9-28
Well, that picked my interest so I just spent a lunch break on it. Running the following using the process function attached (which uses FEX circfit):
process( 'WHL_20mm.PNG' ) ;
process( 'WHR_10mm_1.PNG' ) ;
we get
I wrote the code too quickly but you should still see what I am doing based on the few comments.
Just a few explanations as I have 5 minutes free:
  • For the inner rings (upper and lower), we use a convolution of the derivative along the y axis based on a square kernel. You can see this as a moving average in 2D that smooths things up.
  • We split the image in two blocks based on the position of the largest positive derivative (going from dark (low values) to bright (high values) means positive derivative), analyzing the sum per row of the smoothed out derivative (which is more stable than the central vertical line that I used in the previous version). This assumes that the sleeve(?) is always brighter than the rest. We could find another approach if it's not the case.
  • We then limit the analysis to the lower block that contains the inner rings.
  • We find the red points by taking locations with the largest positive derivative derivatives given a factor for thresholding (e.g. 0.9 * max). We optimize this factor to have a large enough number of points and a minimal variance of their y coordinates.
  • We find the blue points by taking locations with the largest negative derivative derivatives given a factor for thresholding (e.g. 0.9 * min). We optimize this factor to have a large enough number of points and a minimal variance of their y coordinates.
  • We fit circles to these sets of points and compute the mean of their centers coordinates.
  • For the outer ring we process the upper block now.
  • Given the low contrast, we try to spot regions where there is the most important variation (positive or negative) in the derivative along the y axis.
  • For this we perform a convolution of the absolute value of the derivative using a column vector kernel and we compute the max per column.
  • Then we look for a "good" frame (delineated by vertical boundaries) and for points in each column whose values are above a given threshold (e.g. 0.9 * max per column).
  • We find green points by optimizing three parameters which are the factor for thresholding and the frame boundaries, using an objective function that targets minimal variance of y coordinates while keeping enough points.
  • Finally, as this set of points is not well suited for fitting a circle (x0,y0,r), we use the mean x0 and y0 defined by the red and blue circles, and we find an r that minimizes some objective function.
Note that it looks cool, but I know nothing about image processing, so if the purpose is to learn correct image processing you should really investigate the other solutions.
  4 个评论
Oliver Stilz
Oliver Stilz 2017-9-28
Thanks again for that even more detailed solution. i will have to use some time to understand that code fully but just from what i see as your results: i will have to get the highest point of the green fittet circle (thats exactly what i am looking for - in more detail i only need the Y coordinate of that point). for the 2nd image, i think i wasnt clear enough there, but i need the edge thats below the green edge in the 10mm picture. i will try to adapt the code so i get that one. Huge Thank you, ill get in touch if i struggle to get to where i want....
Cedric
Cedric 2017-9-28
编辑:Cedric 2017-9-28
The best way to get the top of any circle is to use its fitted parameters (x0, y0, r). The top is at (x0, y0-r).
See my edited process.m, it adds an orange cross at the top of the green circle. It also outputs the three circles as structs with fields x0, y0, and r and a 4th parameter that holds handles to the most relevant graphic objects.
If you needed to add some text inside the image with the coordinates (in pixels) of the orange cross for example, you could do it as follows:
[~, ~, c, h] = process( 'WHR_10mm_1.PNG' ) ;
axes( h.imgAxes ) ; % Focus on image axes.
text( 10, 20, sprintf( 'x = %.2f, y = %.2f', c.x0, c.y0-c.r ), ...
'Color', [1, 0.4, 0], 'FontWeight', 'bold' ) ;

请先登录,再进行评论。

更多回答(2 个)

Image Analyst
Image Analyst 2017-9-22
Rather than do a crummy job fixing the image and then trying to find the edge in software, I suggest you improve your image capture environment, like with better lighting, perhaps polarizers, etc.
  3 个评论
Image Analyst
Image Analyst 2017-9-25
You'd need to tell me what this is - I have few ideas. Like is this a photo of a brake rotor from a car on a black background?
Have you tried broad illumination? Point source Illumination?
Try calling a machine vision illumination company like Advanced Illumination or SmartVisionLights and discuss your setup with an engineer.
Oliver Stilz
Oliver Stilz 2017-9-26
The bottom part of the picture is a so called sleeve that needs to be welded to a housing device seen in the upper part. the image is taken with a standard industrial camera and the current illumination is diffus/scattered using a broad illumination. i dont have the recources (and the space) to test a lot of different concepts.
The image is used to find the position for the welding devide to find the edge between the sleeve and the housing device that it should be welded to. since the positions of the parts vary, image processing was the idea to autmate the process.
and since this is part of my bachelor thesis calling a machine vision company is not really an option. Does this help or do you not see how I could get this to work?

请先登录,再进行评论。


Ramnarayan Krishnamurthy
The image would need pre-processing before passing it to one of the edge detectors. I would suggest trying to enhance the contrast by histogram equalization using the histeq function https://www.mathworks.com/help/images/ref/histeq.html
The region above the edge to the center seems to have a lot of noise as visible in the contrast stretched image. Consider using the gaussian filter before finally passing it to an edge detector.
I = imread('WHL_20mm.PNG');
I2 = histeq(imread('WHL_20mm.PNG'));
I3 = imgaussfilt(I2, 5);
I4 = edge(I3,'sobel');
imshow(I4)
Another slightly involved approach would be to use Flat-Field correction ( https://en.wikipedia.org/wiki/Flat-field_correction )
Iin = im2double(imread('WHL_20mm.PNG'));
shading = imgaussfilt(Iin,5);
I2 = Iin.*mean2(shading)./Iin;
I3 = Iin-I2;
I4 = stdfilt(I3,ones(21,21));
I5 = imgaussfilt(I4,15);
I6 = imclose(imdilate(edge(I5,'canny'),strel('disk',3)),strel('line',55,0));
% Using regionprops find the longest lines, remove the others, then
% grow/dilate as required.
figure
imagesc(I5)
figure
imshow(I6)
  3 个评论
Image Analyst
Image Analyst 2017-9-26
Can you attach a worst case example? Also, what do you want to know about the edge? Like how perfect and burr-free it is, or it's radius of curvature?
Oliver Stilz
Oliver Stilz 2017-9-27
i added a worse example to the post. the only thing i need to know about the edge is the position in the picture. detecting another edge (of the sleeve) and use an offset would be ok aswell.

请先登录,再进行评论。

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by