Categories: Julia

Inpainting an image in Julia

For our final article of the month, we’ll be showing you how easy it is to inpaint images in Julia. This might be the shortest Julia article here on MLG, but I bet you that its the most interesting Julia article here.

We’ll be using the package ImageInpainting.jl, which is a part of the larger Images.jl package here. We’ll also use ImageDraw.jl from that package in order to draw the masks.

Here I’ve kept the image in a folder named Tempy in the root of my C-drive.

image=load("C:\\Tempy\\2077.jpg")

For a refresher, remember that the way inpainting works is by calculating color gradients, and then interpolating them in the masked region.

But before we’re able to use the inpaint, function, we must convert our image into an array

We’re going to take the following picture:

And remove that logo in the bottom left. So, first we define a masking by drawing a circle over the area we want to inpaint:

masking=draw(image,Ellipse(CirclePointRadius(140,666,90)))

We then compare this to the original image to get us a mask:

Now that you know the gameplan, let’s put it into action.

As this is a rudimentary library, we’re going to have separate the image into its constituent channels, inpaint, and then reconstitute the image. So, first lets split the image:

split=channelview(image);

Now we have separated the three channels(you can zoom in to see the code too):

Our previous mask is perfectly fine as we only want to retouch that area in each channel. So we carry out the inpainting on each channel:

r=inpaint(convert(Array{Float64},(Gray.(split[1,:,:]))),mask,Criminisi(100,10))
g=inpaint(convert(Array{Float64},(Gray.(split[2,:,:]))),mask,Criminisi(150,50))
b=inpaint(convert(Array{Float64},(Gray.(split[3,:,:]))),mask,Criminisi(99,90))

Note that you’ll want to tweak how much area is used by the diffusion equation by tweaking the parameters you pass to Criminisi for each channel. Finally we reconstitute the image from the three channels, and display it:

colorview(RGB,StackedView(r,g,b))

Getting the following result:

Its not the best job ever, but I’m happy enough with it. If you want to better this, I’d recommend you to choose as small a mask as possible, and iterate the painted image into the following function recursively.

Note that we talked at length about all the steps, else they can all be done within less than 5 lines:

function doIt(image)
 split=channelview(image);
 r=inpaint(convert(Array{Float64},(Gray.(split[1,:,:]))),mask,Criminisi(10,10))
 g=inpaint(convert(Array{Float64},(Gray.(split[2,:,:]))),mask,Criminisi(100,100))
 b=inpaint(convert(Array{Float64},(Gray.(split[3,:,:]))),mask,Criminisi(100,100))
 return colorview(RGB,StackedView(r,g,b))
 end

you can find the notebook here:

https://github.com/mathmetal/Misc/blob/master/MLG/Inpaint.jl
Editorial Staff

Share
Published by
Editorial Staff

Recent Posts

MapReduce Algorithm

In this tutorial, we will focus on MapReduce Algorithm, its working, example, Word Count Problem,…

8 months ago

Linear Programming using Pyomo

Learn how to use Pyomo Packare to solve linear programming problems. In recent years, with…

1 year ago

Networking and Professional Development for Machine Learning Careers in the USA

In today's rapidly evolving technological landscape, machine learning has emerged as a transformative discipline, revolutionizing…

1 year ago

Predicting Employee Churn in Python

Analyze employee churn, Why employees are leaving the company, and How to predict, who will…

2 years ago

Airflow Operators

Airflow operators are core components of any workflow defined in airflow. The operator represents a…

2 years ago

MLOps Tutorial

Machine Learning Operations (MLOps) is a multi-disciplinary field that combines machine learning and software development…

2 years ago