I think I have these two identical function (the difference is using acc inside a loop or not)
function convolve_image_bad(M::AbstractMatrix, K::AbstractMatrix)
M′ = zero(M)
nrow, ncol = size(M)
lr, lc = size(K) .÷ 2 # find K's center
for i in 1:nrow
for j in 1:ncol
for r_offset in -lr:lr
for c_offset in -lc:lc
# K centered at (lr+1, lc+1)
M′[i, j] += extend_mat(M, i+r_offset, j+c_offset) * K[lr+1+r_offset, lc+1+c_offset]
end
end
end
end
return M′
end
function convolve_image(M::AbstractMatrix, K::AbstractMatrix)
M′ = zero(M)
nrow, ncol = size(M)
lr, lc = size(K) .÷ 2 # find K's center
for i in 1:nrow
for j in 1:ncol
acc = M′[i, j]
for r_offset in -lr:lr
for c_offset in -lc:lc
# K centered at (lr+1, lc+1)
acc += extend_mat(M, i+r_offset, j+c_offset) * K[lr+1+r_offset, lc+1+c_offset]
end
end
M′[i, j] = acc
end
end
return M′
end
set my kernel to
K_test = [
1/16 1/8 1/16
1/8 1/4 1/8
1/16 1/8 1/16
]
which sums up to 1.
some definitions are here
philip_file = download("https://i.imgur.com/VGPeJ6s.jpg")
decimate(image, ratio=5) = image[1:ratio:end, 1:ratio:end]
function extend_mat(M::AbstractMatrix, i, j)
nrow, ncol = size(M)
return M[clamp(i, 1, nrow), clamp(j, 1, ncol)]
end
philip = let
original = Images.load(philip_file)
decimate(original, 8)
end
when I applied the convolve_image_bad function on this picture
convolve_image_bad(philip, K_test)
I got errors
ArgumentError: element type FixedPointNumbers.Normed{UInt8,8} is an 8-bit type representing 256 values from 0.0 to 1.0,
but the values (0.9120098039215686, 0.9495098039215686, 1.0036764705882353) do not lie within this range.
See the READMEs for FixedPointNumbers and ColorTypes for more information.
throw_colorerror_(::Type{FixedPointNumbers.Normed{UInt8,8}}, ::Tuple{Float64,Float64,Float64})@types.jl:686
throw_colorerror(::Type{ColorTypes.RGBX{FixedPointNumbers.Normed{UInt8,8}}}, ::Tuple{Float64,Float64,Float64})@types.jl:736
checkval@types.jl:654[inlined]
RGBX@types.jl:168[inlined]
_convert@conversions.jl:87[inlined]
cconvert@conversions.jl:76[inlined]
convert@conversions.jl:73[inlined]
setindex!@array.jl:849[inlined]
convolve_image(::Array{ColorTypes.RGBX{FixedPointNumbers.Normed{UInt8,8}},2}, ::Array{Float64,2})@Other: 11
top-level scope@Local: 1[inlined]
which indicates during the loop the RGB value exceeded 1.0.
the image is a matrix of RGBX{Normed{UInt8,8}}
all the FixedPointNumbers.Normed{UInt8,8} is an 8-bit type representing 256 values from 0.0 to 1.0,
and my kernel sums up to 1.0, so no value should be exceeding 1.0 during the loop in theory.
more interestingly when I apply convolve_image(philip, K_test)
it does the job without complaining.
I was wondering what causes the difference between the two convolve functions.