ParthivM1 commited on
Commit
f240301
·
1 Parent(s): aa9c65b

Video processing added

Browse files
Files changed (1) hide show
  1. app.py +100 -9
app.py CHANGED
@@ -4,7 +4,7 @@ import uuid
4
  from fractions import Fraction
5
  import exifread
6
  import uvicorn
7
- from fastapi import FastAPI, UploadFile, File, HTTPException, Form
8
  from fastapi.middleware.cors import CORSMiddleware
9
  from dotenv import load_dotenv
10
  from ultralytics import YOLO
@@ -26,6 +26,7 @@ app.add_middleware(
26
  allow_headers=["*"]
27
  )
28
 
 
29
  SUPABASE_URL = os.getenv("SUPABASE_URL")
30
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
31
 
@@ -33,6 +34,8 @@ if not SUPABASE_URL or not SUPABASE_KEY:
33
  raise ValueError("Supabase credentials not found. Please set them in your environment variables.")
34
  supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
35
 
 
 
36
  def convert_to_decimal(coord):
37
  if coord and len(coord.values) >= 3:
38
  deg = float(coord.values[0])
@@ -56,6 +59,101 @@ def get_gps_location(file_stream):
56
  return lat, lon
57
  return None, None
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  @app.get("/reports")
60
  async def get_reports():
61
  try:
@@ -68,20 +166,13 @@ async def get_reports():
68
  async def get_report(guid: str):
69
  try:
70
  response = supabase.table("potholes").select("guid, image_name, image_url, location, created_at, location_text").eq("guid", guid).execute()
71
-
72
  if response.data and len(response.data) > 0:
73
  return response.data[0]
74
  else:
75
  raise HTTPException(status_code=404, detail=f"Report with guid {guid} not found.")
76
-
77
  except Exception as e:
78
  raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
79
 
80
- # *** ADD THIS NEW BLOCK ***
81
- @app.get("/")
82
- async def root():
83
- return {"message": "API is running"}
84
-
85
  @app.post("/upload")
86
  async def upload_image(file: UploadFile = File(...), location: str = Form(None)):
87
  image_data = await file.read()
@@ -99,7 +190,6 @@ async def upload_image(file: UploadFile = File(...), location: str = Form(None))
99
  raise HTTPException(status_code=500, detail="Failed to encode annotated image.")
100
 
101
  annotated_image_bytes = buffer.tobytes()
102
-
103
  bucket_name = 'pothole-images'
104
  uuid_path = f"annotated_{uuid.uuid4()}.jpg"
105
 
@@ -139,5 +229,6 @@ async def upload_image(file: UploadFile = File(...), location: str = Form(None))
139
 
140
  return {"message": "Upload successful", "image_url": url, "db_response": response.data}
141
 
 
142
  if __name__ == "__main__":
143
  uvicorn.run(app, port=8000, host="127.0.0.1")
 
4
  from fractions import Fraction
5
  import exifread
6
  import uvicorn
7
+ from fastapi import FastAPI, UploadFile, File, HTTPException, Form, BackgroundTasks
8
  from fastapi.middleware.cors import CORSMiddleware
9
  from dotenv import load_dotenv
10
  from ultralytics import YOLO
 
26
  allow_headers=["*"]
27
  )
28
 
29
+ # Connect to Supabase
30
  SUPABASE_URL = os.getenv("SUPABASE_URL")
31
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
32
 
 
34
  raise ValueError("Supabase credentials not found. Please set them in your environment variables.")
35
  supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
36
 
37
+
38
+
39
  def convert_to_decimal(coord):
40
  if coord and len(coord.values) >= 3:
41
  deg = float(coord.values[0])
 
59
  return lat, lon
60
  return None, None
61
 
