Implementing ridge detection

好久不见. 提交于 2019-12-20 14:13:09

问题


I'm trying to write a ridge detection algorithm, and all of the sources I've found seem to conflate edge detection with ridge detection. Right now, I've implemented the Canny edge detection algorithm, but it's not what I want: for example, given a single line in the image, it will effectively translate it to a double line of edges (since it will record both sides of the line) - I just want it to read the one line.

The wikipedia article about ridge detection has a bunch of math, but this kind of this doesn't help me as a programmer (not that I'm averse to math, but it's not my field, and I don't understand how to translate their differential equations into code). Is there a good source for actually implementing this? Or, for that matter, is there a good open source implementation?

Edit: here's the simple example. We start with a simple line:

http://img24.imageshack.us/img24/8112/linez.th.png

and run the Canny Algorithm to get:

http://img12.imageshack.us/img12/1317/canny.th.png

(you can see that it's thicker here - if you click on the image, you'll see that it really is two adjacent lines with a blank in between)

Also, I'm writing in C++, but that shouldn't really matter. But I want to code the algorithm, not just write SomePackage::findRidges() and be done with it.


回答1:


Maybe you need to think in terms of cleaning up the line you already have, rather than a Canny-like edge detection. It feels like you should be able to do something with image morphology, in particular I'm thinking of the skeletonize and ultimate eroded points type operations. Used appropriately these should remove from your image any features which are not 'lines' - I believe they're implemented in Intel's OpenCV library.

You can recover a single line from your double line generated using the Canny filter using one dilate operation followed by 3 erodes (I tried it out in ImageJ) - this should also remove any edges.




回答2:


I was going to suggest cleaning up your lines like Ian said, but if you don't want to do that, you might also look into doing some variant of a hough transform.

http://en.wikipedia.org/wiki/Hough_transform

You should be able to get the actual equation for the line from this, so you can make it as thin or as thick as you like. The only tricky part is figuring out where the line ends.

Here's the code I wrote for a hough transform a few years ago, written in MATLAB. I'm not sure how well it works anymore, but it should give you a general idea. It will find all the lines (not segments) in an image

im = imread('cube.tif');
[bin1,bin2,bin3] = canny(im);

%% define constants
binary = bin1;
distStep = 10; % in pixels
angStep = 6; % in degrees
thresh = 50;

%% vote
maxDist = sqrt((size(binary,1))^2+(size(binary,2))^2);
angLoop = 0:angStep*pi/180:pi;
origin = size(binary)/2;
accum = zeros(ceil(maxDist/distStep)+1,ceil(360/angStep)+1);

for y=1:size(binary,2)
    for x=1:size(binary,1)
    if binary(x,y)
        for t = angLoop
        dx = x-origin(1);
        dy = y-origin(2);
        r = x*cos(t)+y*sin(t);
        if r < 0
            r = -r;
            t = t + pi;
        end
        ri = round(r/distStep)+1;
        ti = round(t*180/pi/angStep)+1;
        accum(ri,ti) = accum(ri,ti)+1;
        end
    end
    end
end
imagesc(accum);

%% find local maxima in accumulator
accumThresh = accum - thresh;
accumThresh(logical(accumThresh<0)) = 0;
accumMax = imregionalmax(accumThresh);
imagesc(accumMax);

%% calculate radius & angle of lines
dist = [];
ang = [];
for t=1:size(accumMax,2)
    for r=1:size(accumMax,1)
    if accumMax(r,t)
        ang = [ang;(t-1)*angStep/180*pi];
        dist = [dist;(r-1)*distStep];
    end
    end
end
scatter(ang,dist);



回答3:


If anyone is still interested in this, here is an implementation of the ridges/valleys algorithm: C++ source code. Look for a function called get_ridges_or_valleys(). This implementation is a 3D version of the algorithm proposed by Linderhed (2009). See page 8 of the paper for the ridges/valleys algorithm.



来源:https://stackoverflow.com/questions/585160/implementing-ridge-detection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!