Update app.py
Browse files
app.py
CHANGED
|
@@ -75,11 +75,10 @@ def custom_nms(preds, iou_threshold=0.3):
|
|
| 75 |
filtered_preds.append(pred)
|
| 76 |
return filtered_preds
|
| 77 |
|
| 78 |
-
# Note the added multiplier parameter.
|
| 79 |
def process_image(job_id, image_path, object_type, multiplier):
|
| 80 |
try:
|
| 81 |
jobs[job_id]['progress'] = 10
|
| 82 |
-
# Load image
|
| 83 |
image = cv2.imread(image_path)
|
| 84 |
if image is None:
|
| 85 |
jobs[job_id]['progress'] = 100
|
|
@@ -97,18 +96,37 @@ def process_image(job_id, image_path, object_type, multiplier):
|
|
| 97 |
jobs[job_id]['progress'] = 100
|
| 98 |
jobs[job_id]['result'] = {"error": "Roboflow model not available."}
|
| 99 |
return
|
| 100 |
-
try:
|
| 101 |
-
results = box_model.predict(image_path, confidence=50, overlap=30).json()
|
| 102 |
-
predictions = results.get("predictions", [])
|
| 103 |
-
except Exception as e:
|
| 104 |
-
jobs[job_id]['progress'] = 100
|
| 105 |
-
jobs[job_id]['result'] = {"error": "Error during Roboflow prediction."}
|
| 106 |
-
return
|
| 107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 108 |
processed_preds = []
|
| 109 |
for prediction in predictions:
|
| 110 |
try:
|
| 111 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
x1 = int(round(x - width / 2))
|
| 113 |
y1 = int(round(y - height / 2))
|
| 114 |
x2 = int(round(x + width / 2))
|
|
@@ -125,10 +143,11 @@ def process_image(job_id, image_path, object_type, multiplier):
|
|
| 125 |
except Exception as e:
|
| 126 |
continue
|
| 127 |
|
|
|
|
| 128 |
box_detections = custom_nms(processed_preds, iou_threshold=0.3)
|
| 129 |
jobs[job_id]['progress'] = 60
|
| 130 |
|
| 131 |
-
# (Optional) Detect ArUco marker for measurement
|
| 132 |
marker_real_width_cm = 10.0
|
| 133 |
try:
|
| 134 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
|
@@ -217,9 +236,11 @@ def process_image(job_id, image_path, object_type, multiplier):
|
|
| 217 |
detection_counts = Counter(det["class"] for det in detection_info)
|
| 218 |
if detection_counts:
|
| 219 |
top_text = ", ".join(f"{cls}: {count}" for cls, count in detection_counts.items())
|
| 220 |
-
|
|
|
|
|
|
|
| 221 |
cv2.rectangle(image, (5, 5), (5 + info_width, 5 + info_height + info_baseline), (0, 255, 0), -1)
|
| 222 |
-
cv2.putText(image, top_text, (5, 5 + info_height), cv2.FONT_HERSHEY_SIMPLEX,
|
| 223 |
|
| 224 |
jobs[job_id]['progress'] = 100
|
| 225 |
retval, buffer = cv2.imencode('.jpg', image)
|
|
@@ -500,7 +521,6 @@ def analyze():
|
|
| 500 |
object_type = request.form.get('object_type', '').lower()
|
| 501 |
if object_type not in {"person", "car", "box"}:
|
| 502 |
return jsonify({"error": "Invalid object type."}), 400
|
| 503 |
-
# Retrieve the multiplier sent from the client
|
| 504 |
try:
|
| 505 |
multiplier = int(request.form.get('multiplier', 1))
|
| 506 |
except ValueError:
|
|
|
|
| 75 |
filtered_preds.append(pred)
|
| 76 |
return filtered_preds
|
| 77 |
|
|
|
|
| 78 |
def process_image(job_id, image_path, object_type, multiplier):
|
| 79 |
try:
|
| 80 |
jobs[job_id]['progress'] = 10
|
| 81 |
+
# Load original image
|
| 82 |
image = cv2.imread(image_path)
|
| 83 |
if image is None:
|
| 84 |
jobs[job_id]['progress'] = 100
|
|
|
|
| 96 |
jobs[job_id]['progress'] = 100
|
| 97 |
jobs[job_id]['result'] = {"error": "Roboflow model not available."}
|
| 98 |
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
|
| 100 |
+
# Upscale the image if it's small so that small boxes become more prominent.
|
| 101 |
+
scale_factor = 1 # default: no upscaling
|
| 102 |
+
if img_width < 1000 or img_height < 1000:
|
| 103 |
+
scale_factor = 2 # adjust factor as needed
|
| 104 |
+
|
| 105 |
+
# Run detection on the appropriate image version.
|
| 106 |
+
if scale_factor > 1:
|
| 107 |
+
upscaled_image = cv2.resize(image, None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_LINEAR)
|
| 108 |
+
temp_path = "upscaled.jpg"
|
| 109 |
+
cv2.imwrite(temp_path, upscaled_image)
|
| 110 |
+
results = box_model.predict(temp_path, confidence=50, overlap=30).json()
|
| 111 |
+
else:
|
| 112 |
+
results = box_model.predict(image_path, confidence=50, overlap=30).json()
|
| 113 |
+
|
| 114 |
+
predictions = results.get("predictions", [])
|
| 115 |
processed_preds = []
|
| 116 |
for prediction in predictions:
|
| 117 |
try:
|
| 118 |
+
if scale_factor > 1:
|
| 119 |
+
# Adjust coordinates from the upscaled image back to the original scale.
|
| 120 |
+
x = prediction["x"] / scale_factor
|
| 121 |
+
y = prediction["y"] / scale_factor
|
| 122 |
+
width = prediction["width"] / scale_factor
|
| 123 |
+
height = prediction["height"] / scale_factor
|
| 124 |
+
else:
|
| 125 |
+
x = prediction["x"]
|
| 126 |
+
y = prediction["y"]
|
| 127 |
+
width = prediction["width"]
|
| 128 |
+
height = prediction["height"]
|
| 129 |
+
|
| 130 |
x1 = int(round(x - width / 2))
|
| 131 |
y1 = int(round(y - height / 2))
|
| 132 |
x2 = int(round(x + width / 2))
|
|
|
|
| 143 |
except Exception as e:
|
| 144 |
continue
|
| 145 |
|
| 146 |
+
# Apply Non-Maximum Suppression.
|
| 147 |
box_detections = custom_nms(processed_preds, iou_threshold=0.3)
|
| 148 |
jobs[job_id]['progress'] = 60
|
| 149 |
|
| 150 |
+
# (Optional) Detect ArUco marker for measurement.
|
| 151 |
marker_real_width_cm = 10.0
|
| 152 |
try:
|
| 153 |
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
|
|
|
|
| 236 |
detection_counts = Counter(det["class"] for det in detection_info)
|
| 237 |
if detection_counts:
|
| 238 |
top_text = ", ".join(f"{cls}: {count}" for cls, count in detection_counts.items())
|
| 239 |
+
summary_font_scale = 1 * multiplier
|
| 240 |
+
summary_thickness = 2 * multiplier
|
| 241 |
+
(info_width, info_height), info_baseline = cv2.getTextSize(top_text, cv2.FONT_HERSHEY_SIMPLEX, summary_font_scale, summary_thickness)
|
| 242 |
cv2.rectangle(image, (5, 5), (5 + info_width, 5 + info_height + info_baseline), (0, 255, 0), -1)
|
| 243 |
+
cv2.putText(image, top_text, (5, 5 + info_height), cv2.FONT_HERSHEY_SIMPLEX, summary_font_scale, (0, 0, 0), summary_thickness)
|
| 244 |
|
| 245 |
jobs[job_id]['progress'] = 100
|
| 246 |
retval, buffer = cv2.imencode('.jpg', image)
|
|
|
|
| 521 |
object_type = request.form.get('object_type', '').lower()
|
| 522 |
if object_type not in {"person", "car", "box"}:
|
| 523 |
return jsonify({"error": "Invalid object type."}), 400
|
|
|
|
| 524 |
try:
|
| 525 |
multiplier = int(request.form.get('multiplier', 1))
|
| 526 |
except ValueError:
|