Документация Engee
Notebook

Обработка изображений

В данном примере мы продемонстируем, как применять Engee для обработки изображений, разберём отдельные функции для обработки изображений, рассмотрим возможности обращения к изображениям и методы их обработки и представления.

Начнем с выбора требуемых библиотек функций.

In [ ]:
using Images # Библиотека обработки изображений
using ImageShow # Библиотека отрисовки изображений

Загрузка изображения

Функция load позволяет сохранить изображения в рабочие пространства в виде матрицы.

In [ ]:
I = load("/user/start/examples/image_processing/processing_methods/IMG_001.jpg")
Out[0]:
No description has been provided for this image

Приведение RGB к оттенкам серого

Создадим пользовательскую функцию расчёта средних значений для суммы измерений трёхмерной матрицы формата RGB.

RGB (red, green, blue) — аддитивная цветовая модель, описывающая способ кодирования цвета для цветовоспроизведения с помощью трёх цветов, которые принято называть основными.

In [ ]:
function brightness(pixel)
    arr = pixel.r + pixel.g + pixel.b;
    return sum(arr) / length(arr)
end
Out[0]:
brightness (generic function with 1 method)

После определения функции вызовем её и выполним отрисовку изображения.

In [ ]:
Ibright = brightness.(I)
simshow(Ibright)
Out[0]:
No description has been provided for this image

Как видно из рисунка выше, мы привели изображения к оттенкам серого цвета.

Обнаружение углов

Метод обнаружения углов пытается выявить точки на изображении, которые имеют четко определенное положение и могут быть надежно обозначены на нескольких изображениях одной и той же сцены. Очень часто эти точки лежат по углам или краям объектов изображения — отсюда и название метода.

Обнаружение углов полезно в ряде задач компьютерного зрения — регистрация изображений, обнаружение движения и панорамное сшивание. Метод основан на том, что, если расположение одних и тех же точек известно на двух разных изображениях, это дает возможности для выравнивания этих изображений.

Для обнаружения углов воспользуемся функцией imcorner, которая имеет один дополнительный показатель, — это параметр порогового процента обнаружения точек интереса.

In [ ]:
corners = imcorner(Ibright, Percentile(98.5));
┌ Error: handle_connection handler error
│   exception = (Base.IOError("write: broken pipe (EPIPE)", -32), Base.StackTraces.StackFrame[uv_write(s::TCPSocket, p::Ptr{UInt8}, n::UInt64) at stream.jl:1064, unsafe_write(s::TCPSocket, p::Ptr{UInt8}, n::UInt64) at stream.jl:1118, unsafe_write(c::HTTP.ConnectionPool.Connection, p::Ptr{UInt8}, n::UInt64) at ConnectionPool.jl:106, write(io::HTTP.ConnectionPool.Connection, s::String) at io.jl:244, write at io.jl:676 [inlined], unsafe_write(http::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Connection}, p::Ptr{UInt8}, n::UInt64) at Streams.jl:96, write(io::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Connection}, s::String) at io.jl:244, write(io::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Connection}, s::Base.CodeUnits{UInt8, String}) at basic.jl:758, (::HTTP.Handlers.var"#1#2"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}})(stream::HTTP.Streams.Stream{HTTP.Messages.Request, HTTP.ConnectionPool.Connection}) at Handlers.jl:61, #invokelatest#2 at essentials.jl:729 [inlined], invokelatest at essentials.jl:726 [inlined], handle_connection(f::Function, c::HTTP.ConnectionPool.Connection, listener::HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, readtimeout::Int64, access_log::Nothing) at Servers.jl:447, (::HTTP.Servers.var"#16#17"{HTTP.Handlers.var"#1#2"{HTTP.Handlers.Router{typeof(HTTP.Handlers.default404), typeof(HTTP.Handlers.default405), Nothing}}, HTTP.Servers.Listener{Nothing, Sockets.TCPServer}, Set{HTTP.ConnectionPool.Connection}, Int64, Nothing, Base.Semaphore, HTTP.ConnectionPool.Connection})() at task.jl:484])
└ @ HTTP.Servers /root/.julia/packages/HTTP/Kxa7P/src/Servers.jl:461

После обнаружения точек интереса отметим их красным цветом, переведя изображения в оттенках серого в RGB и присвоив первому измерению матрицы значения единицы в точках интереса.

In [ ]:
img_copy = RGB.(Ibright)
img_copy[corners] .= RGB(1.0, 0.0, 0.0)
Out[0]:
No description has been provided for this image
┌ Warning: Output swatches are reduced due to the large size (1×29420).
│ Load the ImageShow package for large images.
└ @ Colors /root/.julia/packages/Colors/mIuXl/src/display.jl:159

Как мы видим, углы были найдены на самых контрастных объектах изображения. В данном случае это облака и море.

In [ ]:
simshow(img_copy)
Out[0]:
No description has been provided for this image

Обнаружение границ изображенных объектов

Ещё одной частой задачей при обработке изображений является нахождение границ объектов. Для этого воспользуемся функцией Kernel.sobel, которая позволяет перевести изображения в частотную область. Далее представлена пользовательская функция обнаружения границ.

In [ ]:
function find_energy(image)
    energy_y = imfilter(brightness.(image), Kernel.sobel()[1])
    energy_x = imfilter(brightness.(image), Kernel.sobel()[2])    
    return sqrt.(energy_x.^2 + energy_y.^2)
end
Out[0]:
find_energy (generic function with 1 method)

Следуюющим шагом применим пользовательскую функцию обнаружения границ объектов к исходному изображению и отобразим результат обработки изображения.

In [ ]:
simshow(find_energy(I))
Out[0]:
No description has been provided for this image

По результатам обработки мы однозначно можем определить границы каждого объекта на изображении, и эти данные впоследствии могут быть применены к дальнейшей обработке изображения.

Вывод

Как показал наш пример работы с картиной, Engee отлично подходит для обработки изображений. Учитывая обширную математическую функциональность среды, мы можем описать любой сколь угодно специфический алгоритм обработки, используя пользовательские функции.