# Canny Edge Detector-JuliaImages

**URL:** https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335
**Category:** New to Julia
**Created:** [December 6, 2020, 4:38am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335 "2020-12-06T04:38:24Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![Ashwani\_Rathee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashwani_rathee/32/49551_2.png) [@Ashwani\_Rathee](https://discourse.julialang.org/u/Ashwani_Rathee)
#### Post date: [December 6, 2020, 4:38am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/1 "2020-12-06T04:38:24Z")

</div>

I am trying to implement canny edge detector on my own created image using array functionalities

```julia
 using Images, FileIO, ImageShow, ImageFiltering,TestImages,ImageFeatures,ImageTransformations,CoordinateTransformations, Rotations,OffsetArrays

||img_source=zeros(Float64, (200, 200));|
||img_gray=Gray.(img_source);|
||img_gray[50:150, 50:150] .= 1;|
||tfm = recenter(RotMatrix(pi/8), center(img_gray));|
||imgrot = warp(img_gray, tfm);||
||imgg = imfilter(imgrot, Kernel.gaussian(3));|
||imgfinal=Gray.(imgg);|
||img_edges = canny(imgfinal,(80,20),1);|#error thrown at this point
||[imgfinal Gray.(img_edges)];|

```

Error:

```julia
BoundsError: attempt to access 262×262 OffsetArray(::Array{Float64,2}, -30:231, -30:231) with eltype Float64 with indices -30:231×-30:231 at index [232, 1]

1. **throw_boundserror** (::OffsetArrays.OffsetArray{Float64,2,Array{Float64,2}}, ::Tuple{Int64,Int64})@ *abstractarray.jl:541*
2. **checkbounds** @ *abstractarray.jl:506* [inlined]
3. **getindex** @ *OffsetArrays.jl:269* [inlined]
4. **thin_edges_nonmaxsup_core!** (::Array{Float64,2}, ::Array{Graphics.Vec2,2}, ::OffsetArrays.OffsetArray{Float64,2,Array{Float64,2}}, ::OffsetArrays.OffsetArray{Float64,2,Array{Float64,2}}, ::Float64, ::String, ::Float64)@ *edge.jl:304*
5. **#thin_edges_nonmaxsup#88** (::Float64, ::Float64, ::typeof(Images.thin_edges_nonmaxsup), ::OffsetArrays.OffsetArray{Float64,2,Array{Float64,2}}, ::OffsetArrays.OffsetArray{Float64,2,Array{Float64,2}}, ::String)@ *edge.jl:354*
6. **thin_edges_nonmaxsup** @ *edge.jl:352* [inlined]
7. **canny** (::OffsetArrays.OffsetArray{ColorTypes.Gray{Float64},2,Array{ColorTypes.Gray{Float64},2}}, ::Tuple{Int64,Int64}, ::Int64)@ *edge.jl:399*
8. **top-level scope** @ *[Local: 10](http://localhost:1234/edit?id=76f06094-3761-11eb-0a1c-b75d84b942ec#)*

```

How do I resolve this and make it work??  
Also I wanted to create additional noise in the imgfinal with something like this in python:

```julia

# Generate noisy image of a square
im = np.zeros((128, 128))
im[32:-32, 32:-32] = 1

im = ndi.rotate(im, 15, mode='constant')
im = ndi.gaussian_filter(im, 4#I have successfully done till here
im += 0.2 * np.random.random(im.shape)#this is what I don't know

```

How to do this??

---

<div class="post-metadata">

### Author: ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)
#### Post date: [December 6, 2020, 5:59am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/2 "2020-12-06T05:59:57Z")

</div>

It looks like `canny` doesn’t work well with `OffsetArrays`. The output of `warp` is an `OffsetArray` with indices from -30:231, `canny` is attempting to index `1:width`. The fix is to turn the rotated and offset image back into an ordinary array by calling [`parent`](https://juliaarrays.github.io/OffsetArrays.jl/dev/internals/#Internals)

Something like this:

```julia
img_gray = zeros(Gray{Float64}, 200, 200)
img_gray[50:150, 50:150] .= 1
tfm = recenter(RotMatrix(pi/8), center(img_gray))
imgrot = warp(img_gray, tfm) |> parent
imgg = imfilter(imgrot, Kernel.gaussian(3))
img_edges = canny(imgg,(80,20),1)

```

> [@Ashwani\_Rathee](#):
>
> `im += 0.2 * np.random.random(im.shape)#this is what I don't know`

```julia
im += 0.2*rand(Gray{Float32}, size(im))

```

---

<div class="post-metadata">

### Author: ![zygmuntszpak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zygmuntszpak/32/2591_2.png) [@zygmuntszpak](https://discourse.julialang.org/u/zygmuntszpak)
#### Post date: [December 6, 2020, 10:43am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/3 "2020-12-06T10:43:03Z")

</div>

I registered a new package [ImageEdgeDetection.jl](https://github.com/JuliaImages/ImageEdgeDetection.jl) yesterday and it solves the issues you are encountering. That is, it works on [OffsetArrays](https://github.com/JuliaArrays/OffsetArrays.jl) and it also handles the `NaN`s that arise as a by-product of your `warp` function correctly. I discovered a moment ago when trying your example that the current `canny` function in `Images` seems to have a bug with `NaN`s because it yields spurious artifacts in the `NaN` regions of the image.

With the `ImageEdgeDetection` package, the solution you are looking for looks likes this:

```julia
using CoordinateTransformations
using ImageCore
using ImageEdgeDetection
using ImageFiltering
using ImageTransformations
using ImageShow
using OffsetArrays
using Rotations

img_gray = zeros(Gray{Float64}, 200, 200)
img_gray[50:150, 50:150] .= 1
tfm = recenter(RotMatrix(pi/8), center(img_gray))
imgrot = warp(img_gray, tfm) 
imgg = imfilter(imgrot, Kernel.gaussian(3))
algo = Canny(spatial_scale = 1, 
             high = ImageEdgeDetection.Percentile(80), 
             low = ImageEdgeDetection.Percentile(20))
img_edges = detect_edges(imgg, algo)   

```

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [December 6, 2020, 11:06am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/4 "2020-12-06T11:06:44Z")

</div>

Relevant Image.jl issue: [https://github.com/JuliaImages/Images.jl/issues/926](https://github.com/JuliaImages/Images.jl/issues/926)

---

<div class="post-metadata">

### Author: ![Ashwani\_Rathee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashwani_rathee/32/49551_2.png) [@Ashwani\_Rathee](https://discourse.julialang.org/u/Ashwani_Rathee)
#### Post date: [December 13, 2020, 7:27am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/5 "2020-12-13T07:27:12Z")

</div>

Another Issue arose

 ![Screenshot from 2020-12-13 12-54-09](https://global.discourse-cdn.com/julialang/original/3X/f/8/f85e097aa8fc826ede3830a1acbd9207dc7ab5b4.png)  
Issue arises when I am trying to add random noise after the gaussian filter.It’s another offset arrays issue,How to deal with this now??

@zygmuntszpak your solution worked perfectly well,but the difference between detected edges weren’t significant for sigma =1, sigma=3 with the image without random\_noise which I wanted to show,so I wanted to add some random\_noise…

Also,I am having a little bit of issue with using Plots to show the results as the center in ImageTransformations.j become undefined when I try to use Plots

```julia
# rotate the image by pi/8	
tfm = recenter(RotMatrix(pi/8), center(img_gray)) #this one
imgrot = warp(img_gray, tfm)

```

---

<div class="post-metadata">

### Author: ![Ashwani\_Rathee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashwani_rathee/32/49551_2.png) [@Ashwani\_Rathee](https://discourse.julialang.org/u/Ashwani_Rathee)
#### Post date: [December 13, 2020, 7:32am UTC](https://discourse.julialang.org/t/canny-edge-detector-juliaimages/51335/6 "2020-12-13T07:32:04Z")

</div>

This worked for me with some changes but It would be great if it can solved with ImageEdgeDetection.jl Directly
