Skip to content

Commit

Permalink
Fixes for Julia v0.7
Browse files Browse the repository at this point in the history
  • Loading branch information
juliohm committed Sep 5, 2018
1 parent dd7473c commit a0a2361
Show file tree
Hide file tree
Showing 10 changed files with 50 additions and 51 deletions.
10 changes: 4 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
# Documentation: http://docs.travis-ci.com/user/languages/julia/
language: julia
os:
- linux
- osx
julia:
- 0.6
- 0.7
- 1.0
- nightly
matrix:
allow_failures:
- julia: nightly
fast_finish: true
notifications:
email: false
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.clone(pwd()); Pkg.build("ImageInpainting"); Pkg.test("ImageInpainting"; coverage=true)'
after_success:
- julia -e 'cd(Pkg.dir("ImageInpainting")); Pkg.add("Coverage"); using Coverage; Codecov.submit(process_folder())'
- julia -e 'using Pkg; Pkg.add("Coverage")'
- julia -e 'using Coverage; Codecov.submit(process_folder())'
9 changes: 5 additions & 4 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
julia 0.6
ImageMorphology 0.0.2
ImageFiltering 0.2.3
Hwloc 0.6.2
julia 0.7
ImageMorphology 0.1.0
ImageFiltering 0.3.0
FFTW 0.2.4
CpuId 0.2.0
3 changes: 2 additions & 1 deletion src/ImageInpainting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module ImageInpainting

using ImageMorphology
using ImageFiltering
using Hwloc: num_physical_cores
using FFTW: set_num_threads
using CpuId: cpucores

include("utils.jl")
include("pointgradients.jl")
Expand Down
42 changes: 21 additions & 21 deletions src/crimisini.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
# ------------------------------------------------------------------

"""
Crimisini(psize)
Crimisini(tilesize)
Examplar-based inpainting based on confidence
and isophote maps. `psize` is the patch size
and isophote maps. `tilesize` is the patch size
as a tuple of integers.
## References
Expand All @@ -16,18 +16,18 @@ Crimisini, A., Pérez, P., Toyama, K., 2004. Region Filling
and Object Removal by Examplar-based Image Inpainting.
"""
struct Crimisini{N} <: InpaintAlgo
psize::Dims{N} # patch size
tilesize::Dims{N} # patch size
end

Crimisini(psize::Vararg{Int,N}) where {N} = Crimisini{N}(psize)
Crimisini(tilesize::Vararg{Int,N}) where {N} = Crimisini{N}(tilesize)

# implementation follows the notation in the paper
function inpaint_impl(img::AbstractArray{T,N}, mask::BitArray{N}, algo::Crimisini{N}) where {T,N}
# use all CPU cores in FFT
FFTW.set_num_threads(num_physical_cores())
set_num_threads(cpucores())

# patch size
psize = algo.psize
# patch (or tile) size
tilesize = algo.tilesize

