sparsh007/Azureintegration
0
1import gradio as gr2from azure.storage.blob import BlobServiceClient3import os4import cv25import tempfile6from ultralytics import YOLO7import logging8import time9 10# Configure logging11logging.basicConfig(level=logging.INFO)12logger = logging.getLogger(__name__)13 14# Azure Configuration15AZURE_CONFIG = {16 "account_name": "assentian",17 "sas_token": "sv=2024-11-04&ss=bfqt&srt=sco&sp=rwdlacupiytfx&se=2025-04-30T04:25:22Z&st=2025-04-16T20:25:22Z&spr=https&sig=HYrJBoOYc4PRe%2BoqBMl%2FmoL5Kz4ZYugbTLuEh63sbeo%3D",18 "container_name": "logs",19 "max_size_mb": 50020}21 22# YOLO Model Configuration23MODEL_CONFIG = {24 "model_path": "./best_yolov11 (1).pt",25 "conf_threshold": 0.5,26 "frame_skip": 0 # Process every frame for testing27}28 29# Initialize YOLO Model30try:31 MODEL = YOLO(MODEL_CONFIG["model_path"])32 logger.info(f"Loaded YOLO model: {MODEL_CONFIG['model_path']}")33except Exception as e:34 logger.error(f"Model loading failed: {e}")35 raise36 37def get_azure_client():38 return BlobServiceClient(39 account_url=f"https://{AZURE_CONFIG['account_name']}.blob.core.windows.net",40 credential=AZURE_CONFIG['sas_token']41 )42 43def list_videos():44 try:45 client = get_azure_client()46 container = client.get_container_client(AZURE_CONFIG['container_name'])47 return [48 blob.name for blob in container.list_blobs() 49 if blob.name.lower().endswith(".mp4")50 ]51 except Exception as e:52 logger.error(f"Error listing videos: {e}")53 return []54 55def validate_video_size(blob_client):56 props = blob_client.get_blob_properties()57 size_mb = props.size / (1024 * 1024)58 if size_mb > AZURE_CONFIG["max_size_mb"]:59 raise ValueError(f"Video exceeds {AZURE_CONFIG['max_size_mb']}MB limit")60 61def download_video(blob_name):62 try:63 client = get_azure_client()64 blob = client.get_blob_client(65 container=AZURE_CONFIG['container_name'],66 blob=blob_name67 )68 69 validate_video_size(blob)70 71 with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as f:72 download_stream = blob.download_blob()73 for chunk in download_stream.chunks():74 f.write(chunk)75 return f.name76 except Exception as e:77 logger.error(f"Download failed: {e}")78 return None79 80def process_video(input_path, progress=gr.Progress()):81 try:82 if not input_path or not os.path.exists(input_path):83 raise ValueError("Invalid input video path")84 85 cap = cv2.VideoCapture(input_path)86 if not cap.isOpened():87 raise RuntimeError("Failed to open video file")88 89 # Get video properties with 200 frame limit90 original_frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))91 frame_count = min(original_frame_count, 200) # TESTING LIMIT92 fps = cap.get(cv2.CAP_PROP_FPS)93 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))94 height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))95 96 # Output setup97 output_file = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4").name98 writer = cv2.VideoWriter(output_file, 99 cv2.VideoWriter_fourcc(*'mp4v'), 100 fps, 101 (width, height))102 103 processed_frames = 0104 total_processed = 0105 106 progress(0, desc="Processing first 200 frames...")107 start_time = time.time()108 109 while cap.isOpened() and total_processed < 200: # FRAME LIMIT110 ret, frame = cap.read()111 if not ret:112 break113 114 # Process every frame (frame_skip = 0)115 results = MODEL(frame, verbose=False)116 class_counts = {}117 118 for result in results:119 for box in result.boxes:120 conf = box.conf.item()121 if conf < MODEL_CONFIG["conf_threshold"]:122 continue123 124 x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())125 class_id = int(box.cls.item())126 class_name = MODEL.names[class_id]127 128 # Draw bounding box129 cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)130 131 # Create label132 label = f"{class_name} {conf:.2f}"133 cv2.putText(frame, label, (x1, y1 - 10),134 cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2)135 136 # Write frame to output137 writer.write(frame)138 processed_frames += 1139 total_processed += 1140 141 # Update progress every frame142 if processed_frames % 5 == 0:143 progress(processed_frames / frame_count, 144 desc=f"Processed {processed_frames}/200 frames")145 146 # Calculate statistics147 duration = time.time() - start_time148 fps = processed_frames / duration if duration > 0 else 0149 150 # Cleanup151 cap.release()152 writer.release()153 os.remove(input_path)154 155 return output_file, f"Processed {processed_frames} frames in {duration:.1f}s ({fps:.1f} FPS)"156 157 except Exception as e:158 logger.error(f"Processing failed: {e}")159 return None, f"Error: {str(e)}"160 161# Gradio Interface162with gr.Blocks(theme=gr.themes.Soft(), title="PRISM Video Analyzer") as app:163 gr.Markdown("# ๐๏ธ PRISM Site Diary - Video Analysis (TEST MODE: 200 Frames)")164 165 with gr.Row():166 with gr.Column(scale=1):167 gr.Markdown("## Video Selection")168 video_select = gr.Dropdown(169 label="Available Videos",170 choices=list_videos(),171 filterable=False172 )173 refresh_btn = gr.Button("๐ Refresh List", variant="secondary")174 process_btn = gr.Button("๐ Process First 200 Frames", variant="primary")175 176 with gr.Column(scale=2):177 gr.Markdown("## Results")178 video_output = gr.Video(179 label="Processed Video",180 format="mp4",181 interactive=False182 )183 status = gr.Textbox(184 label="Status",185 value="Ready to process first 200 frames",186 interactive=False187 )188 189 def refresh_video_list():190 return gr.Dropdown.update(choices=list_videos())191 192 def handle_video_processing(blob_name):193 if not blob_name:194 return None, "No video selected!"195 196 try:197 local_path = download_video(blob_name)198 if not local_path:199 return None, "Download failed"200 201 result, message = process_video(local_path)202 return result, message203 204 except Exception as e:205 logger.error(f"Processing error: {e}")206 return None, f"Error: {str(e)}"207 208 refresh_btn.click(refresh_video_list, outputs=video_select)209 process_btn.click(210 handle_video_processing,211 inputs=video_select,212 outputs=[video_output, status],213 queue=True214 )215 216if __name__ == "__main__":217 app.launch(218 server_name="0.0.0.0",219 server_port=7860,220 show_error=True221 )