pascal
October 6, 2022, 9:56am
1
I have multiple images stacked into an array:
using CairoMakie
using Images
using DataFrames
using DataFramesMeta
# Load cow
img_orig = load(Makie.assetpath("cow.png"))
img_filt1 = imfilter(img_orig, Kernel.gaussian(3))
img_filt2 = imfilter(img_orig, Kernel.gaussian(30))
img_filt3 = imfilter(img_orig, Kernel.gaussian(300))
img_bw = Gray.(img_orig)
# Combine
img_array = [img_orig;;; img_filt1;;; img_filt2;;; img_filt3;;; img_bw]
and a data frame with x and y coordinates as well as a colour and a frame column s.t.
df = DataFrame(x=rand(1:400, 10), y=rand(1:300, 10), c=rand(10), f=rand(1:5, 10))
Now, I want to create an animation (i.e. time lapse movie) where each frame corresponds to an image in the array overlayed with dots defined by the dataframe. So far I have the following but cannot figure out how to properly animate, record and save it.
frame_i = Observable(1)
df_i = @lift(@rsubset(df, :f == $frame_i))
img_i = @lift(img_array[:, :, $frame_i])
# Plot
function _plt_fig(frame)
frame_i[] = frame
fig = Figure()
ax = CairoMakie.Axis(fig[1, 1])
image!(ax, rotr90(img_i.val))
scatter!(ax, df_i.val.x, df_i.val.y, color=df_i.val.c, markersize=30)
return fig
end
Any help would be greatly appreciated.
johnh
October 6, 2022, 11:10am
2
For saving as a video I think VideoIO.jl would help
1 Like
pascal
October 7, 2022, 7:32am
3
Thanks @johnh . With VideoIO.save
I could save an image stack to .mp4 for instance.
Which brings me to another way to approach this problem.
I could also flatten the dataframe data into the image such that I get one new image from this and save these to a new stack and write them out to a video. I, however, also do not know how to do this “flattening”.
pascal
October 7, 2022, 8:03am
4
Alright… I’ve figured it out:
using CairoMakie
using Images
using DataFrames
using DataFramesMeta
# Load cow
img_orig = load(Makie.assetpath("cow.png"))
img_filt1 = imfilter(img_orig, Kernel.gaussian(3))
img_filt2 = imfilter(img_orig, Kernel.gaussian(30))
img_filt3 = imfilter(img_orig, Kernel.gaussian(300))
img_bw = Gray.(img_orig)
# Combine
img_array = [img_orig;;; img_filt1;;; img_filt2;;; img_filt3;;; img_bw]
# Data
df = DataFrame(x=rand(1:400, 10), y=rand(1:300, 10), c=rand(10), f=rand(1:5, 10))
frame_i = Observable(1)
df_i = @lift(@rsubset(df, :f == $frame_i))
img_i = @lift(img_array[:, :, $frame_i])
fig = Figure()
ax = CairoMakie.Axis(fig[1, 1])
# Plot
function _plt_fig!(frame)
frame_i[] = frame
image!(ax, rotr90(img_i.val))
scatter!(ax, df_i.val.x, df_i.val.y, color=df_i.val.c, markersize=30)
return fig
end
frames = 1:5
record(fig, "video.mp4", frames; framerate=1) do i
_plt_fig!(i)
end