Sourudra commited on
Commit
4c3c504
·
verified ·
1 Parent(s): c75691f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +128 -110
app.py CHANGED
@@ -1,114 +1,132 @@
1
  import streamlit as st
2
- import pickle
3
- import numpy as np
4
  import cv2
5
- from PIL import Image
6
-
7
- # Load the trained model and other necessary files
8
- model = pickle.load(open('artifacts/license_plate_model.pkl', 'rb'))
9
-
10
- # Function to load custom CSS
11
- def local_css(file_name):
12
- with open(file_name) as f:
13
- st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
14
-
15
- # Apply custom CSS for styling
16
- local_css("style.css")
17
-
18
- # Page configuration
19
- st.set_page_config(page_title='License Plate Detection', layout='centered')
20
-
21
- # Add a fancy header with emojis
22
- st.markdown("""
23
- <div class="glass">
24
- <h1>🚗 License Plate Detection 🚗</h1>
25
- <p>Upload an image to detect license plates</p>
26
- </div>
27
- """, unsafe_allow_html=True)
28
-
29
- # File uploader for image input
30
- st.markdown("""
31
- <div class="glass">
32
- <p>📸 Upload a car image for license plate detection</p>
33
- </div>
34
- """, unsafe_allow_html=True)
35
-
36
- uploaded_file = st.file_uploader("Choose a file", type=["jpg", "jpeg", "png"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
- # If image is uploaded, process the image and make predictions
39
  if uploaded_file is not None:
40
- # Load the image using PIL
41
- image = Image.open(uploaded_file)
42
- st.image(image, caption="Uploaded Image", use_column_width=True)
43
-
44
- # Convert image to OpenCV format (for model processing)
45
- img_array = np.array(image)
46
- img_gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
47
-
48
- # Use the model to detect license plate (model predictions are made here)
49
- # Assuming your model is a classifier or detector for the license plate
50
- plate_detected = model.predict(img_gray) # Modify this depending on your model
51
-
52
- if plate_detected:
53
- st.markdown("""
54
- <div class="glass">
55
- <p>✔️ License Plate Detected!</p>
56
- </div>
57
- """, unsafe_allow_html=True)
58
- else:
59
- st.markdown("""
60
- <div class="glass">
61
- <p>❌ No License Plate Detected!</p>
62
- </div>
63
- """, unsafe_allow_html=True)
64
-
65
- # Apply custom button styling to Streamlit's default button using CSS
66
- st.markdown("""
67
- <style>
68
- .stButton > button {
69
- background: linear-gradient(135deg, #8B5E3C, #B8860B); /* Warm vintage gold-brown gradient */
70
- border: none;
71
- color: white; /* White text */
72
- padding: 12px 24px;
73
- text-align: center;
74
- text-decoration: none;
75
- display: inline-block;
76
- font-size: 16px;
77
- margin: 10px 5px;
78
- cursor: pointer;
79
- border-radius: 12px; /* Rounded corners for a soft vintage touch */
80
- box-shadow: 0 6px 12px rgba(0, 0, 0, 0.25); /* Soft, deep shadow for antique feel */
81
- font-family: 'Georgia', serif; /* Classic serif font for the button */
82
- text-transform: uppercase; /* Uppercase text for a formal touch */
83
- }
84
-
85
- .stButton > button:hover {
86
- background: linear-gradient(135deg, #704214, #B8860B); /* Slightly darker gold-brown */
87
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.3); /* Stronger shadow for depth on hover */
88
- transform: translateY(-2px); /* Lift effect */
89
- }
90
- </style>
91
- """, unsafe_allow_html=True)
92
-
93
- # Optionally, add more interactivity or styling to the button
94
- if st.button('Detect License Plate'):
95
- # Trigger the license plate detection when the button is pressed
96
- pass # Include any additional logic here, if necessary
97
-
98
- # Glassmorphism styling for text elements
99
- st.markdown("""
100
- <style>
101
- h1, h2, h3, h4 {
102
- font-family: 'Georgia', serif;
103
- color: #ffffff;
104
- text-align: center;
105
- text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
106
- }
107
-
108
- p {
109
- font-family: 'Georgia', serif;
110
- color: #ffffff;
111
- text-align: center;
112
- }
113
- </style>
114
- """, unsafe_allow_html=True)
 
1
  import streamlit as st
 
 
2
  import cv2
3
+ import numpy as np
4
+ import easyocr
5
+ from ultralytics import YOLO
6
+
7
+ # Title of the app
8
+ st.title("License Plate Recognition System🚗")
9
+
10
+ # Add external CSS for custom styling
11
+ with open('style.css') as f:
12
+ st.markdown(f'<style>{f.read()}</style>', unsafe_allow_html=True)
13
+
14
+ # Load the YOLO model for license plate detection
15
+ @st.cache_resource
16
+ def load_yolo_model():
17
+ model_path = "best.pt" # Replace with your model file
18
+ model = YOLO(model_path)
19
+ return model
20
+
21
+ # Load EasyOCR reader
22
+ @st.cache_resource
23
+ def load_easyocr_reader():
24
+ return easyocr.Reader(['en'], gpu=False)
25
+
26
+ # Initialize models
27
+ yolo_model = load_yolo_model()
28
+ ocr_reader = load_easyocr_reader()
29
+
30
+ # Function to process image and detect license plates
31
+ def process_image(image, confidence_threshold=0.5):
32
+ # Perform license plate detection
33
+ results = yolo_model(image, conf=confidence_threshold)
34
+ annotated_image = cv2.cvtColor(results[0].plot(), cv2.COLOR_BGR2RGB)
35
+ st.image(annotated_image, caption="Detected License Plate(s)", use_container_width=True)
36
+
37
+ # Loop through detections and perform OCR
38
+ for result in results:
39
+ boxes = result.boxes.xyxy.cpu().numpy().astype(int)
40
+ if len(boxes) == 0:
41
+ st.warning("No license plate detected!")
42
+ return
43
+ for i, box in enumerate(boxes):
44
+ x1, y1, x2, y2 = box
45
+ cropped_image = image[y1:y2, x1:x2]
46
+ cropped_image_rgb = cv2.cvtColor(cropped_image, cv2.COLOR_BGR2RGB)
47
+ st.image(cropped_image_rgb, caption=f"Cropped License Plate {i+1}", use_container_width=True)
48
+
49
+ # Perform OCR on the cropped image
50
+ text_results = ocr_reader.readtext(cropped_image_rgb, detail=0)
51
+ detected_text = " ".join(text_results)
52
+ st.write(f"**Extracted Text (Plate {i+1}):** {detected_text}")
53
+ st.write(f"**Confidence Score:** {result.boxes.conf.cpu().numpy()[i]:.2f}")
54
+
55
+ # Function to process video and detect license plates
56
+ def process_video(video_path, confidence_threshold=0.5, output_path="output_video.mp4"):
57
+ # Open the video file
58
+ cap = cv2.VideoCapture(video_path)
59
+
60
+ # Get video frame dimensions
61
+ frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
62
+ frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
63
+
64
+ # Create VideoWriter object to save the output video
65
+ fourcc = cv2.VideoWriter_fourcc(*"mp4v") # Codec for mp4
66
+ out = cv2.VideoWriter(output_path, fourcc, 20.0, (frame_width, frame_height)) # 20 FPS
67
+
68
+ if not cap.isOpened():
69
+ st.error("Error opening video stream or file")
70
+ return
71
+
72
+ while cap.isOpened():
73
+ ret, frame = cap.read()
74
+ if not ret:
75
+ break
76
+
77
+ results = yolo_model(frame, conf=confidence_threshold)
78
+ annotated_frame = cv2.cvtColor(results[0].plot(), cv2.COLOR_BGR2RGB)
79
+
80
+ # Loop through detections and perform OCR
81
+ for result in results:
82
+ boxes = result.boxes.xyxy.cpu().numpy().astype(int)
83
+ for i, box in enumerate(boxes):
84
+ x1, y1, x2, y2 = box
85
+ cropped_plate = frame[y1:y2, x1:x2]
86
+ cropped_rgb = cv2.cvtColor(cropped_plate, cv2.COLOR_BGR2RGB)
87
+
88
+ # Perform OCR on the cropped image
89
+ text_results = ocr_reader.readtext(cropped_rgb, detail=0)
90
+ detected_text = " ".join(text_results)
91
+
92
+ # Optionally add detected text on the annotated frame
93
+ cv2.putText(annotated_frame, detected_text, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.9, (0, 255, 0), 2)
94
+
95
+ # Write the annotated frame to the output video
96
+ out.write(cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR))
97
+
98
+ cap.release()
99
+ out.release()
100
+
101
+ st.success(f"Video processing complete. Output video saved to {output_path}.")
102
+
103
+ # Provide a download link for the processed video
104
+ with open(output_path, "rb") as f:
105
+ st.download_button(label="Download Processed Video", data=f, file_name=output_path)
106
+
107
+ # Sidebar input for file upload
108
+ uploaded_file = st.file_uploader("Upload an Image or Video", type=["mp4", "avi", "mov", "jpg", "jpeg", "png"])
109
 
 
110
  if uploaded_file is not None:
111
+ # Check if it's an image or video
112
+ file_type = uploaded_file.type
113
+
114
+ if file_type.startswith("image"):
115
+ # Read and process the image
116
+ image = cv2.imdecode(np.frombuffer(uploaded_file.read(), np.uint8), 1)
117
+ confidence_threshold = st.sidebar.slider("Confidence Threshold", 0.0, 1.0, 0.5, 0.01)
118
+ process_image(image, confidence_threshold)
119
+
120
+ elif file_type.startswith("video"):
121
+ # Save the uploaded video to a temporary file
122
+ video_bytes = uploaded_file.read()
123
+ video_path = "/tmp/uploaded_video.mp4"
124
+ with open(video_path, "wb") as f:
125
+ f.write(video_bytes)
126
+
127
+ # Process the video and save the output
128
+ output_path = "/tmp/output_video.mp4"
129
+ process_video(video_path, confidence_threshold=0.5, output_path=output_path)
130
+
131
+ st.markdown("---")
132
+ st.info("This application uses Fine Tuned YOLOv8 for detection and EasyOCR for text recognition.")