Lowering rope on steeple until saddle point connecting to adjacent peak

Tags: #<Tag:0x00007fa2ffd0b458> #<Tag:0x00007fa2ffd0b318> #<Tag:0x00007fa2ffd0b1d8>


In an image where grey values plotted as height resemble a mountain landscape, I find the summit. In an attempt to isolate the peak, from that location, I want to lower a horizontal (=same grey value) loop of rope around the peak, until it lowering is prevented by a saddlepoint between the summit and a nearby lower peak. Then I can cut out the peak for further analysis.

Just Enlarging… the ROI by 1 wouldn’t work because the steeple is not a perfect vertical cone and thus the loop (ROI) wouldn’t remain horizontal. Not every grey value (height) is available on the slope around the summit, so the solution must be robust enough to allow skipping grey values.
Also the peak is not perfectly round, so convex parts of the ROI may exist. Watershed-ding demands a binary image and because the adjacent peak may be much lower, thresholding is not straightforward.
Flood fill wouldn’t necessarily find 8-connected neighbouring grey values.

Is there a nifty trick or a built-in command for this region growing based on monotonically descending grey value?


Good day!

Let’s assume you’ve two overlapping Gaussians with different maximum.

You could lower a threshold from the absolute maximum until the thresholded areas fuse, i.e. you get (again) a single selection instead of two.

Would this work?




If it is the only other peak, I would know where that other peak is, and what its height is, yes, you could. I know neither a priori and there are many peaks.
There are 10 peaks in this cropped part of a very much larger image…
if you do the Plot Surface, you will see them.
(I did upload the 27x32 pix image but don’t see it. Lets put an enlarged image here)


Why do you need to know it?

You simply start with the absolute maximum which is easy to determine, then lower until you get two selections, and finally stop if these two selections fuse.

Perhaps I misunderstood your problem.




Please don’t post the image/excerpt as screen shot, but as original TIFF or PNG.


Thanks, I tried that approach first. Running a macro that implemented your idea cost me too much time (days).

The ‘analyse particles’ with lowering threshold grey value by grey value will too often find a distant peak (ie. the one-but hightest summit), not the one causing nearest saddle point.

Apart from that: if you first would reasonably quickly find the peaks and then have to calculate all their respective neighbour’s distances, the problem is O(N2), with some clever sorting maybe a bit faster; once I solve this for 2D, I’ll have to do 3D, so time would increase with N3. The solution I’m looking for should preferably be O(N), N the number of peaks, not O(N2).

Hence maybe I should restate the problem, with the current knowledge, to
"how do I find the saddle point nearest a summit without a priori knowledge"

I posted (ie. uploaded) the 27x32 pixel 16 bit tiff file twice during my previous reply but it vanished in the intergalactic bit bucket. Probably because it was too small for display? Hence I zoomed in 1600%, took a screen shot and that is accepted and displayed.


It’s always interesting to receive personal boundary conditions after having invested in ideas and methods.

Please post the sample image in original size (perhaps embedded in a larger black canvas), otherwise one cannot try out any approaches.




Thanks Herbie. The boundary conditions are not a limit, they were to indicate why and how things went wrong, because run time was 3 days on a O(N2) type solution when I used the full size image in 2D, and would be even more problematic in 3D. I mentioned ‘preferabley’, didn’t I? A 10 minute run time solution on a full scale 2D stack, even if it is O(N2), would be quite OK too!

As you requested, I have uploaded the ten peaks image embedded in a larger field and uploaded this, along with the surface plot visualisation of the ten peaks I refer to.

(This saddle search is part of a larger macro, which I currently test by using a circle that is only 3 pixels in diameter and hence never can contain a saddle point.)



(do you see the 100x100x16 bit TIFF file or the surface plot tif? I don’t.)


I fear image stacks are not accepted by the Forum.


It is a flat image of 100 x 100 pixels, 16 bit. The surface plot is a 610 x 519 RGB tiff file. I drag and drop the images in the Editor field of the forum, see a brief [Uploading...]() . message in the editor window and that’s it. No image to be seen in my posting.


Please use the upload button, i.e. the one with the arrow pointing upwards.

As far as I understand you are looking for a single maximum plus the defined surrounding per image. Is this correct?


  • Do you know anything about the relative position (maximum distance to the maximum peak) of the adjacent peak?
  • How many peaks are in a typical image?




I have now tried uploading using the upload button, as you asked, the same RGB surface plot file.
Uploading with the button behaves exactly the same, unfortunately: brief display of [Uploading...] (). but no image visible. Maybe after I upload, I should also link the uploaded image too the message I’m editing? (i don’t know the link once it is uploaded :frowning: ). Looks like a bug in the forum software?

I also tried an annotated jpg file, and that does work as you can see below.

I am looking for every peak and their nearest saddle point. After locating each peak, I ablate it from the image (fill its ROI with zeroes), rinse and repeat.

I keep looking for lower peaks until the peak is as high as the image’s average plus some [later to determine, for now the stddev] value or until I have found enough peaks to fit the needs of statistical analysis.

In the typical image there may be as many as 8000 peaks, as determined by my previous macro that did not yet grow regions (a broad peak would be recognised as many smaller peaks of 3x3 pixels). Realistic estimates are 500 individual peaks.


Things are far from clear to me after that many exchanges.

So you are not only interested in a single peak plus surround of an image?
Do you start with the highest peak?

Could you please explain what is the goal of your analysis?

Please post the original sample image as TIFF or PNG file.





Are you familiar with the watersheds in image processing? At quick glance, your goal seems to be identical to the watershed algorithm applied on the negative (or inverse) of your intensities (“topographic map”).

@Herbie 's suggestion above would be “Watershed by flooding”



@bogovicj: Unless I misunderstand you, when I apply Watershed, I need a binary image. The ImageJ error message when applied to my sample image or the inverted of my sample image thus is "Watershed: 8-bit binary image (0 and 255) required."
Making the image binary in the proper way is the problem. Maybe I overlook the obvious?


Watershed can and should be run on grayscale images.

The Classic Watershed plugin runs on any grayscale image (8, 16 and 32-bit) in 2D and 3D.

from https://imagej.net/Classic_Watershed


Marvellous. It calculated exactly what I need, and in under three minutes. Thanks!


Hello @eljonco,
I’m sorry to butt in here, but could you (please) send a finished image so that I may more understand exactly it is you were looking for?
It was a very interesting conversation and I would like to remember it for future reference.
Sorry for any trouble but I am relatively new to ImageJ and its very steep learning curve.



A little clarification: Consider this as a mountain landscape. The watershed method places a trench around a peak and this trench has the highest altitutde on the saddle point between two peaks. The trench runs downhill to either side, but since we are looking for a horizontal ‘rope’ around the peak we don’t want to descend, go lower, than the saddle point’s altitude.

We do however now have obtained the height we were looking for. Reading the altitude from the saddle point, we encircle our peak at the same height until we return at our saddle point. Coding “is left as an excercise to the student” and is almost trivial using a setThreshold(saddlepointAltitude,peakAltitude) and a doWand(saddlepointx,saddlepointy).