# Debugging with ImageView.jl

**URL:** <https://discourse.julialang.org/t/debugging-with-imageview-jl/54646>\
**Category:** New to Julia\
**Tags:** question, images\
**Created:** [February 4, 2021, 8:26pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646 "2021-02-04T20:26:43Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![nicrummel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicrummel/32/6304_2.png) [@nicrummel](https://discourse.julialang.org/u/nicrummel)\
**Post date:** [February 4, 2021, 8:26pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/1 "2021-02-04T20:26:43Z")

</div>

I really like the simplicity of ImageView.jl. It appears to be everything I need:

- showing an Matrix{Float64} as an image that scales appropriately,
- annotating with simple shapes or text

I am currently working on a detection algorithm, and I want to show the current image with my detections boxed. I do not want to have to open and close a gui every time a new image comes, but rather update the image and the annotaitons at each frame. This is a very simple task in C++ and Matlab. I would have thought this would be a basic behavior to ImageView.jl. There must be something simple I am missing, but I do not seem to see an easy solution.

Thanks for any assistance!

```julia
using Statistics, Images, ImageView
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
    ## Create data for reproducibility
    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

    ## Below is the code that I wish worked
    gd, c = nothing, nothing
    for fn in 1:numFrames
        if fn ==1
            gd = imshow(img[:,:,fn])
            c = gd["gui"]["canvas"]
        else
            # this part seems to be creating issues
            # if I use imshow! the matrix does not get converted in to the proper type, maybe ?
                imshow!(c, img[:,:,fn])
                # error message
                # Warning: Error in @guarded callback
                # └ @ GtkReactive ~/.julia/packages/Gtk/C22jV/src/base.jl:90
                # ::ERROR: ReactiveArgumentError: element type Normed{UInt8,8} is an 
                # 8-bit type representing 256 values from 0.0 to 1.0,
                # but the values (-1.5032452089414814,) do not lie within this range.
                # See the READMEs for FixedPointNumbers and ColorTypes for more information..
            # if I use imshow (sans !) this image changes, but zooming does not work
            # and annotations dont show up
                # imshow(c, img[:,:,fn])
        end
        # 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!(gd,
                        AnnotationBox(x - 5, y - 5,
                                        x + 5, y + 5,
                                        linewidth=2, color=RGB(1,0,0))
                        )
            push!(aIx, a)
        end
        readline()
        [delete!(gd,a) for a in aIx] # remove previous detections after they have been seen
    end
end
ex()

```

---

<div class="post-metadata">

**Author:** ![nicrummel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicrummel/32/6304_2.png) [@nicrummel](https://discourse.julialang.org/u/nicrummel)\
**Post date:** [February 4, 2021, 8:28pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/2 "2021-02-04T20:28:19Z")

</div>

@tim.holy do you have any suggestions?

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [February 4, 2021, 9:04pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/3 "2021-02-04T21:04:58Z")

</div>

`?imshow`; the example at the end gives a demo (see that final `push!`).

---

<div class="post-metadata">

**Author:** ![nicrummel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicrummel/32/6304_2.png) [@nicrummel](https://discourse.julialang.org/u/nicrummel)\
**Post date:** [February 4, 2021, 10:47pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/4 "2021-02-04T22:47:28Z")

</div>

I have tried this as well. The annotations are not connnected to the gui that is created by calling imshow in this way. Thanks for your help

```julia
    ## Below is the code that I wish worked
    # Change the type of the matrix to be compatible
    img .-= minimum(img)
    img = n0f8.(img./maximum(img)) # make the type of img be compatible with ImageView.Signal
    # Follow the example from the help string for imshow
    gd = imshow_gui((numCols, numRows))
    c = gd["canvas"]
    Gtk.showall(gd["window"])
    sig = ImageView.Signal(img[:,:,1])
    anns = annotations() # I do not see a Annotations in any of the fields of either roi_dict or gd
    roi_dict = imshow(c, sig)
    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
        for p in list_of_detections
            y, x = Int(round(p[1])), Int(round(p[2]))
            # while this does not error out, no annotations are shown
            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!(gd,a) for a in aIx] # remove previous detections after they have been seen
    end

```

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [February 4, 2021, 10:50pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/5 "2021-02-04T22:50:23Z")

</div>

And are you happy with the outcome?

For the purposes of your original question, the `ImageView.closeall` seems undesirable?

---

<div class="post-metadata">

**Author:** ![nicrummel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicrummel/32/6304_2.png) [@nicrummel](https://discourse.julialang.org/u/nicrummel)\
**Post date:** [February 4, 2021, 10:51pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/6 "2021-02-04T22:51:34Z")

</div>

I am sorry, the close all should not appear anymore. I replaced it with a sleep(0.5).  
The problem is that the annotations are not showing even though there is no error.

---

<div class="post-metadata">

**Author:** ![nicrummel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicrummel/32/6304_2.png) [@nicrummel](https://discourse.julialang.org/u/nicrummel)\
**Post date:** [February 4, 2021, 11:49pm UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/7 "2021-02-04T23:49:58Z")

</div>

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.

```julia
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()

```

---

<div class="post-metadata">

**Author:** ![tim.holy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tim.holy/32/52_2.png) [@tim.holy](https://discourse.julialang.org/u/tim.holy)\
**Post date:** [February 5, 2021, 9:00am UTC](https://discourse.julialang.org/t/debugging-with-imageview-jl/54646/8 "2021-02-05T09:00:29Z")

</div>

I’m short on time so won’t dig into this since you’ve got a solution you’re happy with, but please do submit any issues (or better, PRs 😉 ) about what was missing in the documentation or missing bits of functionality that would have made this easier.
