Engee 文档
Notebook

无人机仪器读数的可视化

在这个例子中,用于可视化的算法
实现了从无人机传感器记录的飞行数据。

本演示的目的是展示各种可能性
显示数据,包括它们的时间参考。

让我们从CSV文件中读取记录的数据开始。

In [ ]:
using CSV

# Читаем данные из файла data.csv
df_read = CSV.read("$(@__DIR__)/data_drone.csv", DataFrame)

# Проверка первых строк
first(df_read, 5)
Out[0]:
5×3 DataFrame
RowВремяВысотаУгол
Int64Float64Float64
100.0-4.0
213.0-5.0
325.0-3.0
438.0-3.0
5410.0-3.0

正如我们所看到的,该表包含3个字段,时间计数,高度值以及无人机相对于地平线的角度。

In [ ]:
max_idx = 350;
t = df_read.Время[1:max_idx]
heights = df_read.Высота[1:max_idx]
angles = df_read.Угол[1:max_idx]

H = plot(t, heights, title="Высота")
A = plot(t, angles, title="Угол наклона")
plot(H, A, layout=(2, 1), legend=false)
Out[0]:

基于传感器值的可视化,我们
看到无人机逐渐获得高度和
改变了倾斜的角度,盘旋一些
障碍。 我们也看到偏差的波动
相对于地平线,这很可能是由于
事实上,无人机是在大风天气飞行。

接下来,我们将在循环中声明不需要更新的静态变量。

In [ ]:
max_y_h = maximum(heights)+10

# Уравнение единичной окружности
θ = range(0, 2π, length=100)
x_circle = cos.(θ)
y_circle = sin.(θ)
x = [-1, 1]

using Images
# Загрузка изображения дрона
drone_img = load("$(@__DIR__)/drone.jpg") 
Out[0]:
No description has been provided for this image

现在让我们继续讨论数据可视化周期本身。 它大致可以分为三个部分。

  1. 高度显示。 对于每个时间点,高度图绘制为红点。
    轴约束设置为显示当前时间±10秒周围的区域。
    图表标题显示当前高度值和向上/向下箭头,具体取决于高度是增加还是减少。
  2. 间距图。 俯仰图显示了无人机相对于地平线的偏转角度。
    Cosdsind函数用于绘制斜率线。
    航向包含以度为单位的俯仰角值。
  3. 无人机图像旋转可视化,将无人机图像旋转一定角度(俯仰值+90度)。
    Channelview函数将图像转换为便于进一步处理的视图。
    掩模用于去除黑色像素。

结果,所有三个图被组装成形成GIF帧的单个帧。

In [ ]:
@gif for i in 1:length(t)
    ti = t[i]
    ai = angles[i]
    hi = heights[i]
    
    # Высота
    h_plt = scatter([ti], [hi], 
        markershape=:circle, markersize=15, markercolor=:red, framestyle=:box, 
        xlims = (ti-10, ti+10), ylims = (0, max_y_h), 
        legend=false, grid=false, 
        title="Высота: $hi m $((i == 1 || heights[i] > heights[i-1]) ? "↑" : "↓")")

    # Тангаж
    tang = plot([x_circle, (cosd(-ai) .* x)], [y_circle, (sind(-ai) .* x)], 
        linewidth=3, color=:black, framestyle=:none, 
        title="Отклонение: $(ai)°")
    
    # Дрон
    sx,sy = size(drone_img)  3;
    mini_drone = imresize( drone_img, sx, sy );
    rotated_array = channelview(Gray.(imrotate(mini_drone, π*(ai+90)/ 180, fillvalue=oneunit(eltype(mini_drone)), axes(mini_drone))));
    
    dron = plot(framestyle=:none, grid=false, title = "Время: $(t[i])sec")
    # Отображаем повернутое изображение дрона
    heatmap!(
        1:size(rotated_array, 2), 1:size(rotated_array, 1),
        permutedims(rotated_array, (2, 1)),
        colorbar=false, c=:grays
    )
    Tng_Dr = plot(dron, tang, layout = grid(2, 1, heights=[0.8, 0.2]))
    grup = plot(Tng_Dr, h_plt, layout= grid(1, 2, width = [0.75, 0.25]), legend=false)
end
[ Info: Saved animation to /user/start/examples/image_processing/dron/tmp.gif
Out[0]:
No description has been provided for this image

结论

正如我们所看到的,基于GIF结果,
我们得到了一个相当丰富的数据表示
随着时间的推移。 这种方法可以应用
很多时候,特别是在描述真实物理对象的行为的情况下。