Update app.py
Browse files
app.py
CHANGED
|
@@ -109,40 +109,40 @@ if canvas_result.image_data is not None:
|
|
| 109 |
st.markdown("---")
|
| 110 |
st.subheader("Prediction Output")
|
| 111 |
|
| 112 |
-
# Preprocess the drawing
|
| 113 |
img = canvas_result.image_data.astype("uint8")
|
| 114 |
img_gray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)
|
| 115 |
img_gray = 255 - img_gray # Invert
|
| 116 |
_, thresh = cv2.threshold(img_gray, 30, 255, cv2.THRESH_BINARY)
|
| 117 |
|
| 118 |
-
#
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
is_multi = nonzero_cols > 40 # simple heuristic
|
| 125 |
|
| 126 |
-
|
| 127 |
st.info("🔢 Detected Multi-Digit Input")
|
| 128 |
-
|
|
|
|
| 129 |
input_img = input_img.reshape(1, 28, 100, 1)
|
| 130 |
|
| 131 |
preds = model_multi.predict(input_img)
|
| 132 |
predicted_digits = [np.argmax(p[0]) for p in preds]
|
| 133 |
predicted_str = ''.join(str(d) for d in predicted_digits)
|
| 134 |
|
| 135 |
-
st.image(
|
| 136 |
st.success(f"🧠 Predicted Number: **{predicted_str}**")
|
| 137 |
-
|
| 138 |
-
else:
|
| 139 |
-
st.info("✏️ Detected Single-Digit Input")
|
| 140 |
-
input_img = resized_single.astype("float32") / 255.0
|
| 141 |
-
input_img = input_img.reshape(1, 28, 28, 1)
|
| 142 |
-
|
| 143 |
-
prediction = model_single.predict(input_img)
|
| 144 |
-
predicted_digit = np.argmax(prediction)
|
| 145 |
-
|
| 146 |
-
st.image(resized_single, caption="Preprocessed 28x28 Image", width=200)
|
| 147 |
-
st.success(f"🧠 Predicted Digit: **{predicted_digit}**")
|
| 148 |
-
|
|
|
|
| 109 |
st.markdown("---")
|
| 110 |
st.subheader("Prediction Output")
|
| 111 |
|
|
|
|
| 112 |
img = canvas_result.image_data.astype("uint8")
|
| 113 |
img_gray = cv2.cvtColor(img, cv2.COLOR_RGBA2GRAY)
|
| 114 |
img_gray = 255 - img_gray # Invert
|
| 115 |
_, thresh = cv2.threshold(img_gray, 30, 255, cv2.THRESH_BINARY)
|
| 116 |
|
| 117 |
+
# Detect bounding box of the drawing
|
| 118 |
+
contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
|
| 119 |
+
if contours:
|
| 120 |
+
x, y, w, h = cv2.boundingRect(np.vstack(contours))
|
| 121 |
+
else:
|
| 122 |
+
w = 0 # fallback
|
| 123 |
+
|
| 124 |
+
# Use width of the drawn content to decide
|
| 125 |
+
if w < 50:
|
| 126 |
+
st.info("✏️ Detected Single-Digit Input")
|
| 127 |
+
resized = cv2.resize(thresh, (28, 28))
|
| 128 |
+
input_img = resized.astype("float32") / 255.0
|
| 129 |
+
input_img = input_img.reshape(1, 28, 28, 1)
|
| 130 |
+
|
| 131 |
+
prediction = model_single.predict(input_img)
|
| 132 |
+
predicted_digit = np.argmax(prediction)
|
| 133 |
|
| 134 |
+
st.image(resized, caption="Preprocessed 28x28 Image", width=200)
|
| 135 |
+
st.success(f"🧠 Predicted Digit: **{predicted_digit}**")
|
|
|
|
| 136 |
|
| 137 |
+
else:
|
| 138 |
st.info("🔢 Detected Multi-Digit Input")
|
| 139 |
+
resized = cv2.resize(thresh, (100, 28))
|
| 140 |
+
input_img = resized.astype("float32") / 255.0
|
| 141 |
input_img = input_img.reshape(1, 28, 100, 1)
|
| 142 |
|
| 143 |
preds = model_multi.predict(input_img)
|
| 144 |
predicted_digits = [np.argmax(p[0]) for p in preds]
|
| 145 |
predicted_str = ''.join(str(d) for d in predicted_digits)
|
| 146 |
|
| 147 |
+
st.image(resized, caption="Preprocessed 100x28 Image", width=250)
|
| 148 |
st.success(f"🧠 Predicted Number: **{predicted_str}**")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|