ImageView update image

I have an img that I display using ImageView.imshow(img). When img is modified, I would like to tell imshow to update the image. A thread on discourse suggest to call again imshow as follows.

canvas = imshow(img)[“gui”][“canvas”]
… some modification to img
imshow(canvas, img)

Unfortunately the second call to imshow is slow.
If instead I update the margins of the canvas, the redraw is faster (x10 at least)

Gtk.set_gtk_property!(canvas, :margin_top, some_value)

The problem is, I don’t want to change the margins! There should be another way to get a quick update of the image but I can’t find it. Any idea?

There’s a bit of documentation about precisely this with ?imshow, but perhaps it’s a bit too terse for it to be obvious. I improved the docstrings for imshow and imshow!, and in responding to this I noticed a bug; you’ll get all of this if you update your package(s).

Want to see if you can figure it out now? (Hint: check docstrings for imshow and imshow!, which is a lower-level approach.) I’m not being deliberately cagey, I’m deliberately using you as a testcase to see if the documentation is good enough now. If not, a PR would be appreciated!

My results:

julia> @time for i in axes(mri, 3); push!(imgsig, view(mri, :, :, i)); sleep(0.005); end
  0.168816 seconds (2.10 k allocations: 26.071 MiB, 1.43% gc time)

which since there are 27 frames is dominated by the sleep.

That doesn’t mean that there isn’t performance work to be done on ImageView, but perhaps it’s good enough for your purposes.

1 Like

Thanks for your answer.

Yes, the documentation of imshow is clear now and I get the same performance by pushing the image onto the Signal than by resizing the margins. Note that in the docstring example of imshow, you may want to add GtkReactive to the list of library used since Signal is part of it.

@doc imshow

[…]

Example
≡≡≡≡≡≡≡≡≡

using ImageView, TestImages, Gtk # ← GtkReactive is also used in the example.
mri = testimage(“mri”);
[…]
imgsig = Signal(mri[:,:,1]) # GtkReactive.Signal here

Is there a way to catch and update the signal from the output of imshow without using Gtk and GtkReactive? I tried to push onto guidict["roi"]["image roi"] without success.

let img = rand(600,600),
guidict = imshow(img),
canvas = guidict[“gui”][“canvas”],
signal = guidict[“roi”][“image roi”]
sleep(1)
img[:,:] .= 0
sleep(1)
push!(signal, img) # imshow!(canvas, img) works
sleep(1)
“done”
end

1 Like

Doesn’t have to be me, anyone can do this if they have a web browser: Editing files - GitHub Docs. People unfamiliar with the code can make awesome documentation improvements since they catch errors that the developer might not (like in this case).

1 Like