DeepActionPotential commited on
Commit
5f36299
Β·
verified Β·
1 Parent(s): a4a6e0a

πŸš€ Initial upload of my app

Browse files
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ demo/demo.mp4 filter=lfs diff=lfs merge=lfs -text
37
+ demo/demo.png filter=lfs diff=lfs merge=lfs -text
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Eslam Tarek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
README.md CHANGED
@@ -1,20 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
- title: LPlateVision
3
- emoji: πŸš€
4
- colorFrom: red
5
- colorTo: red
6
- sdk: docker
7
- app_port: 8501
8
- tags:
9
- - streamlit
10
- pinned: false
11
- short_description: YOLO-based License Plate Detection
12
- license: mit
 
 
 
 
 
 
 
 
 
13
  ---
14
 
15
- # Welcome to Streamlit!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- Edit `/src/streamlit_app.py` to customize this app to your heart's desire. :heart:
18
 
19
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
20
- forums](https://discuss.streamlit.io).
 
 
1
+ # license_plate_predicition β€” YOLOv8 License Plate Detection πŸ“ΈπŸš€
2
+
3
+ A lightweight Streamlit app that loads a trained YOLOv8 model and detects license plates in images with an intuitive chat-style UI.
4
+
5
+ ---
6
+
7
+ ## Badges
8
+
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
10
+ ![Python](https://img.shields.io/badge/Python-3.10%2B-blue)
11
+
12
+ ---
13
+
14
+ ## Table of Contents
15
+
16
+ - [Demo](#demo)
17
+ - [Features](#features)
18
+ - [Installation / Setup](#installation--setup)
19
+ - [Usage](#usage)
20
+ - [Configuration / Options](#configuration--options)
21
+ - [Contributing](#contributing)
22
+ - [License](#license)
23
+ - [Acknowledgements / Credits](#acknowledgements--credits)
24
+
25
+ ---
26
+
27
+ ## Demo
28
+
29
+ The repository includes real demo assets under `./demo/`.
30
+
31
+ - Screenshot: `./demo/demo.png`
32
+
33
+ <img src="./demo/demo.png" alt="demo" width="640" />
34
+
35
+ - Video: `./demo/demo.mp4`
36
+
37
+ <video src="./demo/demo.mp4" width="640" controls></video>
38
+
39
+ ---
40
+
41
+ ## Features
42
+
43
+ - **YOLOv8 inference** via `ultralytics` for license plate detection.
44
+ - **Chat-style Streamlit UI** to upload an image or paste an image URL.
45
+ - **On-image annotations** with bounding boxes.
46
+ - **Single-command launch** with Streamlit.
47
+
48
+ ---
49
+
50
+ ## Installation / Setup
51
+
52
+ Use a virtual environment for isolation.
53
+
54
+ ```bash
55
+ # Create a virtual environment
56
+ python -m venv .venv
57
+
58
+ # Activate it
59
+ # On Linux/Mac:
60
+ source .venv/bin/activate
61
+ # On Windows:
62
+ .venv\Scripts\activate
63
+
64
+ # Upgrade pip (recommended)
65
+ pip install --upgrade pip
66
+
67
+ # Install dependencies
68
+ pip install -r requirements.txt
69
+ ```
70
+
71
  ---
72
+
73
+ ## Usage
74
+
75
+ - Make sure you have a YOLOv8 model file at `./models/model.pt` (see [Configuration](#configuration--options)).
76
+ - Launch the app:
77
+
78
+ ```bash
79
+ streamlit run app.py
80
+ ```
81
+
82
+ - In the app UI (`app.py` calling `render_chat_ui()` in `ui.py`):
83
+ - Choose "Upload Image" and provide a `.jpg/.jpeg/.png`, or
84
+ - Choose "Image URL" and paste a direct image URL.
85
+ - Click "Detect License Plate" to run inference. The result image with bounding boxes will be displayed.
86
+
87
+ Programmatic highlights:
88
+
89
+ - Model loading: `utils.load_model()` uses `ultralytics.YOLO` and Streamlit caching.
90
+ - Inference: `utils.detect_license_plate()` runs `model.predict()` and returns an annotated image.
91
+
92
  ---
93
 
94
+ ## Configuration / Options
95
+
96
+ - **Model path**: `app.py` loads `./models/model.pt` once at startup.
97
+ - Replace this file with your trained YOLOv8 weights.
98
+ - You can retrain with Ultralytics and export to `.pt`.
99
+ - **Confidence threshold**: Set in `utils.detect_license_plate()` (default `conf=0.25`). Adjust as needed.
100
+ - **Image inputs**:
101
+ - Upload via Streamlit file uploader.
102
+ - Provide a URL; the app fetches it using `requests` and decodes with OpenCV.
103
+
104
+ ---
105
+
106
+ ## Contributing
107
+
108
+ Contributions are welcome! Please:
109
+
110
+ 1. Fork the repo.
111
+ 2. Create a feature branch.
112
+ 3. Commit changes with clear messages.
113
+ 4. Open a pull request describing the motivation and changes.
114
+
115
+ For larger changes, consider opening an issue first to discuss the proposal.
116
+
117
+ ---
118
+
119
+ ## License
120
+
121
+ This project is licensed under the MIT License. See [`LICENSE`](./LICENSE) for details.
122
+
123
+ ---
124
 
125
+ ## Acknowledgements / Credits
126
 
127
+ - [`ultralytics`](https://github.com/ultralytics/ultralytics) β€” YOLOv8 model and inference utilities.
128
+ - [`streamlit`](https://streamlit.io) β€” simple web app framework for ML demos.
129
+ - [`opencv-python`](https://pypi.org/project/opencv-python/), [`numpy`](https://numpy.org/), and [`Pillow`](https://python-pillow.org/) for image handling and visualization.
__pycache__/ui.cpython-311.pyc ADDED
Binary file (2.46 kB). View file
 
__pycache__/utils.cpython-311.pyc ADDED
Binary file (2.27 kB). View file
 
app.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from ui import render_chat_ui
3
+ from utils import load_model, detect_license_plate
4
+
5
+ st.set_page_config(page_title="License Plate Detector", layout="centered")
6
+
7
+ # Title
8
+ st.title("πŸ“Έ License Plate Detector")
9
+
10
+ # Load YOLO model (runs once)
11
+ model = load_model("./models/model.pt")
12
+
13
+ # Chat-like interface
14
+ render_chat_ui(model)
demo/demo.mp4 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e8878e916f1a2931696c17423a941ed7a2a589698873b3f3fad7921f15f9b0e8
3
+ size 2641455
demo/demo.png ADDED

Git LFS Details

  • SHA256: 9b8e077830d79b90e9e727c239db70c4fc41de5fe3da35a2236c46d746288ff6
  • Pointer size: 131 Bytes
  • Size of remote file: 923 kB
models/model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:5d7626826b6c2ac960f1664c237cb7113783095d0d9b9e8a3457ef7a36ceb4b7
3
+ size 6245667
requirements.txt CHANGED
@@ -1,3 +1,8 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
1
+ ultralytics==8.3.158
2
+ streamlit==1.37.1
3
+ numpy==1.26.4
4
+ opencv-python==4.10.0.84
5
+ requests==2.32.3
6
+ Pillow==10.4.0
7
+ pandas==2.2.2
8
+ matplotlib==3.8.4
ui.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from utils import detect_license_plate, load_image_from_upload, load_image_from_url
3
+ import io
4
+ from PIL import Image
5
+ import numpy as np
6
+
7
+ def render_chat_ui(model):
8
+ st.markdown("Chat-style license plate detector. Upload an image or paste a URL.")
9
+
10
+ history = st.session_state.get("chat_history", [])
11
+ input_mode = st.radio("Choose Input Type", ["Upload Image", "Image URL"])
12
+
13
+ # Input
14
+ uploaded_file = None
15
+ image_url = None
16
+
17
+ if input_mode == "Upload Image":
18
+ uploaded_file = st.file_uploader("Upload an image", type=["jpg", "jpeg", "png"])
19
+ else:
20
+ image_url = st.text_input("Paste image URL")
21
+
22
+ submit = st.button("Detect License Plate")
23
+
24
+ if submit:
25
+ if input_mode == "Upload Image" and uploaded_file is not None:
26
+ image = load_image_from_upload(uploaded_file)
27
+ label = "User uploaded an image."
28
+ elif input_mode == "Image URL" and image_url.strip():
29
+ image = load_image_from_url(image_url)
30
+ label = f"User sent image URL: {image_url}"
31
+ else:
32
+ st.warning("Please provide a valid image.")
33
+ return
34
+
35
+ st.session_state.chat_history = history + [(label, image)]
36
+
37
+ # Detect and display
38
+ with st.spinner("Detecting license plate..."):
39
+ result_img = detect_license_plate(model, image)
40
+ st.image(result_img, caption="Bounding box", use_column_width=True)
41
+
42
+ # Save result to history
43
+ st.session_state.chat_history.append(("Bounding box", result_img))
44
+
45
+
utils.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from ultralytics import YOLO
2
+ import numpy as np
3
+ import cv2
4
+ import tempfile
5
+ import requests
6
+ from PIL import Image
7
+ import os
8
+ import streamlit as st
9
+
10
+ @st.cache_resource
11
+ def load_model(model_path):
12
+ """Load the trained YOLOv8 model."""
13
+ return YOLO(model_path)
14
+
15
+ def detect_license_plate(model, image: np.ndarray) -> np.ndarray:
16
+ """Detect license plate and return image with drawn bounding boxes."""
17
+ results = model.predict(image, conf=0.25)
18
+ annotated = results[0].plot() # Draw boxes on the image
19
+ return annotated
20
+
21
+ def load_image_from_upload(uploaded_file) -> np.ndarray:
22
+ """Load image from an uploaded file."""
23
+ image = Image.open(uploaded_file).convert("RGB")
24
+ return np.array(image)
25
+
26
+ def load_image_from_url(url: str) -> np.ndarray:
27
+ """Download and convert an image from a URL."""
28
+ response = requests.get(url)
29
+ img_arr = np.asarray(bytearray(response.content), dtype=np.uint8)
30
+ image = cv2.imdecode(img_arr, cv2.IMREAD_COLOR)
31
+ image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
32
+ return image
yolo8-predict-a-bounding-box-accuracy-over-95.ipynb ADDED
The diff for this file is too large to render. See raw diff