Here is the full solution. You have to include the annotations in the creation of the roi_dict. It took some digging but you also need give a zr::Signal{ZoomRegion{T}} to use the desired version of imshow. To get an out of the box solution, I needed to also inclued GtkReactive.
using Statistics, Images, ImageView, Gtk.ShortNames, GtkReactive
function ex()
numCols, numRows, numFrames = 100, 100, 100
frameRate = 1 # numFrames / sec
p0 = [25, 25] # initial position of target
v = [1, 1] # velocity pixel / sec
img = randn(numCols, numRows, numFrames) # creat white noise background
kernel = 10 .* [0 1 0;
1 2 1;
0 1 0] # simple bright target
p_truth = zeros(2, numFrames)
for fn = 1:numFrames
p = p0 + (fn / frameRate-1) * v # constant velocity
y, x = Int(round(p[1])), Int(round(p[2])) # convert position to nearest pixel for simplicity
if 1 < y < numCols && 1 < x < numRows # our kernel is 3x3 so only get within one of the edge
img[y-1:y+1, x-1:x+1, fn] = kernel
end
p_truth[:,fn] = p
end
img .-= minimum(img)
img = n0f8.(img./maximum(img))
gd = imshow_gui((numCols, numRows))
c = gd["canvas"]
Gtk.showall(gd["window"])
sig = ImageView.Signal(img[:,:,1])
anns = annotations()
roi_dict = imshow(c, sig, Signal(ZoomRegion(value(sig))), anns)
for fn in 2:numFrames
push!(sig, img[:,:,fn]) # this works, and zoom is still supported
# Get detections from algo
list_of_detections = [p_truth[:,fn]] # for simplicity only grab true detections
aIx = []
for p in list_of_detections
y, x = Int(round(p[1])), Int(round(p[2]))
# Creating annotation do not show after first frame
a = annotate!(anns, c, roi_dict,
AnnotationBox(x - 5, y - 5,
x + 5, y + 5,
linewidth=2, color=RGB(1,0,0))
)
push!(aIx, a)
end
sleep(0.5)
[delete!(anns,a) for a in aIx] # remove previous detections after they have been seen
end
end
ex()