Deblurring an Image using Julia (Transform from Matlab to Julia)


#1

I wrote the code for deblurring an image using the heat equation. I transformed the matlab code to Julia code. But it’s not working and I don’t really understand the error message. I get an error message:

ERROR: LoadError: MethodError: no method matching ccolor(::Type{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}}}, ::Type{Array{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},1}})
Closest candidates are:
  ccolor{Cdest<:ColorTypes.Colorant{T,N},Csrc<:ColorTypes.Colorant{T,N}}(::Type{Cdest<:ColorTypes.Colorant}, ::Type{Csrc<:ColorTypes.Colorant}) at /Users/hi88/.julia/v0.5/ColorTypes/src/traits.jl:237
  ccolor{Cdest<:ColorTypes.Color{T,1},T<:Number}(::Type{Cdest<:ColorTypes.Color{T,1}}, ::Type{T<:Number}) at /Users/hi88/.julia/v0.5/ColorTypes/src/traits.jl:238
 in convert(::Type{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}}}, ::Array{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},1}) at /Users/hi88/.julia/v0.5/ColorTypes/src/conversions.jl:7
 in macro expansion at ./multidimensional.jl:350 [inlined]
 in macro expansion at ./cartesian.jl:64 [inlined]
 in macro expansion at ./multidimensional.jl:348 [inlined]
 in _unsafe_getindex! at ./multidimensional.jl:340 [inlined]
 in macro expansion at ./multidimensional.jl:298 [inlined]
 in _unsafe_getindex(::Base.LinearFast, ::Array{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},2}, ::Colon, ::Array{Any,1}) at ./multidimensional.jl:291
 in getindex(::Array{ColorTypes.Gray{FixedPointNumbers.UFixed{UInt8,8}},2}, ::Colon, ::Array{Any,1}) at ./abstractarray.jl:752
 in macro expansion; at /Users/hi88/Desktop/julia/heat.jl:14 [inlined]
 in anonymous at ./<missing>:?
 in include_from_node1(::String) at ./loading.jl:488
 in include_from_node1(::String) at /Applications/Julia-0.5.app/Contents/Resources/julia/lib/julia/sys.dylib:?
while loading /Users/hi88/Desktop/julia/heat.jl, in expression starting on line 13

This is my code:

#clear,clc;
using ImageView, Images, Colors, FixedPointNumbers, TestImages

  img=imread("clock.tiff")
  A=data(img)
  u=convert(Array,A)

  (m,n)=size(u)
  k=1;
  dt=0.2
  T=10

  for t in 0:dt:T
    u_xx=u[:, [2:n,n]]-2*u+u[:,[1, 1:n-1]]
    u_yy=u[[2:m,m],:]-2*u+u[[1,1:m-1],:]
    L=u_xx+u_yy
    u=u-k*dt*T
  end

  imshow(reinterpret(Uint8,u))
  imwrite(reinterpret(Uint8,u),"deblurredimage.tiff")
end

#2

The error is to do with colors, and hence with the image processing. If you enter the code line by line in the REPL or in a notebook, where does the first error occur?

Also, what is the final end doing?


#3

It keeps saying that my loop is incorrect. But I think it’s fine. I don’t know if my imshow, data, and convert is used correctly in my code.


#4

Hi

You have

u_xx=u[:, [2:n,n]]-2*u+u[:,[1, 1:n-1]]

however

@show typeof([2:n,n])
typeof([2:n,n]) = Array{Any,1}
Array{Any,1}

julia> @show size([2:n,n])
size([2:n,n]) = (2,)
(2,)

I suspect what you want is:

@show typeof([2:n;n])
typeof([2:n;n]) = Array{Int64,1}
Array{Int64,1}

julia> @show size([2:n;n])
size([2:n;n]) = (512,)
(512,)

Thus a loop looking closer to this:

for t in 0:dt:T
           u_xx=u[:, [2:n;n]]-2*u+u[:,[1; 1:n-1]]
           u_yy=u[[2:m;m],:]-2*u+u[[1;1:m-1],:]
           L=u_xx+u_yy
           u=u-k*dt*T
         end

Even with that change I still get an error due to -k*dt*T being a float and the - operator not being implemented for the color type I have in combination with a float. You would probably need to cast between float and Fixed in some manner (sorry, I have almost no experience with the FixedPointNumbers so cannot quickly supply the cast)
Note I don’t have the same “clock.tiff”, so I’m getting a different colortype (GrayA) on the test image I used.


#5

I used the “clock.tiff” from http://sipi.usc.edu/database/database.php?volume=misc. I’m just trying to deblur the image for grayscale images. Is that the problem?


#6

As mentioned in my first post, your main problem is using a , instead of ; and thus creating a weird vector instead of the indexing vector you expected.

With that file and my modified for loop, the code now runs. Atleast until it doesn’t find the imshow on my system.

However I guess you still have a mistake, since L is never used and thus u is just the original image being modified by a constant very time through the loop.


#7

Could I see your code? My still doesn’t run as expected. Thanks!


#8
using ImageView, Images, Colors, FixedPointNumbers, TestImages

img=imread("clock.tiff")
  A=data(img)
  u=convert(Array,A)

  (m,n)=size(u)
  k=1;
  dt=0.2
  T=10

  for t in 0:dt:T
    u_xx=u[:, [2:n;n]]-2*u+u[:,[1; 1:n-1]]
    u_yy=u[[2:m;m],:]-2*u+u[[1;1:m-1],:]
    L=u_xx+u_yy
    u=u-k*dt*T
  end

# Renormalise to be within 0 and 1
u -= minimum(u)
u ./= maximum(u)

ImageView.view(grayim(u))   # display as seperate window
grayim(u)                   # display in IJulia



#9

As a beginner I do find Images.jl tricky to use (if you’re more used to other systems), but I’m sure it’s more than capable of doing the job, once you’ve got the hang of it.

I went back to the original paper (PDF here), and tried to get their method working. I didn’t have a lot of success, but here’s as far as I’ve got. Using the cameraman from TestImages.jl:

using Images, TestImages
function deblurimage(inputimage, targetfilename)
    width, height = widthheight(inputimage)
    dt = .00006
    dx = 1/(width-1)
    dy = 3.2/(height-1)

    source = inputimage
    target = similar(source)

    for n in 1:20
        for j = 2:height-1
            for i = 2:width-1
                target[i, j] = clamp(
                    source[i, j]   - (dt/(dx^2)) * (source[i-1, j] -2source[i,j]) + 
                    source[i+1, j] - (dt/(dy^2)) * (source[i, j-1] -2source[i, j] + source[i, j+1]), 0, 1)
            end
        end
    end
    save(targetfilename, target)
end

inputimage = testimage("cameraman")
deblurimage(inputimage, "/tmp/output.tiff")

I’ve used clamp() because I don’t see how you can do all these calculations on values without pushing them outside the 0…1.0 range. @lwabeke’s idea of renormalising is good but I got too many NaN values.

I’m sure there’s a better way. I hope Images.jl starts to build up some basic tutorial material before too long…! :slight_smile:


#10

I tried it. But the code you provided doesn’t seem to work. Do you have any other suggestions?


#11

Please define what you mean by not working?
Is it giving error messages? What is the error message?

Yes, the code doesn’t deblur the image, but that is due to the fact that your original code had a bug in the algorithm.