Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1041,40 +1041,9 @@ def server_status():
|
|
| 1041 |
|
| 1042 |
@app.route('/upload', methods=['POST'])
|
| 1043 |
def upload_file():
|
| 1044 |
-
"""Handle file upload and prediction (legacy endpoint)"""
|
| 1045 |
-
|
| 1046 |
-
|
| 1047 |
-
|
| 1048 |
-
file = request.files['file']
|
| 1049 |
-
direction = request.form.get('direction', 'north')
|
| 1050 |
-
task_type = request.form.get('task_type', 'TASK_1')
|
| 1051 |
-
num_obstacles = request.form.get('NUM_OBSTACLES', '0')
|
| 1052 |
-
|
| 1053 |
-
if file.filename == '':
|
| 1054 |
-
return jsonify({'error': 'No selected file'}), 400
|
| 1055 |
-
|
| 1056 |
-
if file:
|
| 1057 |
-
filename = os.path.basename(file.filename)
|
| 1058 |
-
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
| 1059 |
-
file.save(file_path)
|
| 1060 |
-
|
| 1061 |
-
# Process the file and predict
|
| 1062 |
-
class_id, detection_result = process_file(file_path, direction, task_type, filename)
|
| 1063 |
-
|
| 1064 |
-
# Handle NUM_OBSTACLES parameter for obstacle display
|
| 1065 |
-
if num_obstacles and num_obstacles.isdigit() and 1 <= int(num_obstacles) <= 8:
|
| 1066 |
-
save_obstacle_image(detection_result, int(num_obstacles))
|
| 1067 |
-
|
| 1068 |
-
if class_id is not None:
|
| 1069 |
-
return jsonify({
|
| 1070 |
-
'message': 'File successfully uploaded and processed',
|
| 1071 |
-
'predicted_id': class_id,
|
| 1072 |
-
'direction': direction,
|
| 1073 |
-
'task_type': task_type,
|
| 1074 |
-
'num_obstacles': num_obstacles
|
| 1075 |
-
}), 200
|
| 1076 |
-
else:
|
| 1077 |
-
return jsonify({'error': 'Failed to process image'}), 500
|
| 1078 |
|
| 1079 |
@app.route('/image', methods=['POST'])
|
| 1080 |
def image_predict():
|
|
@@ -1095,13 +1064,18 @@ def image_predict():
|
|
| 1095 |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
| 1096 |
file.save(file_path)
|
| 1097 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1098 |
# Try to parse filename format: "<timestamp>_<obstacle_id>_<signal>.jpeg"
|
| 1099 |
# But be flexible with different formats
|
| 1100 |
constituents = file.filename.split("_")
|
| 1101 |
|
| 1102 |
# Default values
|
| 1103 |
obstacle_id = "unknown"
|
| 1104 |
-
signal =
|
| 1105 |
|
| 1106 |
# Try to extract obstacle_id and signal if available
|
| 1107 |
try:
|
|
@@ -1123,11 +1097,14 @@ def image_predict():
|
|
| 1123 |
|
| 1124 |
# Check for optional preference parameter
|
| 1125 |
prefer_close = request.form.get('prefer_close_objects', 'true').lower() == 'true'
|
| 1126 |
-
task_type = request.form.get('task_type', 'TASK_1')
|
| 1127 |
|
| 1128 |
# Process the file and predict
|
| 1129 |
class_id, detection_result = process_file(file_path, signal, task_type, filename)
|
| 1130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1131 |
if detection_result is None:
|
| 1132 |
return jsonify({'error': 'Failed to process image'}), 500
|
| 1133 |
|
|
@@ -1138,20 +1115,32 @@ def image_predict():
|
|
| 1138 |
print(f"Annotated image saved to: {detection_result['marked_image_path']}")
|
| 1139 |
print(f"YOLO txt file saved to: {detection_result.get('txt_file_path', 'N/A')}")
|
| 1140 |
|
| 1141 |
-
#
|
| 1142 |
-
|
| 1143 |
-
|
| 1144 |
-
|
| 1145 |
-
|
| 1146 |
-
|
| 1147 |
-
|
| 1148 |
-
|
| 1149 |
-
|
| 1150 |
-
|
| 1151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1152 |
}
|
| 1153 |
-
|
| 1154 |
-
return jsonify(result)
|
| 1155 |
|
| 1156 |
@app.route('/latest-result')
|
| 1157 |
def get_latest_result():
|
|
@@ -1315,7 +1304,7 @@ if __name__ == '__main__':
|
|
| 1315 |
print(f"Starting Enhanced Image Recognition Server...")
|
| 1316 |
print(f"Web interface available at: http://{HOST}:{PORT}")
|
| 1317 |
print(f"Obstacles display available at: http://{HOST}:{PORT}/obstacles")
|
| 1318 |
-
print(f"API endpoints: /image (
|
| 1319 |
|
| 1320 |
try:
|
| 1321 |
app.run(host=HOST, port=PORT, debug=False)
|
|
|
|
| 1041 |
|
| 1042 |
@app.route('/upload', methods=['POST'])
|
| 1043 |
def upload_file():
|
| 1044 |
+
"""Handle file upload and prediction (legacy endpoint - redirects to /image)"""
|
| 1045 |
+
# Redirect to /image endpoint to avoid code duplication
|
| 1046 |
+
return image_predict()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1047 |
|
| 1048 |
@app.route('/image', methods=['POST'])
|
| 1049 |
def image_predict():
|
|
|
|
| 1064 |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
| 1065 |
file.save(file_path)
|
| 1066 |
|
| 1067 |
+
# Get parameters from both old and new format
|
| 1068 |
+
direction = request.form.get('direction', 'north')
|
| 1069 |
+
task_type = request.form.get('task_type', 'TASK_1')
|
| 1070 |
+
num_obstacles = request.form.get('NUM_OBSTACLES', '0') # Support NUM_OBSTACLES parameter
|
| 1071 |
+
|
| 1072 |
# Try to parse filename format: "<timestamp>_<obstacle_id>_<signal>.jpeg"
|
| 1073 |
# But be flexible with different formats
|
| 1074 |
constituents = file.filename.split("_")
|
| 1075 |
|
| 1076 |
# Default values
|
| 1077 |
obstacle_id = "unknown"
|
| 1078 |
+
signal = direction # Use direction parameter as signal
|
| 1079 |
|
| 1080 |
# Try to extract obstacle_id and signal if available
|
| 1081 |
try:
|
|
|
|
| 1097 |
|
| 1098 |
# Check for optional preference parameter
|
| 1099 |
prefer_close = request.form.get('prefer_close_objects', 'true').lower() == 'true'
|
|
|
|
| 1100 |
|
| 1101 |
# Process the file and predict
|
| 1102 |
class_id, detection_result = process_file(file_path, signal, task_type, filename)
|
| 1103 |
|
| 1104 |
+
# Handle NUM_OBSTACLES parameter for obstacle display
|
| 1105 |
+
if num_obstacles and num_obstacles.isdigit() and 1 <= int(num_obstacles) <= 8:
|
| 1106 |
+
save_obstacle_image(detection_result, int(num_obstacles))
|
| 1107 |
+
|
| 1108 |
if detection_result is None:
|
| 1109 |
return jsonify({'error': 'Failed to process image'}), 500
|
| 1110 |
|
|
|
|
| 1115 |
print(f"Annotated image saved to: {detection_result['marked_image_path']}")
|
| 1116 |
print(f"YOLO txt file saved to: {detection_result.get('txt_file_path', 'N/A')}")
|
| 1117 |
|
| 1118 |
+
# Determine response format based on request context
|
| 1119 |
+
# If it's from the web interface (has direction/task_type), return simple format
|
| 1120 |
+
if direction != 'north' or task_type != 'TASK_1' or num_obstacles != '0':
|
| 1121 |
+
# Web interface format
|
| 1122 |
+
return jsonify({
|
| 1123 |
+
'message': 'File successfully uploaded and processed',
|
| 1124 |
+
'predicted_id': class_id,
|
| 1125 |
+
'direction': direction,
|
| 1126 |
+
'task_type': task_type,
|
| 1127 |
+
'num_obstacles': num_obstacles
|
| 1128 |
+
}), 200
|
| 1129 |
+
else:
|
| 1130 |
+
# Original API format
|
| 1131 |
+
result = {
|
| 1132 |
+
"obstacle_id": obstacle_id,
|
| 1133 |
+
"image_id": image_id,
|
| 1134 |
+
"detection": {
|
| 1135 |
+
"label": detection_result["label"],
|
| 1136 |
+
"confidence": detection_result["confidence"],
|
| 1137 |
+
"bbox_coordinates": detection_result["bbox"],
|
| 1138 |
+
"original_image_path": detection_result.get("original_image_path"),
|
| 1139 |
+
"annotated_image_path": detection_result["marked_image_path"],
|
| 1140 |
+
"txt_file_path": detection_result.get("txt_file_path")
|
| 1141 |
+
}
|
| 1142 |
}
|
| 1143 |
+
return jsonify(result)
|
|
|
|
| 1144 |
|
| 1145 |
@app.route('/latest-result')
|
| 1146 |
def get_latest_result():
|
|
|
|
| 1304 |
print(f"Starting Enhanced Image Recognition Server...")
|
| 1305 |
print(f"Web interface available at: http://{HOST}:{PORT}")
|
| 1306 |
print(f"Obstacles display available at: http://{HOST}:{PORT}/obstacles")
|
| 1307 |
+
print(f"API endpoints: /image (unified endpoint), /upload (legacy redirect)")
|
| 1308 |
|
| 1309 |
try:
|
| 1310 |
app.run(host=HOST, port=PORT, debug=False)
|