From 89d2ae15c254ae983f22ebc6f007f1134c13452e Mon Sep 17 00:00:00 2001 From: Shemanti Pal <116779027+Shemantipal@users.noreply.github.com> Date: Sun, 11 Aug 2024 15:41:24 +0530 Subject: [PATCH] title UI changes --- app.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 28 deletions(-) diff --git a/app.py b/app.py index 287e541..18f3f7d 100644 --- a/app.py +++ b/app.py @@ -2,6 +2,7 @@ import cv2 import os import numpy as np +import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from collections import defaultdict @@ -16,6 +17,9 @@ cap = cv2.VideoCapture(video_path) net = cv2.dnn.readNetFromCaffe(prototxt_path, model_path) +# Load the store data +store_data = pd.read_csv('store.csv') + def detect_people(frame): h, w = frame.shape[:2] blob = cv2.dnn.blobFromImage(cv2.resize(frame, (300, 300)), 0.007843, (300, 300), 127.5) @@ -58,45 +62,129 @@ def calculate_footfall(frame, people): return footfall def plot_heatmap(footfall): - plt.figure(figsize=(10, 4)) - sns.heatmap(footfall, cmap='hot', annot=True) + plt.figure(figsize=(8, 6)) + sns.heatmap(footfall, cmap='YlOrRd', annot=True, fmt='.0f', cbar_kws={'label': 'Foot Traffic'}) plt.title('Customer Footfall Heatmap') - plt.xlabel('Grid X') - plt.ylabel('Grid Y') + plt.xlabel('Store Width') + plt.ylabel('Store Length') return plt.gcf() def generate_report(footfall): deadspots = [] threshold = np.percentile(footfall, 25) # Define a threshold for low footfall areas + grid_size = footfall.shape + items_per_grid = len(store_data) // (grid_size[0] * grid_size[1]) + + report_data = [] + for i in range(footfall.shape[0]): for j in range(footfall.shape[1]): if footfall[i, j] <= threshold: deadspots.append((i, j)) - - report = f"Total Grids: {footfall.size}\n" - report += f"Deadspots Identified: {len(deadspots)}\n\n" - report += "Deadspots Locations (Grid Y, Grid X):\n" - for (y, x) in deadspots: - report += f"- Grid Y: {y + 1}, Grid X: {x + 1}\n" - - return report + start_index = (i * grid_size[1] + j) * items_per_grid + end_index = start_index + items_per_grid + items = store_data.iloc[start_index:end_index] + for _, item in items.iterrows(): + report_data.append({ + "Grid Location": f"Y: {i+1}, X: {j+1}", + "Product": item['Product'], + "Brand": item['Brand'], + "Weekly Sales": f"${item['Weekly Sales']}" + }) + + report_df = pd.DataFrame(report_data) + + summary = f"Total Grids: {footfall.size}\n" + summary += f"Deadspots Identified: {len(deadspots)}" + + return summary, report_df + +def get_best_selling_products_with_brands(category): + category_data = store_data[store_data['Category'] == category] + best_selling = category_data.groupby(['Product', 'Brand'])['Weekly Sales'].sum().sort_values(ascending=False).head(5) + return best_selling + +def plot_best_selling_products_with_brands(data): + plt.figure(figsize=(12, 6)) + ax = data.plot(kind='bar', color='skyblue', edgecolor='navy') + plt.title('Top 5 Best-Selling Products with Brands', fontsize=16) + plt.xlabel('Product (Brand)', fontsize=12) + plt.ylabel('Total Weekly Sales ($)', fontsize=12) + plt.xticks(rotation=45, ha='right') + + # Modify x-axis labels to show Product (Brand) + labels = [f"{product} ({brand})" for product, brand in data.index] + ax.set_xticklabels(labels) + + # Add value labels on top of each bar + for i, v in enumerate(data): + ax.text(i, v, f'${v:,.0f}', ha='center', va='bottom') + + plt.tight_layout() + return plt.gcf() def run_app(): - st.title("Store Deadspot Detection") - - # Layout with two columns - col1, col2 = st.columns(2) - - with col1: - st.subheader("Video Feed") - frame_placeholder = st.empty() - st.subheader("Customer Footfall Heatmap") - heatmap_placeholder = st.empty() - - with col2: + st.set_page_config(layout="wide", page_title="Store Analysis Dashboard") + + # Apply custom CSS for layout and styling + st.markdown(""" + + """, unsafe_allow_html=True) + + st.markdown('
Store Analysis Dashboard
', unsafe_allow_html=True) + + # Create tabs for different sections + tab1, tab2, tab3 = st.tabs(["Live Feed & Heatmap", "Category Analysis", "Deadspots Report"]) + + with tab1: + col1, col2 = st.columns(2) + + with col1: + st.subheader("Live Video Feed") + frame_placeholder = st.empty() + + with col2: + st.subheader("Customer Footfall Heatmap") + heatmap_placeholder = st.empty() + + with tab2: + st.subheader("Category Analysis") + categories = store_data['Category'].unique() + selected_category = st.selectbox("Select a category", categories) + best_selling = get_best_selling_products_with_brands(selected_category) + + st.pyplot(plot_best_selling_products_with_brands(best_selling)) + + with tab3: st.subheader("Deadspots Report") - report_placeholder = st.empty() + col3, col4 = st.columns([1, 3]) + + with col3: + summary_placeholder = st.empty() + + with col4: + table_placeholder = st.empty() # Start the video processing while cap.isOpened(): @@ -109,18 +197,23 @@ def run_app(): frame_with_boxes = draw_bounding_boxes(frame, people) # Update the video feed - frame_placeholder.image(frame_with_boxes, channels="BGR") + frame_placeholder.image(frame_with_boxes, channels="BGR", use_column_width=True) # Calculate and display the heatmap footfall = calculate_footfall(frame, people) heatmap_placeholder.pyplot(plot_heatmap(footfall)) # Generate and display the report - report = generate_report(footfall) - report_placeholder.text(report) + summary, report_df = generate_report(footfall) + summary_placeholder.text(summary) + table_placeholder.dataframe(report_df) + + # Add a short pause to reduce CPU usage + plt.pause(0.1) # Release the video capture cap.release() if __name__ == "__main__": run_app() +