Spaces:
Runtime error
Runtime error
Updated UI, files and resources
Browse files- src/config.py +3 -3
- src/models/handwritten_name_ocr_model.pth +3 -0
- src/streamlit_app.py +32 -34
src/config.py
CHANGED
@@ -7,8 +7,8 @@ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
7 |
DATA_DIR = os.path.join(BASE_DIR, 'data')
|
8 |
MODELS_DIR = os.path.join(BASE_DIR, 'models')
|
9 |
|
10 |
-
TRAIN_IMAGES_DIR = os.path.join(DATA_DIR, 'images')
|
11 |
-
TEST_IMAGES_DIR = os.path.join(DATA_DIR, 'images')
|
12 |
|
13 |
TRAIN_CSV_PATH = os.path.join(DATA_DIR, 'train.csv')
|
14 |
TEST_CSV_PATH = os.path.join(DATA_DIR, 'test.csv')
|
@@ -35,7 +35,7 @@ print(f"Blank Symbol: '{BLANK_TOKEN_SYMBOL}' at index {BLANK_TOKEN}")
|
|
35 |
|
36 |
# --- Image Preprocessing Parameters ---
|
37 |
IMG_HEIGHT = 32 # Target height for all input images to the model
|
38 |
-
MAX_IMG_WIDTH =
|
39 |
|
40 |
# --- Training Parameters ---
|
41 |
BATCH_SIZE = 10
|
|
|
7 |
DATA_DIR = os.path.join(BASE_DIR, 'data')
|
8 |
MODELS_DIR = os.path.join(BASE_DIR, 'models')
|
9 |
|
10 |
+
TRAIN_IMAGES_DIR = os.path.join(DATA_DIR, 'images','train')
|
11 |
+
TEST_IMAGES_DIR = os.path.join(DATA_DIR, 'images','test')
|
12 |
|
13 |
TRAIN_CSV_PATH = os.path.join(DATA_DIR, 'train.csv')
|
14 |
TEST_CSV_PATH = os.path.join(DATA_DIR, 'test.csv')
|
|
|
35 |
|
36 |
# --- Image Preprocessing Parameters ---
|
37 |
IMG_HEIGHT = 32 # Target height for all input images to the model
|
38 |
+
MAX_IMG_WIDTH = 720 # Adjust this value based on your typical image widths and available RAM
|
39 |
|
40 |
# --- Training Parameters ---
|
41 |
BATCH_SIZE = 10
|
src/models/handwritten_name_ocr_model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:a8625e259aa257335a787b54bbc9325fdf4fe46d6b67debb4f50665fe2c47ad8
|
3 |
+
size 21382549
|
src/streamlit_app.py
CHANGED
@@ -79,7 +79,7 @@ with tab1:
|
|
79 |
st.markdown("""
|
80 |
**[π Project Documentation ](https://drive.google.com/file/d/1HBrQT_UnzNLdEsouW9wMk4alAeCsQxZb/view?usp=sharing)**
|
81 |
|
82 |
-
**[ποΈ Demo Presentation ](https://drive.google.com/
|
83 |
|
84 |
**[π Dataset (from Kaggle)](https://www.kaggle.com/datasets/landlord/handwriting-recognition)**
|
85 |
|
@@ -88,43 +88,41 @@ with tab1:
|
|
88 |
|
89 |
# --- Tab 2: Predict Name (Main Content: Prediction Section) ---
|
90 |
with tab2:
|
91 |
-
|
92 |
-
st.markdown("Upload a clear image of a single handwritten name or word for recognition.")
|
93 |
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
else:
|
97 |
-
|
98 |
-
|
99 |
-
if uploaded_file is not None:
|
100 |
-
try:
|
101 |
-
image_pil = Image.open(uploaded_file).convert('L')
|
102 |
-
st.image(image_pil, caption="Uploaded Image", use_container_width=True)
|
103 |
-
st.write("---")
|
104 |
-
st.write("Processing and Recognizing...")
|
105 |
-
|
106 |
-
processed_image_tensor = preprocess_user_image_for_ocr(image_pil, IMG_HEIGHT).to(device)
|
107 |
-
|
108 |
-
ocr_model.eval() # Ensure model is in eval mode for prediction
|
109 |
-
with torch.no_grad():
|
110 |
-
output = ocr_model(processed_image_tensor)
|
111 |
-
|
112 |
-
predicted_texts = ctc_greedy_decode(output, char_indexer)
|
113 |
-
predicted_text = predicted_texts[0]
|
114 |
-
|
115 |
-
st.success(f"Recognized Text: **{predicted_text}**")
|
116 |
-
|
117 |
-
except Exception as e:
|
118 |
-
st.error(f"Error processing image or recognizing text: {e}")
|
119 |
-
st.info("π‘ **Tips for best results:**\n"
|
120 |
-
"- Ensure the handwritten text is clear and on a clean background.\n"
|
121 |
-
"- Only include one name/word per image.\n"
|
122 |
-
"- The model is trained on specific characters. Unusual symbols might not be recognized.")
|
123 |
-
st.exception(e)
|
124 |
|
125 |
# --- Tab 3: Train & Evaluate ---
|
126 |
with tab3:
|
127 |
-
st.
|
128 |
st.markdown("Here you can train a new OCR model or load a pre-trained one.")
|
129 |
|
130 |
# --- Model Loading / Initialization (Cached) ---
|
@@ -272,7 +270,7 @@ with tab3:
|
|
272 |
|
273 |
# --- Training History Plots Section ---
|
274 |
st.subheader("Training History Plots")
|
275 |
-
if st.session_state.training_history:
|
276 |
history_df = pd.DataFrame({
|
277 |
'Epoch': range(1, len(st.session_state.training_history['train_loss']) + 1),
|
278 |
'Train Loss': st.session_state.training_history['train_loss'],
|
|
|
79 |
st.markdown("""
|
80 |
**[π Project Documentation ](https://drive.google.com/file/d/1HBrQT_UnzNLdEsouW9wMk4alAeCsQxZb/view?usp=sharing)**
|
81 |
|
82 |
+
**[ποΈ Demo Presentation ](https://drive.google.com/file/d/1j_S8cijxy6zxIn3cWg6tuLPNWB_7nwdI/view?usp=sharing)**
|
83 |
|
84 |
**[π Dataset (from Kaggle)](https://www.kaggle.com/datasets/landlord/handwriting-recognition)**
|
85 |
|
|
|
88 |
|
89 |
# --- Tab 2: Predict Name (Main Content: Prediction Section) ---
|
90 |
with tab2:
|
91 |
+
st.markdown("Upload a clear image of a single handwritten name or word for recognition.")
|
|
|
92 |
|
93 |
+
uploaded_file = st.file_uploader("πΌοΈ Choose an image...", type=["png", "jpg", "jpeg", "jfif"])
|
94 |
+
if uploaded_file is not None:
|
95 |
+
try:
|
96 |
+
image_pil = Image.open(uploaded_file).convert('L')
|
97 |
+
st.image(image_pil, caption="Uploaded Image", use_container_width=True)
|
98 |
+
st.write("---")
|
99 |
+
st.write("Processing and Recognizing...")
|
100 |
+
|
101 |
+
processed_image_tensor = preprocess_user_image_for_ocr(image_pil, IMG_HEIGHT).to(device)
|
102 |
+
|
103 |
+
ocr_model.eval() # Ensure model is in eval mode for prediction
|
104 |
+
with torch.no_grad():
|
105 |
+
output = ocr_model(processed_image_tensor)
|
106 |
+
|
107 |
+
predicted_texts = ctc_greedy_decode(output, char_indexer)
|
108 |
+
predicted_text = predicted_texts[0]
|
109 |
+
|
110 |
+
st.success(f"Recognized Text: **{predicted_text}**")
|
111 |
+
|
112 |
+
except Exception as e:
|
113 |
+
st.error(f"Error processing image or recognizing text: {e}")
|
114 |
+
st.info("π‘ **Tips for best results:**\n"
|
115 |
+
"- Ensure the handwritten text is clear and on a clean background.\n"
|
116 |
+
"- Only include one name/word per image.\n"
|
117 |
+
"- The model is trained on specific characters. Unusual symbols might not be recognized.")
|
118 |
+
st.exception(e)
|
119 |
+
|
120 |
else:
|
121 |
+
st.warning("Model not loaded. Please train or load a model in the 'Train & Evaluate' tab before attempting prediction.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
|
123 |
# --- Tab 3: Train & Evaluate ---
|
124 |
with tab3:
|
125 |
+
st.subheader("Model Training and Evaluation")
|
126 |
st.markdown("Here you can train a new OCR model or load a pre-trained one.")
|
127 |
|
128 |
# --- Model Loading / Initialization (Cached) ---
|
|
|
270 |
|
271 |
# --- Training History Plots Section ---
|
272 |
st.subheader("Training History Plots")
|
273 |
+
if st.session_state.training_history:
|
274 |
history_df = pd.DataFrame({
|
275 |
'Epoch': range(1, len(st.session_state.training_history['train_loss']) + 1),
|
276 |
'Train Loss': st.session_state.training_history['train_loss'],
|