Advice on vertical edge detection on grayscale image with very weak contrast
10 views (last 30 days)
Show older comments
Petter Stefansson
on 20 Mar 2016
Commented: Image Analyst
on 20 Mar 2016
I’ve taken a large quantity of X-ray images of wooden samples and in order perform the analysis I’m trying to do I need to extract the individual yearly growth cycles from the wood by finding the column index of each latewood line (dark lines that can be seen in the attached image WoodXray.jpg) of each row.
So far I’ve tried applying a strong Gaussian blur to the image to remove noise and looping through the rows of the image one by one and identifying the points with the lowest values, which corresponds to a darker color in the image (see rowbyrowminima.jpg for an example of what I get from that). By viewing all the resulting rows from that as a vector I then get a pretty good estimation of where the boundary between early-wood/late-wood should be (see attached EdgeDetected.jpg to see what I get). I then get exactly what I want, the problem is that the outcome is rarely as good as on the image, very often the whole boundary detection collapses and the lines are fragmented all over the image. The method I am using is in other words very unrobust. I’ve also tried a bit with Sobel edge detection for vertical lines but I didn’t seem to have much more luck there.
Does anyone who work a lot with edge detection have any suggestions for how I could do this in a more robust or easier way? I suspect that it would be much more robust to have a detection method that already knows its looking for something that more or less is shaped like a line, right now I’m only detecting row by row and the next coming row does not consider at all the previous one.
Any advice?
I’ve also attached one of the images in matlab format if you would like to look at it yourself (XrayWoodenSample.mat).
Thanks
0 Comments
Accepted Answer
Image Analyst
on 20 Mar 2016
The results you showed looked pretty good so I don't see what's wrong. Please attach an image where the results are not so ideal.
I'm not sure what "the outcome is rarely as good as on the image" means. Please explain.
If you just don't like the image being so blurred, then display the lines over the original image, not the blurred image.
If you don't want huge blurring, make sure you're just blurring vertically and not horizontally. You could also take a look at some other denoising routines that are better, like medfilt2(), non-local means, k-SVD, UINTA, K-LLD, and BM3D (which is often regarded as the best).
To accentuate and find the ridge/valley lines, you could try anisotropic diffusion (my demo attached), or a Frangi or Hessian filter (see the File Exchange for submissions).
2 Comments
Image Analyst
on 20 Mar 2016
How many do you have? What's wrong with manually specifying all the lines with improfile()?
Do you know if all the lines are vertical? If so, just get the mean horizontal profile and use that to scan for minima
horizontalProfile = mean(grayImage, 1);
If that's the best line collection you can get (which I don't think it is), then you can do "edge linking". Get the coordinates of the lines and identify which lines are in the same "column" by using kmeans() (In the Statistics and Machine Learning Toolbox) to identify groupings of the "x" values. Then for all lines in a certain vertical band (identified from your x cluster means), use an edge linking routine to join the lines into a single big long line.
Attach the original image for not so good.jpg in case I ever get time to try anything.
More Answers (0)
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!