Prudhvi Raj Grandhe
commited on
Commit
•
94a2a81
1
Parent(s):
ee706ad
test
Browse files- Dockerfile +14 -0
- app.py +163 -0
- requirements.txt +16 -0
Dockerfile
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# read the doc: https://huggingface.co/docs/hub/spaces-sdks-docker
|
2 |
+
# you will also find guides on how best to write your Dockerfile
|
3 |
+
|
4 |
+
FROM python:3.9
|
5 |
+
|
6 |
+
WORKDIR /code
|
7 |
+
|
8 |
+
COPY ./requirements.txt /code/requirements.txt
|
9 |
+
|
10 |
+
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
|
11 |
+
|
12 |
+
COPY . .
|
13 |
+
|
14 |
+
CMD ["gunicorn", "-b", "0.0.0.0:7860", "app:app"]
|
app.py
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from flask import Flask, Response, request, jsonify
|
2 |
+
import cv2
|
3 |
+
from flask_cors import CORS
|
4 |
+
import pytesseract
|
5 |
+
import numpy as np
|
6 |
+
import os
|
7 |
+
import uuid
|
8 |
+
|
9 |
+
from pymongo.mongo_client import MongoClient
|
10 |
+
from pymongo.server_api import ServerApi
|
11 |
+
|
12 |
+
uri = "mongodb+srv://cse443Prudhvi:pEjVbWv6oJHaHSJA@cluster0.7ournot.mongodb.net/"
|
13 |
+
# Create a new client and connect to the server
|
14 |
+
|
15 |
+
|
16 |
+
cluster = MongoClient(uri)
|
17 |
+
db = cluster['cseData'] # Replace '<dbname>' with your actual database name
|
18 |
+
collection = db['numberPlates']
|
19 |
+
|
20 |
+
|
21 |
+
|
22 |
+
FRAME_WIDTH = 640
|
23 |
+
FRAME_HEIGHT = 480
|
24 |
+
PLATE_CASCADE = cv2.CascadeClassifier('./indian_license_plate.xml')
|
25 |
+
MIN_AREA = 300
|
26 |
+
COLOR = (255, 0, 255)
|
27 |
+
|
28 |
+
|
29 |
+
# Declare a variable with the type ndarray[Any, dtype[generic]]
|
30 |
+
img_roi: np.ndarray = np.array([1, 2, 3])
|
31 |
+
|
32 |
+
app = Flask(__name__)
|
33 |
+
CORS(app)
|
34 |
+
counter = 0 # Counter for image filenames
|
35 |
+
|
36 |
+
def generate_frames(n):
|
37 |
+
cap = cv2.VideoCapture(0)
|
38 |
+
|
39 |
+
global img_roi
|
40 |
+
while cap.isOpened():
|
41 |
+
# read the camera frame
|
42 |
+
success, frame = cap.read()
|
43 |
+
|
44 |
+
if not success:
|
45 |
+
break
|
46 |
+
else:
|
47 |
+
img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
48 |
+
number_plates = PLATE_CASCADE.detectMultiScale(img_gray, 1.3, 7)
|
49 |
+
|
50 |
+
# Iterate through detected plates
|
51 |
+
|
52 |
+
for (x, y, w, h) in number_plates:
|
53 |
+
area = (w * h)+100
|
54 |
+
if area > MIN_AREA:
|
55 |
+
# Draw rectangle around the plate
|
56 |
+
cv2.rectangle(frame, (x, y), (x + w, y + h), COLOR, 2)
|
57 |
+
# Add text label
|
58 |
+
cv2.putText(frame, "License Plate", (x, y - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, COLOR, 2)
|
59 |
+
# Show region of interest (ROI)
|
60 |
+
img_roi = frame[y:y + h , x:x + w ]
|
61 |
+
|
62 |
+
|
63 |
+
ret, buffer = cv2.imencode('.jpg', frame)
|
64 |
+
frame_bytes = buffer.tobytes()
|
65 |
+
|
66 |
+
yield (b'--frame\r\n'
|
67 |
+
b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
|
68 |
+
@app.route('/')
|
69 |
+
def index():
|
70 |
+
return "Hello World"
|
71 |
+
|
72 |
+
|
73 |
+
@app.route('/video')
|
74 |
+
def video():
|
75 |
+
return Response(generate_frames(0), mimetype='multipart/x-mixed-replace; boundary=frame')
|
76 |
+
|
77 |
+
|
78 |
+
|
79 |
+
|
80 |
+
@app.route('/save', methods=['POST'])
|
81 |
+
def save():
|
82 |
+
|
83 |
+
global counter
|
84 |
+
global img_roi
|
85 |
+
cv2.imwrite(f"/Users/prudhviraj/Documents/CSE443/img/{counter}.png", img_roi)
|
86 |
+
|
87 |
+
image = f"/Users/prudhviraj/Documents/CSE443/img/{counter}.png"
|
88 |
+
pytesseract.pytesseract.tesseract_cmd = '/opt/homebrew/bin/tesseract'
|
89 |
+
extracted_text = pytesseract.image_to_string(image)
|
90 |
+
|
91 |
+
new_text=''
|
92 |
+
alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
93 |
+
num="0123456789"
|
94 |
+
for i in extracted_text:
|
95 |
+
if i in alpha or i in num:
|
96 |
+
new_text+=i
|
97 |
+
print(new_text)
|
98 |
+
print("Yes!!!!!")
|
99 |
+
# collection.insert_one({"number":f"{new_text}"})
|
100 |
+
|
101 |
+
counter += 1
|
102 |
+
return new_text
|
103 |
+
|
104 |
+
UPLOAD_FOLDER = '/Users/prudhviraj/Documents/CSE443/img'
|
105 |
+
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
|
106 |
+
|
107 |
+
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
|
108 |
+
|
109 |
+
def allowed_file(filename):
|
110 |
+
return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS
|
111 |
+
|
112 |
+
@app.route('/upload', methods=['POST'])
|
113 |
+
def upload_image():
|
114 |
+
# check if the post request has the file part
|
115 |
+
if 'image' not in request.files:
|
116 |
+
return jsonify({"error": "No image part in the request"}), 400
|
117 |
+
|
118 |
+
image_file = request.files['image']
|
119 |
+
|
120 |
+
# if user does not select file, browser also submits an empty part without filename
|
121 |
+
if image_file.filename == '':
|
122 |
+
return jsonify({"error": "No selected image file"}), 400
|
123 |
+
|
124 |
+
if image_file and allowed_file(image_file.filename):
|
125 |
+
filename = str(uuid.uuid4()) + '.' + image_file.filename.rsplit('.', 1)[1].lower()
|
126 |
+
filepath = os.path.join(app.config['UPLOAD_FOLDER'], filename)
|
127 |
+
image_file.save(filepath)
|
128 |
+
|
129 |
+
print(filepath)
|
130 |
+
frame = cv2.imread(filepath)
|
131 |
+
# success, frame = image.read()
|
132 |
+
|
133 |
+
img_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
|
134 |
+
number_plates = PLATE_CASCADE.detectMultiScale(img_gray, 1.3, 7)
|
135 |
+
|
136 |
+
for (x, y, w, h) in number_plates:
|
137 |
+
area = w * h
|
138 |
+
if area > MIN_AREA:
|
139 |
+
# Draw rectangle around the plate
|
140 |
+
cv2.rectangle(frame, (x, y), (x + w, y + h), COLOR, 2)
|
141 |
+
# Add text label
|
142 |
+
cv2.putText(frame, "License Plate", (x, y - 5), cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, COLOR, 2)
|
143 |
+
# Show region of interest (ROI)
|
144 |
+
img_roi = frame[y:y + h, x:x + w]
|
145 |
+
pytesseract.pytesseract.tesseract_cmd = '/opt/homebrew/bin/tesseract'
|
146 |
+
extracted_text = pytesseract.image_to_string(img_roi)
|
147 |
+
|
148 |
+
new_text=''
|
149 |
+
alpha="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
150 |
+
num="0123456789"
|
151 |
+
for i in extracted_text:
|
152 |
+
if i in alpha or i in num:
|
153 |
+
new_text+=i
|
154 |
+
print(new_text)
|
155 |
+
return jsonify({"success": "Image uploaded successfully", "filename": filename}), 200
|
156 |
+
|
157 |
+
else:
|
158 |
+
return jsonify({"error": "File type not allowed"}), 400
|
159 |
+
|
160 |
+
|
161 |
+
|
162 |
+
if __name__ == '__main__':
|
163 |
+
app.run(debug=True)
|
requirements.txt
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
blinker==1.7.0
|
2 |
+
click==8.1.7
|
3 |
+
dnspython==2.6.1
|
4 |
+
Flask==3.0.3
|
5 |
+
Flask-Cors==4.0.0
|
6 |
+
gunicorn==22.0.0
|
7 |
+
itsdangerous==2.1.2
|
8 |
+
Jinja2==3.1.3
|
9 |
+
MarkupSafe==2.1.5
|
10 |
+
numpy==1.26.4
|
11 |
+
opencv-contrib-python==4.9.0.80
|
12 |
+
packaging==24.0
|
13 |
+
pillow==10.3.0
|
14 |
+
pymongo==4.6.3
|
15 |
+
pytesseract==0.3.10
|
16 |
+
Werkzeug==3.0.2
|