3
votes

Here is the great example from StatWithJuliaBook (please find the following)

It demos how to smooth a plot of stary sky stars.png

My question is about argmax().I. According to the author, "Note the use of the trailing “.I” at the end of each argmax, which extracts the values of the co-ordinates in column-major."

What does it mean? Is there other parameter? I can't find any description in the document.

According to author, it seems to be the position of column-wise maxmum value, yet when I tried argmax(gImg, dims=2), the result is different.

#julia> yOriginal, xOriginal = argmax(gImg).I
#(192, 168)


#julia> yy, xx = argmax(gImg, dims = 2)
#400×1 Matrix{CartesianIndex{2}}:
# CartesianIndex(1, 187)
# CartesianIndex(2, 229)
 ⋮
# CartesianIndex(399, 207)
# CartesianIndex(400, 285)

#julia> yy, xx
#(CartesianIndex(1, 187), CartesianIndex(2, 229))

Please advise.

using Plots, Images; pyplot()

img = load("stars.png")
gImg = red.(img)*0.299 + green.(img)*0.587 + blue.(img)*0.114
rows, cols = size(img)

println("Highest intensity pixel: ", findmax(gImg))

function boxBlur(image,x,y,d)
    if x<=d || y<=d || x>=cols-d || y>=rows-d
        return image[x,y]
    else
        total = 0.0
        for xi = x-d:x+d
            for yi = y-d:y+d
                total += image[xi,yi]
            end
        end
        return total/((2d+1)^2)
    end
end

blurImg = [boxBlur(gImg,x,y,5) for x in 1:cols, y in 1:rows]

yOriginal, xOriginal = argmax(gImg).I
yBoxBlur, xBoxBlur   = argmax(blurImg).I

p1 = heatmap(gImg, c=:Greys, yflip=true)
p1 = scatter!((xOriginal, yOriginal), ms=60, ma=0, msw=4, msc=:red) 
p2 = heatmap(blurImg, c=:Greys, yflip=true)
p2 = scatter!((xBoxBlur, yBoxBlur), ms=60, ma=0, msw=4, msc=:red)

plot(p1, p2, size=(800, 400), ratio=:equal, xlims=(0,cols), ylims=(0,rows), 
    colorbar_entry=false, border=:none, legend=:none)

1

1 Answers

3
votes

I is a field in an object of type CartesianIndex which is returned by argmax when its argument has more than 1 dimension.

If in doubt always try using dump.

Please consider the code below:

julia> arr = rand(4,4)
4×4 Matrix{Float64}:
 0.971271  0.0350186  0.20805   0.284678
 0.348161  0.19649    0.30343   0.291894
 0.385583  0.990593   0.216894  0.814146
 0.283823  0.750008   0.266643  0.473104

julia> el = argmax(arr)
CartesianIndex(3, 2)

julia> dump(el)
CartesianIndex{2}
  I: Tuple{Int64, Int64}
    1: Int64 3
    2: Int64 2

However, getting CartesianIndex object data via its internal structure is not very elegant. The nice Julian way to do it is to use the appropriate method:

julia> Tuple(el)
(3, 2)

Or just access the indices directly:

julia> el[1], el[2]
(3, 2)