Interactively cropping a TIFF stack?

I’ve got some 8-bit TIFF stacks, on the order of 300x300x150 (x * y * slices) in size. I can load these into Julia fine and display them, what I’d really like to be able to do now is interactively crop out a region define by the mouse (rectangular is fine, no need for spline fits to many points) and save that crop to a new image.

The basic code I’ve got so far is:

using Images, ImageView;
using Gtk;

using QuartzImageIO; 
#On a mac, it seems I need this else I get errors about no being able to load image

filename = open_dialog("My Open dialog")
image = load(filename);

imshow(image);

mouse_pos = map(d->println("x = $(float(d.position.x)), y = $(float(d.position.y))"),s["gui"]["canvas"].mouse.buttonpress)
@show mouse_pos;

I’ll admit the mouse_pos bit is complete cargo cult programming, it came from a google search and I’m not sure how it is supposed to work. It just doesn’t seem to for me. I think I could probably do this using GTKReactive, but I don’t really want t create a whole GUI program for this simple-ish task.

Any pointers to info or help with the code is greatly appreciated.

Here’s a solution with GLMakie, although somehow it seems the zoom rectangle was broken in the last version so it’s not actually visible. Would have been cooler if the selection was actually visible.

I didn’t write the cropping and saving part but you can see where you’d put it in the code.

using GLMakie

images = randn(300, 300, 150)

fig = Figure()

i_slice = Node(1)

ax = Axis(fig[1, 1], aspect = DataAspect(), yreversed = true,
    title = @lift("Slice $($i_slice)"))
hidedecorations!(ax)

chosen_slice = @lift(images[:, :, $i_slice]')

i = image!(ax, chosen_slice)
translate!(i, 0, 0, -5)

buttongrid = fig[1, 2] = GridLayout(tellheight = false)
b = Button(buttongrid[1, 1], label = "Save crop")
b2 = Button(buttongrid[2, 1], label = "Next image")
b3 = Button(buttongrid[3, 1], label = "Previous image")

on(b.clicks) do c
    lims = ax.finallimits[]
    println("save image cropped to $lims")
end

on(b2.clicks) do c
    i_slice[] = mod1(i_slice[] + 1, 150)
    autolimits!(ax)
end

on(b3.clicks) do c
    i_slice[] = mod1(i_slice[] - 1, 150)
    autolimits!(ax)
end

fig
1 Like

Thank you!

It is a shame the crop boundary isn;t drawn, but that’s something minor for now.