# Extracting ridges in automatically in image

I am trying to extract ridges from an image, calculated using the eigenvalues of the Hessian matrix (see answer in Best way of segmenting veins in leaves?). In this image I have zeroed out the negative eigenvalues.

Visually I can see the regions I want, but how would I be able to sensibly extract them automatically? If I LogNorm() the colorbar it is not so clear

Initially I thought if the noise in the image can be estimated, I can mask the image accordingly, but the only estimate to the noise I can find is its standard deviation (assuming Gaussian noise) in skimage.restoration.estimate_sigma and not its mean.

Masking via threshold is also possible, but do the magnitudes of the eigenvalues have physical meaning?

I'm new to image processing so any help would be greatly appreciated. I have attached the data for my image also (https://drive.google.com/file/d/1Wdvqtv4rUmLtSNiq-p0M5BwSKxUoW76T/view?usp=sharing).

Thanks!

• Automated ridge extraction is currently in development at ssqueezepy; unsure if suits your purpose, but worth a look Feb 5 at 15:39
• Funny you mention that as I am actually trying to automatically extract ridges from my ssqueezepy coefficients! I somehow missed the frequency_ridge_extraction function in the documentation so thank you for pointing me to it. I'd love to be able to ask you some questions if you wouldn't mind? Feb 5 at 15:40
• Wonderful. Unsure when it'll be ready, but seems to work well enough as-is; I've zipped a stable version you could use that includes GM wavelets, here. If you find shortcomings, I'd appreciate any feedback. -- And sure, but best to ask on the PR thread than here, so its author can have a look (who's more knowledgeable than I on the algorithm) Feb 5 at 15:54
• Forgot to note, dev_ridge.py is an example script to show how extract_ridges work, rather than part of ssqueezepy. Also includes a bunch of test signals. Feb 5 at 16:11

This should be doable with ssqueezepy's extract_ridges; try varying penalty and bw (see their docstrings). As last resort, feeding a cropped image that excludes region without ridges may work better, as the algorithm assumes the ridge spans the entire frame. You can automate this by finding indices at which column energies fall below a set threshold, e.g. np.where(np.sum(np.abs(stft_transform)**2, axis=0) < 0.1).