Update existing imshow with new image data

I want to set up a rapid loop of updating a screen with some image data and then fetching the result with a webcam that is pointed at the screen (the idea is to sample hundreds of cycles, change some external filter between the screen and camera, and sample again).

How can I update an already existing imshow Dict with new image data? The new data has the same dimensions and type as the old one. The updated imshow window should not move in relation to the physical screen from update to update.

I’m convinced that I need to connect the call to imshow with a Signal of an image, and then just push! to that signal, but I can’t get it to work…

Thanks!!!

3 Likes

Not sure what plotting library you’re using, but I’ve been playing around with Makie.jl for this sort of thing and it’s great (though still in development).

I’ve got some code here that updates a heatmap display with a 2D matrix representing an scrolling audio spectrogram, which seems to perform really well.

1 Like

Also note that code isn’t a particularly great audio DSP example because it doesn’t do any windowing so there’s a lot of spectral leakage. It should get the point across, though

Cool! Well, because I’m only updating an image, I thought ImageView.imshow would do. But I’ve been meaning to try Makie for a while now, so maybe this should be it!

I do think there’s a way to get ImageView to do what you want, I’m pretty sure I’ve seen Tim demo animations and videos before. Unhelpfully I don’t know how though. :slightly_frowning_face:

Same here :slight_smile:

Maybe someone will. Thanks for the Makie tip though!

Here’s a way with ImageView.imshow:

using ImageView, Images
img = rand(640,480)
guidict = ImageView.imshow(img)
canvas = guidict["gui"]["canvas"]
img2 = rand(640,480)
ImageView.imshow(canvas, img2)
2 Likes

I think this is how you do the same thing with Makie:

using Makie, FileIO, GeometryTypes, Colors
scene = Scene(resolution = (500, 500), color = :black);
img = rand(RGB{N0f8}, 256, 256);
image(img);
center!(scene);
img2 = rand(RGB{N0f8}, 256, 256);
image(img2);

(I overloaded on the semicolons at the line ends because some of these spit out pretty big output at the REPL.)

1 Like

rather than creating a new image object you can just update the data for the existing one with img = image(olddata); img[:image] = newdata. Not sure how much overhead this saves, but I’d guess it’s at least slightly more efficient. This might act strangely if the image size changes though.

2 Likes

Thanks @ssfrr, that approach is much faster with Makie.

Cool guys!!! Thanks!

When this is called in a loop RAM is slowly filled until it is full. Didnt find a solution yet.