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.

enter image description here

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

enter image description here

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).


  • $\begingroup$ Automated ridge extraction is currently in development at ssqueezepy; unsure if suits your purpose, but worth a look $\endgroup$ Commented Feb 5, 2021 at 15:39
  • $\begingroup$ 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? $\endgroup$
    – R Thompson
    Commented Feb 5, 2021 at 15:40
  • $\begingroup$ 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) $\endgroup$ Commented Feb 5, 2021 at 15:54
  • $\begingroup$ 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. $\endgroup$ Commented Feb 5, 2021 at 16:11

1 Answer 1


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).

'Cropped' example:

enter image description here


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.