# Two almost identical image convolve function different results

**URL:** <https://discourse.julialang.org/t/two-almost-identical-image-convolve-function-different-results/52353>\
**Category:** General Usage\
**Tags:** question, package, images\
**Created:** [December 24, 2020, 11:49pm UTC](https://discourse.julialang.org/t/two-almost-identical-image-convolve-function-different-results/52353 "2020-12-24T23:49:22Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![zshen0x](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zshen0x/32/20524_2.png) [@zshen0x](https://discourse.julialang.org/u/zshen0x)\
**Post date:** [December 24, 2020, 11:49pm UTC](https://discourse.julialang.org/t/two-almost-identical-image-convolve-function-different-results/52353/1 "2020-12-24T23:49:22Z")

</div>

I think I have these two identical function (the difference is using acc inside a loop or not)

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

```

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

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

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

```julia
convolve_image_bad(philip, K_test)

```

I got errors

```julia
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.