62
+
63
+
64
+ def process_video_in_background(video_data: bytes, video_guid: str, filename: str):
65
+
66
+ bucket_name = 'pothole-images'
67
+
68
+ try:
69
+ supabase.table("videos").insert({
70
+ "guid": video_guid,
71
+ "video_name": filename
72
+ }).execute()
73
+ except Exception as e:
74
+ print(f"Database Error on video insert: {str(e)}")
75
+ return
76
+
77
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as temp_video_file:
78
+ temp_video_file.write(video_data)
79
+ temp_path = temp_video_file.name
80
+
81
+ cap = cv2.VideoCapture(temp_path)
82
+ frame_number = 0
83
+
84
+ while cap.isOpened():
85
+ ret, frame = cap.read()
86
+ if not ret:
87
+ break
88
+
89
+ if frame_number % 3 == 0:
90
+ results = model(frame, device='cpu')
91
+
92
+ if len(results[0].boxes) > 0: #
93
+ annotated_frame = results[0].plot()
94
+ is_success, buffer = cv2.imencode(".jpg", annotated_frame)
95
+
96
+ if is_success:
97
+ frame_bytes = buffer.tobytes()
98
+ frame_path = f"{video_guid}/frame_{frame_number}.jpg"
99
+
100
+ try:
101
+ supabase.storage.from_(bucket_name).upload(
102
+ path=frame_path,
103
+ file=frame_bytes,
104
+ file_options={"content-type": "image/jpeg"}
105
+ )
106
+ frame_url = supabase.storage.from_(bucket_name).get_public_url(frame_path)
107
+
108
+ # Save frame information to the 'detected_frames' table
109
+ supabase.table("detected_frames").insert({
110
+ "video_guid": video_guid,
111
+ "frame_image": frame_url,
112
+ "frame_number": frame_number
113
+ }).execute()
114
+ except Exception as e:
115
+ print(f"Error saving frame {frame_number}: {str(e)}")
116
+
117
+ frame_number += 1
118
+
119
+ cap.release()
120
+ os.remove(temp_path)
121
+ print(f"Finished processing video {video_guid}")
122
+
123
+
124
+
125
+ @app.get("/")
126
+ async def root():
127
+ return {"message": "API is running"}
128
+
129
+ @app.post("/upload_video")
130
+ async def upload_video(background_tasks: BackgroundTasks, file: UploadFile = File(...)):
131
+ if not file.content_type.startswith('video/'):
132
+ raise HTTPException(status_code=400, detail="File is not a video.")
133
+
134
+ video_data = await file.read()
135
+ video_guid = str(uuid.uuid4())
136
+
137
+ background_tasks.add_task(process_video_in_background, video_data, video_guid, file.filename)
138
+
139
+ return {"message": "Video upload successful. Processing has started.", "video_guid": video_guid}
140
+
141
+ @app.get("/video_report/{guid}")
142
+ async def get_video_report(guid: str):
143
+ try:
144
+ video_response = supabase.table("videos").select("*").eq("guid", guid).single().execute()
145
+ frames_response = supabase.table("detected_frames").select("*").eq("video_guid", guid).order("frame_number").execute()
146
+
147
+ if not video_response.data:
148
+ raise HTTPException(status_code=404, detail="Video report not found")
149
+
150
+ return {
151
+ "video_info": video_response.data,
152
+ "detected_frames": frames_response.data
153
+ }
154
+ except Exception as e:
155
+ raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
156
+
157
  @app.get("/reports")
158
  async def get_reports():
159
  try:
 
166
  async def get_report(guid: str):
167
  try:
168
  response = supabase.table("potholes").select("guid, image_name, image_url, location, created_at, location_text").eq("guid", guid).execute()
 
169
  if response.data and len(response.data) > 0:
170
  return response.data[0]
171
  else:
172
  raise HTTPException(status_code=404, detail=f"Report with guid {guid} not found.")
 
173
  except Exception as e:
174
  raise HTTPException(status_code=500, detail=f"Database Error: {str(e)}")
175
 
 
 
 
 
 
176
  @app.post("/upload")
177
  async def upload_image(file: UploadFile = File(...), location: str = Form(None)):
178
  image_data = await file.read()
 
190
  raise HTTPException(status_code=500, detail="Failed to encode annotated image.")
191
 
192
  annotated_image_bytes = buffer.tobytes()
 
193
  bucket_name = 'pothole-images'
194
  uuid_path = f"annotated_{uuid.uuid4()}.jpg"
195
 
 
229
 
230
  return {"message": "Upload successful", "image_url": url, "db_response": response.data}
231
 
232
+
233
  if __name__ == "__main__":
234
  uvicorn.run(app, port=8000, host="127.0.0.1")