File size: 4,085 Bytes
b60c4ae 7226b1b b60c4ae |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import streamlit as st
import pandas as pd
from typing import Tuple
import plotly.graph_objects as go
def create_header():
"""Create the application header"""
st.markdown("""
<div class='custom-header'>
F1 Video Analysis Platform
<div style='font-size: 0.5em; font-weight: 400; margin-top: 10px;'>
Precision Telemetry & Analysis
</div>
</div>
""", unsafe_allow_html=True)
def create_upload_section():
"""Create the video upload section"""
st.markdown("<div class='glassmorphic-container'>", unsafe_allow_html=True)
uploaded_file = st.file_uploader(
"Upload video file",
type=['mp4', 'avi', 'mov'],
help="Upload onboard camera footage for analysis"
)
st.markdown("</div>", unsafe_allow_html=True)
return uploaded_file
def create_frame_selector(total_frames: int) -> Tuple[int, int]:
"""Create frame selection controls with slider and +/- buttons"""
st.markdown("<div class='glassmorphic-container'>", unsafe_allow_html=True)
# Create a slider for frame range selection
start_frame, end_frame = st.select_slider(
"Select Frame Range",
options=range(0, total_frames),
value=(0, total_frames-1),
format_func=lambda x: f"Frame {x}"
)
st.markdown("</div>", unsafe_allow_html=True)
return start_frame, end_frame
def display_results(df: pd.DataFrame):
csv = df.to_csv(index=False)
st.markdown("")
st.markdown("#### Download Results 📥")
st.download_button(
label="Download Results (CSV)",
data=csv,
file_name="Steering_Angle_Results.csv",
mime="text/csv"
)
st.markdown("")
def create_line_chart(df: pd.DataFrame):
"""Create a line chart with the given DataFrame"""
fig = go.Figure()
# Add the main steering angle line
fig.add_trace(go.Scatter(
x=df['time'],
y=df['steering_angle'],
mode='lines',
name='Steering Angle',
line=dict(color='white', width=1),
hovertemplate='<b>Time:</b> %{x}<br><b>Angle:</b> %{y:.2f}°<extra></extra>'
))
# Add reference lines for straight, full right, and full left
fig.add_shape(type="line",
x0=df['time'].min(), y0=0, x1=df['time'].max(), y1=0,
line=dict(color="red", width=2, dash="solid"),
name="Straight (0°)"
)
fig.add_shape(type="line",
x0=df['time'].min(), y0=90, x1=df['time'].max(), y1=90,
line=dict(color="red", width=2, dash="dash"),
name="Full Right (90°)"
)
fig.add_shape(type="line",
x0=df['time'].min(), y0=-90, x1=df['time'].max(), y1=-90,
line=dict(color="red", width=2, dash="dash"),
name="Full Left (-90°)"
)
# Añadir etiquetas a las líneas de referencia
fig.add_annotation(x=df['time'].min(), y=0,
text="Straight (0°)",
showarrow=True,
arrowhead=1,
ax=-40,
ay=-20
)
fig.add_annotation(x=df['time'].min(), y=90,
text="Full Right (90°)",
showarrow=True,
arrowhead=1,
ax=-40,
ay=-20
)
fig.add_annotation(x=df['time'].min(), y=-90,
text="Full Left (-90°)",
showarrow=True,
arrowhead=1,
ax=-40,
ay=20
)
# Configure layout
fig.update_layout(
title="Steering Angle Over Time",
xaxis_title="Time (seconds)",
yaxis_title="Steering Angle (degrees)",
yaxis=dict(range=[-180, 180]),
hovermode="x unified",
legend_title="Legend",
template="plotly_white",
height=500,
margin=dict(l=20, r=20, t=40, b=20)
)
# Add a light gray range for "straight enough" (-10° to 10°)
fig.add_shape(type="rect",
x0=df['time'].min(), y0=-10,
x1=df['time'].max(), y1=10,
fillcolor="lightgray",
opacity=0.2,
layer="below",
line_width=0,
)
# Display the plot in Streamlit
st.plotly_chart(fig, use_container_width=True) |