# already filled region
ϕ = .!mask
Expand All @@ -36,55 +36,55 @@ function inpaint_impl(img::AbstractArray{T,N}, mask::BitArray{N}, algo::Crimisin
C = Float64.(ϕ)

# pad arrays
prepad = [(psize[i]-1) ÷ 2 for i=1:N]
postpad = [(psize[i]) ÷ 2 for i=1:N]
prepad = [(tilesize[i]-1) ÷ 2 for i=1:N]
postpad = [(tilesize[i]) ÷ 2 for i=1:N]
padimg = parent(padarray(img, Pad(:symmetric, prepad, postpad)))
ϕ = parent(padarray(ϕ, Fill(true, prepad, postpad)))
C = parent(padarray(C, Fill(0.0, prepad, postpad)))

# fix any invalid pixel value (e.g. NaN) inside of the mask
padimg[isnan.(padimg)] = zero(T)
padimg[isnan.(padimg)] .= zero(T)

# inpainting frontier
δΩ = find(dilate(ϕ) - ϕ)

while !isempty(δΩ)
# update confidence values in frontier
for p in δΩ
c, b = selectpatch((C, ϕ), psize, p)
C[p] = sum(c[b]) / prod(psize)
c, b = selectpatch((C, ϕ), tilesize, p)
C[p] = sum(c[b]) / prod(tilesize)
end

# isophote map
grads = pointgradients(padimg, δΩ)
direc = pointgradients(ϕ, δΩ)
D = vec(abs.(sum(grads.*direc, 2)))
D = vec(abs.(sum(grads.*direc, dims=2)))
D /= maximum(D)

# select patch in frontier
idx = indmax(C[δΩ].*D)
idx = argmax(C[δΩ].*D)
p = δΩ[idx]
ψₚ, bₚ = selectpatch((padimg, ϕ), psize, p)
ψₚ, bₚ = selectpatch((padimg, ϕ), tilesize, p)

# compute distance to all other patches
Δ = convdist(padimg, ψₚ, weights=bₚ)

# only consider patches in filled region
Δ[mask] = Inf
Δ[mask] .= Inf

# find index in padded arrays
idx = indmin(Δ)
idx = argmin(Δ)
sub = ind2sub(size(Δ), idx)
padsub = [sub[i] + (psize[i]-1)÷2 for i in 1:length(psize)]
padsub = [sub[i] + (tilesize[i]-1)÷2 for i in 1:length(tilesize)]
q = sub2ind(size(padimg), padsub...)

# select best candidate
ψᵦ, bᵦ = selectpatch((padimg, ϕ), psize, q)
ψᵦ, bᵦ = selectpatch((padimg, ϕ), tilesize, q)

# paste patch and mark pixels as painted
b = bᵦ .& .!bₚ
ψₚ[b] = ψᵦ[b]
bₚ[b] = true
ψₚ[b] .= ψᵦ[b]
bₚ[b] .= true

# update frontier
δΩ = find(dilate(ϕ) - ϕ)
Expand Down
4 changes: 2 additions & 2 deletions src/pointgradients.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ function pointgradients(img::AbstractArray, points::AbstractVector; method=:ando
end
end

A = zeros(kern)
A = zeros(size(kern))
shape = size(kern)
for (k, p) in enumerate(points)
icenter = CartesianIndex(ind2sub(extent, p))
i1 = CartesianIndex(tuple(ones(Int, ndirs)...))
for ii in CartesianRange(shape)
for ii in CartesianIndices(shape)
A[ii] = padimg[ii + icenter - i1]
end

Expand Down
4 changes: 2 additions & 2 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Perform filtering on `img` with kernel `kern` using the FFT algorithm.
"""
function imfilter_cpu{T<:Real,K<:Real,N}(img::AbstractArray{T,N}, kern::AbstractArray{K,N})
function imfilter_cpu(img::AbstractArray{T,N}, kern::AbstractArray{K,N}) where {T<:Real,K<:Real,N}
imfilter(img, centered(kern), Inner(), Algorithm.FFT())
end

Expand All @@ -28,7 +28,7 @@ function convdist(img::AbstractArray, kern::AbstractArray; weights=nothing)
AB = imfilter_cpu(img, wkern)
= sum(abs2, wkern)

D = abs.(A² - 2AB + B²)
D = abs.(A² .- 2AB .+ B²)

# always return a plain simple array
parent(D)
Expand Down
7 changes: 4 additions & 3 deletions test/REQUIRE
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
GR
Plots
VisualRegressionTests
ColorTypes
TestImages
Plots
VisualRegressionTests
ImageMagick
QuartzImageIO
Binary file modified test/data/Blobs.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified test/data/LightHouse.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 10 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
using ImageInpainting
using ColorTypes
using TestImages
using Plots
using Base.Test
using Plots; gr(size=(800,400),yflip=true,colorbar=false,ticks=false)
using VisualRegressionTests

# plot defaults
gr(size=(800,400), yflip=true, colorbar=false, ticks=false)

# setup GR backend for Travis CI
ENV["GKSwstype"] = "100"
ENV["PLOTS_TEST"] = "true"
using Test, Pkg

# list of maintainers
maintainers = ["juliohm"]
Expand All @@ -20,16 +13,21 @@ istravis = "TRAVIS" ∈ keys(ENV)
ismaintainer = "USER" keys(ENV) && ENV["USER"] maintainers
datadir = joinpath(@__DIR__,"data")

if ismaintainer
Pkg.add("Gtk")
using Gtk
end

# test images
blobs = testimage("blobs")
lighthouse = testimage("lighthouse")

# helper functions
function plot_crimisini_on_array(fname, img, inds, psize)
fimg = Float64.(Gray.(img))
mask = falses(fimg)
mask[inds...] = true
fimg[mask] = NaN
mask = falses(size(fimg))
mask[inds...] .= true
fimg[mask] .= NaN
fimg2 = inpaint(fimg, mask, Crimisini(psize))
plt1 = heatmap(fimg, title="before inpainting")
plt2 = heatmap(fimg2, title="after inpainting")
Expand Down

0 comments on commit a0a2361

Please sign in to comment.