Where's Waldo?
We will use FLCC
to find Waldo
using FastLocalCorrelationCoefficients, Images
img = mktemp() do fn,f
download("https://i.stack.imgur.com/reNlF.jpg", fn)
load(fn)
end
Our template is a noisy, darkened version of Waldo
waldo = 0.5 .* img[140:200, 160:195] .+ Gray.( 0.2*rand(200-140+1, 195-160+1) )
Transform the images into 3D tensors
T = permutedims( Float64.( collect( channelview(waldo) ) ), [2 3 1] );
F = permutedims( Float64.( collect( channelview(img) ) ), [2 3 1] );
768×1024×3 Array{Float64, 3}: [:, :, 1] = 1.0 0.772549 0.34902 0.654902 … 0.298039 0.772549 0.941176 1.0 0.94902 0.501961 0.470588 0.631373 0.929412 0.929412 0.984314 1.0 0.803922 0.423529 0.92549 0.917647 0.921569 0.988235 0.984314 1.0 0.788235 0.941176 0.933333 0.905882 0.894118 0.984314 1.0 1.0 0.576471 0.819608 0.72549 0.811765 1.0 0.980392 0.976471 … 0.407843 0.541176 0.490196 0.945098 0.996078 1.0 0.996078 0.556863 0.592157 0.717647 1.0 1.0 1.0 1.0 0.494118 0.380392 0.545098 0.976471 1.0 0.996078 1.0 0.470588 0.623529 0.831373 0.737255 1.0 1.0 0.988235 0.623529 0.788235 1.0 ⋮ ⋱ 0.964706 1.0 1.0 0.843137 0.498039 0.560784 0.815686 1.0 1.0 1.0 0.623529 … 0.45098 0.592157 0.803922 0.827451 0.984314 1.0 1.0 0.509804 0.482353 0.803922 0.596078 0.745098 0.901961 1.0 0.631373 0.364706 0.784314 0.952941 0.694118 0.505882 0.490196 0.882353 0.419608 0.380392 1.0 0.960784 0.643137 0.517647 1.0 0.796078 0.333333 1.0 1.0 0.882353 0.568627 … 0.992157 0.929412 0.72549 0.972549 1.0 1.0 0.631373 0.945098 0.741176 0.784314 0.976471 0.972549 1.0 0.94902 0.956863 0.756863 0.760784 [:, :, 2] = 0.964706 0.737255 0.356863 0.698039 … 0.270588 0.756863 0.92549 0.984314 0.921569 0.509804 0.501961 0.596078 0.894118 0.894118 0.960784 1.0 0.807843 0.443137 0.87451 0.858824 0.862745 0.968627 0.980392 1.0 0.796078 0.866667 0.85098 0.811765 0.886275 0.976471 1.0 1.0 0.486275 0.709804 0.611765 0.803922 0.992157 0.964706 0.956863 … 0.298039 0.419608 0.352941 0.929412 0.980392 0.996078 0.972549 0.45098 0.454902 0.568627 0.976471 0.984314 0.996078 0.980392 0.388235 0.25098 0.396078 0.929412 0.988235 0.984314 1.0 0.372549 0.501961 0.698039 0.623529 0.917647 0.992157 0.984314 0.533333 0.678431 0.905882 ⋮ ⋱ 0.960784 0.992157 0.956863 0.780392 0.498039 0.666667 0.980392 0.960784 0.964706 0.980392 0.537255 … 0.454902 0.709804 0.992157 0.729412 0.882353 0.909804 0.917647 0.498039 0.588235 0.968627 0.447059 0.603922 0.764706 0.913725 0.580392 0.407843 0.882353 0.8 0.545098 0.360784 0.333333 0.819608 0.435294 0.431373 0.968627 0.847059 0.513725 0.34902 0.984314 0.803922 0.376471 0.952941 0.984314 0.772549 0.396078 … 0.972549 0.968627 0.792157 0.980392 0.984314 0.952941 0.466667 0.976471 0.839216 0.917647 1.0 0.972549 0.980392 0.788235 1.0 0.882353 0.92549 [:, :, 3] = 0.964706 0.709804 0.262745 0.541176 … 0.239216 0.721569 0.890196 0.992157 0.898039 0.423529 0.356863 0.568627 0.866667 0.866667 0.968627 0.980392 0.737255 0.317647 0.843137 0.831373 0.835294 0.984314 0.972549 0.956863 0.709804 0.843137 0.831373 0.796078 0.905882 0.980392 0.980392 0.956863 0.462745 0.694118 0.596078 0.815686 0.996078 0.960784 0.945098 … 0.282353 0.407843 0.345098 0.917647 0.976471 1.0 0.988235 0.423529 0.439216 0.556863 0.945098 0.960784 0.992157 1.0 0.360784 0.231373 0.384314 0.866667 0.941176 0.956863 0.992157 0.352941 0.490196 0.690196 0.552941 0.85098 0.952941 0.964706 0.509804 0.662745 0.890196 ⋮ ⋱ 0.160784 0.184314 0.156863 0.00784314 0.490196 0.701961 1.0 0.203922 0.2 0.219608 0.0 … 0.435294 0.74902 1.0 0.12549 0.266667 0.254902 0.27451 0.470588 0.615686 1.0 0.129412 0.235294 0.294118 0.392157 0.545098 0.415686 0.909804 0.670588 0.360784 0.054902 0.0 0.768627 0.431373 0.454902 0.941176 0.776471 0.352941 0.133333 0.94902 0.8 0.392157 0.960784 0.956863 0.690196 0.282353 … 0.94902 0.976471 0.819608 0.960784 0.952941 0.898039 0.380392 0.984314 0.866667 0.956863 0.984314 0.941176 0.937255 0.717647 1.0 0.92549 0.980392
First, we show that the un-normalized convolution is unable to locate Waldo
R = FastLocalCorrelationCoefficients.fcorr( F, T );
R = R[CartesianIndex((size(T))):CartesianIndex(size(F))][:,:,1]
R = R / maximum(R)
Gray.( R )
The position with the maximum value is not Waldo.
idx_R = best_correlated( R ) .+ (CartesianIndex(0,0):CartesianIndex(70, 35))
img[idx_R]
Next, we compute FLCC
and visualize the correlations.
M = flcc( F, T )[:,:,1];
Gray.( (M .+ 1) ./ 2 )
We found Waldo!
idx = best_correlated( M ) .+ (CartesianIndex(0,0):CartesianIndex(70, 35))
img[idx]