In this example, let's look at how to restore a blurred image by solving an optimization problem using the linear least squares method with constraints.
We will attach the necessary libraries.
neededLibs = ["FileIO", "Images", "ImageShow", "LinearAlgebra", "SparseArrays", "JuMP", "Ipopt", "Printf"]
for lib in neededLibs
try
eval(Meta.parse("using $lib"))
catch ex
Pkg.add(lib)
eval(Meta.parse("using $lib"))
end
end
There is a photo showing the Engee booth.
P = load("image.jpg")
P = Gray.(P)
P = Float64.(channelview(P))
m, n = size(P)
mn = m * n
p1 = heatmap(reverse(P, dims=1), aspect_ratio=:equal, color=:grays, axis=false, colorbar=false, title="Исходное изображение $m x $n ($mn пикселей)")
display(p1)
The task is to take a blurred version of this photo and try to restore its clarity. The original image is black and white, which means that it can be represented as a matrix.
Let's simulate the effect of vertical motion blur by averaging each pixel with 15 pixels at the top and bottom. Let's construct a sparse matrix D to perform blurring by matrix multiplication.
blur = 15
weight = 1/(2*blur + 1)
mindex = Int[]
nindex = Int[]
values = Float64[]
for i = 1:mn
push!(mindex, i)
push!(nindex, i)
push!(values, weight)
for k = 1:blur
if i + k <= mn
push!(mindex, i + k)
push!(nindex, i)
push!(values, weight)
end
if i - k >= 1
push!(mindex, i - k)
push!(nindex, i)
push!(values, weight)
end
end
end
D = sparse(mindex, nindex, values, mn, mn);
Let's display the first 30×30 elements of the matrix D.
println("\nОператор размытия (первые 30x30 элементов):")
for i in 1:30
for j in 1:30
if abs(i-j) <= blur
print("x ")
else
print("0 ")
end
end
println("...")
end
println("..."^10)
Multiplying the matrix D by the original image transformed into a column vector, we get a blurred image.
G_vec = D * vec(P)
G = reshape(G_vec, m, n)
p2 = heatmap(reverse(G, dims=1), aspect_ratio=:equal, color=:grays, axis=false, colorbar=false, title="Blurred image")
display(p2)
The image has become blurry, and the labels are unreadable.
To restore clarity, assume that the blur operator is known.
The simplest approach is to solve the least squares problem for
In this problem, the blur matrix
model = Model(Ipopt.Optimizer)
set_silent(model)
@variable(model, 0 <= x[1:mn] <= 1)
@expression(model, expr, D * x - G_vec)
@objective(model, Min, expr' * expr)
Let's solve the optimization problem.
optimize!(model)
x_val = value.(x)
xpic = reshape(x_val, m, n)
We will display the restored image.
println("\nВосстановленное изображение")
p3 = heatmap(reverse(xpic, dims=1), aspect_ratio=:equal, color=:grays, axis=false, colorbar=false, title="The restored image")
display(p3)
By applying the optimization problem solution, we were able to almost perfectly restore the original image to such an extent that the inscriptions on it became distinguishable and readable again.
In this paper, the practical task of image restoration was considered using the example of eliminating vertical blurring. The experimental results convincingly demonstrate the effectiveness of the linear least squares method with constraints for solving inverse problems in image processing, clearly demonstrating how abstract mathematical concepts find concrete application in solving practical problems of digital visual information processing.