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

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

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

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

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

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

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

I = load("/user/start/examples/image_processing/processing_methods/IMG_001.jpg")

interactive-scripts/images/image_processing_Processing_methods/b8ab774841b1aaed62e033a26da97c515f26d8d2

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

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

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

function brightness(pixel)
    arr = pixel.r + pixel.g + pixel.b;
    return sum(arr) / length(arr)
end
brightness (generic function with 1 method)

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

Ibright = brightness.(I)
simshow(Ibright)

interactive-scripts/images/image_processing_Processing_methods/70eff9ade8d4aa4bf31bb768641815ae04de5611

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

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

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

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

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

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 и присвоив первому измерению матрицы значения единицы в точках интереса.

img_copy = RGB.(Ibright)
img_copy[corners] .= RGB(1.0, 0.0, 0.0)

interactive-scripts/images/image_processing_Processing_methods/11b019a5ad73307db0a2fe296ff96f395c643aaf

┌ 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

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

simshow(img_copy)

interactive-scripts/images/image_processing_Processing_methods/cdf3226a1f8220516a0616eb6a72ed56e61c9c55

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

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

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
find_energy (generic function with 1 method)

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

simshow(find_energy(I))

interactive-scripts/images/image_processing_Processing_methods/d3fe54bdf4d6a88036b81e6edeedadf1fe142ef9

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

Вывод

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