Spaces:
Sleeping
Sleeping
cleaned some code, redundant tasks and old code removed
#2
by
RatanPrakash
- opened
app.py
CHANGED
@@ -13,12 +13,6 @@ import matplotlib.pyplot as plt
|
|
13 |
|
14 |
# Initialize PaddleOCR model
|
15 |
ocr = PaddleOCR(use_angle_cls=True, lang='en')
|
16 |
-
# Define the class names based on your dataset
|
17 |
-
class_names = [
|
18 |
-
'fresh_apple', 'fresh_banana', 'fresh_bitter_gourd', 'fresh_capsicum',
|
19 |
-
'fresh_orange', 'fresh_tomato', 'stale_apple', 'stale_banana',
|
20 |
-
'stale_bitter_gourd', 'stale_capsicum', 'stale_orange', 'stale_tomato'
|
21 |
-
]
|
22 |
|
23 |
# Team details
|
24 |
team_members = [
|
@@ -77,6 +71,8 @@ def make_image_circular1(img, size=(256, 256)):
|
|
77 |
output = ImageOps.fit(img, mask.size, centering=(0.5, 0.5))
|
78 |
output.putalpha(mask) # Apply the mask as transparency
|
79 |
return output
|
|
|
|
|
80 |
# Function to check if a file exists
|
81 |
def file_exists(file_path):
|
82 |
return os.path.isfile(file_path)
|
@@ -332,70 +328,6 @@ elif app_mode == "Task 1":
|
|
332 |
else:
|
333 |
st.write("Please upload images to extract product details.")
|
334 |
|
335 |
-
elif app_mode == "Task 2":
|
336 |
-
st.write("## Task 2:π
Expiry Date Validation β
")
|
337 |
-
st.write("Use OCR to get expiry and MRP details printed on items.")
|
338 |
-
# File uploader for images (supports multiple files)
|
339 |
-
uploaded_files = st.file_uploader("Upload images of products containing expiry date", type=["jpeg", "png", "jpg"], accept_multiple_files=True)
|
340 |
-
|
341 |
-
if uploaded_files:
|
342 |
-
st.write("### Uploaded Images in Circular Format:")
|
343 |
-
circular_images = []
|
344 |
-
|
345 |
-
for uploaded_file in uploaded_files:
|
346 |
-
img = Image.open(uploaded_file)
|
347 |
-
circular_img = make_image_circular(img) # Create circular images
|
348 |
-
circular_images.append(circular_img)
|
349 |
-
|
350 |
-
# Display the circular images in a matrix/grid format
|
351 |
-
display_images_in_grid(circular_images, max_images_per_row=4)
|
352 |
-
|
353 |
-
# Function to simulate loading process with a progress bar
|
354 |
-
def simulate_progress():
|
355 |
-
progress_bar = st.progress(0)
|
356 |
-
for percent_complete in range(100):
|
357 |
-
time.sleep(0.02)
|
358 |
-
progress_bar.progress(percent_complete + 1)
|
359 |
-
|
360 |
-
for idx, uploaded_file in enumerate(uploaded_files):
|
361 |
-
image = Image.open(uploaded_file)
|
362 |
-
img_array = np.array(image)
|
363 |
-
result = ocr.ocr(img_array, cls=True)
|
364 |
-
|
365 |
-
if result and result[0]:
|
366 |
-
# Extract recognized texts
|
367 |
-
recognized_texts = [line[1][0] for line in result[0]]
|
368 |
-
|
369 |
-
# Clean up recognized texts by removing extra spaces and standardizing formats
|
370 |
-
cleaned_texts = []
|
371 |
-
for text in recognized_texts:
|
372 |
-
cleaned_text = re.sub(r'\s+', ' ', text.strip()) # Replace multiple spaces with a single space
|
373 |
-
cleaned_text = cleaned_text.replace('.', '').replace(',', '') # Remove dots and commas for date detection
|
374 |
-
cleaned_texts.append(cleaned_text)
|
375 |
-
|
376 |
-
# Extract dates from recognized texts
|
377 |
-
extracted_dates, date_texts, date_boxes, date_scores = extract_dates_with_dateparser(cleaned_texts, result)
|
378 |
-
|
379 |
-
if extracted_dates:
|
380 |
-
# Display extracted dates
|
381 |
-
st.write("**Extracted Dates**:")
|
382 |
-
for date, text in zip(extracted_dates, date_texts):
|
383 |
-
st.write(f"Detected Date: **{date}**, Original Text: *{text}*")
|
384 |
-
else:
|
385 |
-
st.write("No valid dates found in the image.")
|
386 |
-
|
387 |
-
# Option to visualize the bounding boxes on the image
|
388 |
-
if st.checkbox(f"Show image with highlighted dates for {uploaded_file.name}", key=f"highlight_{idx}"):
|
389 |
-
# Draw the OCR results on the image
|
390 |
-
image_with_boxes = draw_ocr(image, date_boxes, date_texts, date_scores,font_path='CedarvilleCursive-Regular.ttf') # Removed font path
|
391 |
-
|
392 |
-
# Display the image with highlighted boxes
|
393 |
-
plt.figure(figsize=(10, 10))
|
394 |
-
plt.imshow(image_with_boxes)
|
395 |
-
plt.axis('off') # Hide axes
|
396 |
-
st.pyplot(plt)
|
397 |
-
else:
|
398 |
-
st.write("No text detected in the image.")
|
399 |
|
400 |
|
401 |
def make_image_circular1(image):
|
@@ -425,158 +357,6 @@ def display_images_in_grid1(images, max_images_per_row=4):
|
|
425 |
if idx < len(cols):
|
426 |
cols[idx].image(img, use_column_width=True)
|
427 |
|
428 |
-
# Initialize your Streamlit app
|
429 |
-
if app_mode == "Task 3":
|
430 |
-
st.write("## Task 3: Image Recognition πΈ and IR-Based Counting π")
|
431 |
-
|
432 |
-
# File uploader for images (supports multiple files)
|
433 |
-
uploaded_files = st.file_uploader("Upload images of fruits, vegetables, or products for brand recognition and freshness detection",
|
434 |
-
type=["jpeg", "png", "jpg"], accept_multiple_files=True)
|
435 |
-
if uploaded_files:
|
436 |
-
st.write("### Uploaded Images:")
|
437 |
-
# Load the pre-trained YOLOv8 model
|
438 |
-
model = YOLO('yolov9c.pt') # Adjust path to your YOLO model if needed
|
439 |
-
|
440 |
-
# Initialize a dictionary to store counts of detected products
|
441 |
-
product_count_dict = {}
|
442 |
-
circular_images = []
|
443 |
-
images=[]
|
444 |
-
|
445 |
-
for uploaded_file in uploaded_files:
|
446 |
-
img = Image.open(uploaded_file)
|
447 |
-
circular_img = make_image_circular(img) # Create circular images
|
448 |
-
circular_images.append(circular_img)
|
449 |
-
images.append(img)
|
450 |
-
|
451 |
-
# Display the circular images in a matrix/grid format
|
452 |
-
display_images_in_grid(circular_images, max_images_per_row=4)
|
453 |
-
|
454 |
-
detected_images = []
|
455 |
-
|
456 |
-
for idx, image in enumerate(images):
|
457 |
-
# Run object detection
|
458 |
-
results = model(image)
|
459 |
-
|
460 |
-
# Initialize counts for this image
|
461 |
-
image_counts = {}
|
462 |
-
|
463 |
-
# Display results with bounding boxes
|
464 |
-
for result in results:
|
465 |
-
img_with_boxes = result.plot() # Get image with bounding boxes
|
466 |
-
detected_images.append(make_image_circular(image.resize((150, 150)))) # Resize and make circular
|
467 |
-
|
468 |
-
# Display detected object counts per class
|
469 |
-
counts = result.boxes.cls.tolist() # Extract class IDs
|
470 |
-
class_counts = {int(cls): counts.count(cls) for cls in set(counts)}
|
471 |
-
|
472 |
-
# Update the image counts for this image
|
473 |
-
for cls_id, count in class_counts.items():
|
474 |
-
product_name = result.names[cls_id] # Get the product name from class ID
|
475 |
-
image_counts[product_name] = count
|
476 |
-
|
477 |
-
# Aggregate counts into the main product count dictionary
|
478 |
-
for product, count in image_counts.items():
|
479 |
-
if product in product_count_dict:
|
480 |
-
product_count_dict[product] += count
|
481 |
-
else:
|
482 |
-
product_count_dict[product] = count
|
483 |
-
|
484 |
-
# Option to visualize the bounding boxes on the image
|
485 |
-
if st.checkbox(f"Show image with highlighted boxes for image {idx + 1}", key=f"checkbox_{idx}"):
|
486 |
-
st.image(img_with_boxes, caption="Image with Highlighted Boxes", use_column_width=True)
|
487 |
-
|
488 |
-
# Display the total counts as a bar chart
|
489 |
-
st.write("### Total Product Counts Across All Images:")
|
490 |
-
if product_count_dict:
|
491 |
-
product_count_df = pd.DataFrame(product_count_dict.items(), columns=["Product", "Count"])
|
492 |
-
st.bar_chart(product_count_df.set_index("Product"))
|
493 |
-
else:
|
494 |
-
st.write("No products detected.")
|
495 |
-
|
496 |
-
elif app_mode == "Task 4":
|
497 |
-
st.write("## Task 4: π Fruit and Vegetable Freshness Detector π
")
|
498 |
-
# Load the trained model
|
499 |
-
try:
|
500 |
-
model = tf.keras.models.load_model('fruit_freshness_model.h5') # Using TensorFlow to load the model
|
501 |
-
st.success("Model loaded successfully!")
|
502 |
-
except Exception as e:
|
503 |
-
st.error(f"Error loading model: {e}")
|
504 |
-
|
505 |
-
# File uploader for images (supports multiple files)
|
506 |
-
uploaded_files = st.file_uploader("Upload images of fruits/vegetables", type=["jpeg", "png", "jpg"], accept_multiple_files=True)
|
507 |
-
|
508 |
-
if uploaded_files:
|
509 |
-
st.write("### Uploaded Images in Circular Format:")
|
510 |
-
circular_images = []
|
511 |
-
images=[]
|
512 |
-
|
513 |
-
for uploaded_file in uploaded_files:
|
514 |
-
img = Image.open(uploaded_file)
|
515 |
-
circular_img = make_image_circular(img) # Create circular images
|
516 |
-
circular_images.append(circular_img)
|
517 |
-
images.append(img)
|
518 |
-
|
519 |
-
# Display the circular images in a matrix/grid format
|
520 |
-
display_images_in_grid(circular_images, max_images_per_row=4)
|
521 |
-
|
522 |
-
# Function to simulate loading process with a progress bar
|
523 |
-
def simulate_progress():
|
524 |
-
progress_bar = st.progress(0)
|
525 |
-
for percent_complete in range(100):
|
526 |
-
time.sleep(0.02)
|
527 |
-
progress_bar.progress(percent_complete + 1)
|
528 |
-
|
529 |
-
# Create an empty DataFrame to hold the image name and prediction results
|
530 |
-
results_df = pd.DataFrame(columns=["Image", "Prediction"])
|
531 |
-
|
532 |
-
# Create a dictionary to count the occurrences of each class
|
533 |
-
class_counts = {class_name: 0 for class_name in class_names}
|
534 |
-
|
535 |
-
# Button to initiate predictions
|
536 |
-
if st.button("Run Prediction"):
|
537 |
-
# Display progress bar
|
538 |
-
simulate_progress()
|
539 |
-
|
540 |
-
for idx, img in enumerate(images): # Use circular images for predictions
|
541 |
-
img_array = preprocess_image(img.convert('RGB')) # Convert to RGB
|
542 |
-
|
543 |
-
try:
|
544 |
-
# Perform the prediction
|
545 |
-
prediction = model.predict(img_array)
|
546 |
-
|
547 |
-
# Get the class with the highest probability
|
548 |
-
result = class_names[np.argmax(prediction)]
|
549 |
-
st.success(f'Prediction for Image {idx + 1}: **{result}**')
|
550 |
-
|
551 |
-
# Increment the class count
|
552 |
-
class_counts[result] += 1
|
553 |
-
|
554 |
-
# Add the result to the DataFrame
|
555 |
-
result_data = pd.DataFrame({"Image": [uploaded_files[idx].name], "Prediction": [result]})
|
556 |
-
results_df = pd.concat([results_df, result_data], ignore_index=True)
|
557 |
-
|
558 |
-
except Exception as e:
|
559 |
-
st.error(f"Error occurred during prediction: {e}")
|
560 |
-
|
561 |
-
# Display class distribution as a bar chart
|
562 |
-
st.write("### Class Distribution:")
|
563 |
-
class_counts_df = pd.DataFrame(list(class_counts.items()), columns=['Class', 'Count'])
|
564 |
-
st.bar_chart(class_counts_df.set_index('Class'))
|
565 |
-
|
566 |
-
# Option to download the prediction results as a CSV file
|
567 |
-
st.write("### Download Results:")
|
568 |
-
csv = results_df.to_csv(index=False).encode('utf-8')
|
569 |
-
st.download_button(
|
570 |
-
label="Download prediction results as CSV",
|
571 |
-
data=csv,
|
572 |
-
file_name='prediction_results.csv',
|
573 |
-
mime='text/csv',
|
574 |
-
)
|
575 |
-
|
576 |
-
# Display the dataframe after the graph
|
577 |
-
st.write("### Prediction Data:")
|
578 |
-
st.dataframe(results_df)
|
579 |
-
|
580 |
# Footer with animation
|
581 |
st.markdown("""
|
582 |
<style>
|
|
|
13 |
|
14 |
# Initialize PaddleOCR model
|
15 |
ocr = PaddleOCR(use_angle_cls=True, lang='en')
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
|
17 |
# Team details
|
18 |
team_members = [
|
|
|
71 |
output = ImageOps.fit(img, mask.size, centering=(0.5, 0.5))
|
72 |
output.putalpha(mask) # Apply the mask as transparency
|
73 |
return output
|
74 |
+
|
75 |
+
|
76 |
# Function to check if a file exists
|
77 |
def file_exists(file_path):
|
78 |
return os.path.isfile(file_path)
|
|
|
328 |
else:
|
329 |
st.write("Please upload images to extract product details.")
|
330 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
331 |
|
332 |
|
333 |
def make_image_circular1(image):
|
|
|
357 |
if idx < len(cols):
|
358 |
cols[idx].image(img, use_column_width=True)
|
359 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
# Footer with animation
|
361 |
st.markdown("""
|
362 |
<style>
|