Engee 文档
Notebook

图像处理

在这个例子中,我们将演示如何使用Engee进行图像处理,分析用于图像处理的单个函数,考虑访问图像的可能性以及它们的处理和表示方法。

让我们从选择所需的函数库开始。

In [ ]:
Pkg.add(["ImageShow"])
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(红、绿、蓝)是一种加色模型,它描述了一种使用三种颜色(通常称为原色)对颜色进行编码以进行颜色再现的方法。

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

检测描绘对象的边界

图像处理中的另一个常见任务是找到对象的边界。 为此,请使用内核。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非常适合图像处理。 鉴于环境的广泛数学功能,我们可以使用自定义函数描述任何任意特定的处理算法。