ujalaarshad17 commited on
Commit
0d4d45c
·
1 Parent(s): e6f3a2d

first commit

Browse files
Files changed (8) hide show
  1. Dockerfile +13 -0
  2. app.py +84 -0
  3. best.pt +3 -0
  4. index.js +31 -0
  5. latest.tflite +3 -0
  6. model_chip_v4.tflite +3 -0
  7. requirements.txt +7 -0
  8. templates/index.html +181 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.9
2
+
3
+ RUN useradd -m -u 1000 user
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ CMD ["gunicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ from flask import Flask, request, jsonify, render_template
4
+ from ultralytics import YOLO
5
+ import numpy as np
6
+ import tensorflow as tf
7
+ from PIL import Image
8
+
9
+ # Initialize Flask app
10
+ app = Flask(__name__)
11
+
12
+ # Load YOLO model
13
+ trained_model = YOLO("best.pt")
14
+
15
+ # Load TFLite model
16
+ interpreter = tf.lite.Interpreter(model_path='app\\model_chip_v4.tflite')
17
+ interpreter.allocate_tensors()
18
+
19
+ # Get input and output details for TFLite model
20
+ input_details = interpreter.get_input_details()
21
+ output_details = interpreter.get_output_details()
22
+
23
+ # ImageNet normalization values
24
+ imagenet_mean = np.array([0.485, 0.456, 0.406])
25
+ imagenet_std = np.array([0.229, 0.224, 0.225])
26
+
27
+ @app.route('/')
28
+ def home():
29
+ # Render the HTML template for the homepage
30
+ return render_template('index.html')
31
+
32
+ @app.route('/predict', methods=['POST'])
33
+ def predict():
34
+ if 'file' not in request.files:
35
+ return jsonify({'error': 'No file part'})
36
+
37
+ file = request.files['file']
38
+ if file.filename == '':
39
+ return jsonify({'error': 'No selected file'})
40
+
41
+ if file:
42
+ image = Image.open(file.stream)
43
+ image = image.convert('RGB')
44
+ image = np.array(image)
45
+ image_rgb = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
46
+
47
+ results = trained_model.predict(image_rgb)
48
+
49
+ if isinstance(results, list):
50
+ result = results[0]
51
+ boxes = result.boxes.xyxy
52
+ scores = result.boxes.conf
53
+ classes = result.boxes.cls
54
+ class_names = result.names
55
+
56
+ for i, (box, score, class_id) in enumerate(zip(boxes, scores, classes)):
57
+ if score > 0.4: # Consider only detections with score > 0.4
58
+ x1, y1, x2, y2 = map(int, box)
59
+ cropped_img = image[y1:y2, x1:x2]
60
+
61
+ class_id = int(class_id)
62
+ class_name = class_names[class_id]
63
+ if class_id == 2:
64
+ cropped_img = cv2.resize(cropped_img, (92, 92))
65
+ cropped_img = cropped_img.astype('float32') / 255.0
66
+ cropped_img -= imagenet_mean
67
+ cropped_img /= imagenet_std
68
+ cropped_img = np.expand_dims(cropped_img, axis=0)
69
+
70
+ interpreter.set_tensor(input_details[0]['index'], cropped_img)
71
+ interpreter.invoke()
72
+ output_data = interpreter.get_tensor(output_details[0]['index'])
73
+
74
+ # Convert float32 to native Python float
75
+ confidence_score = float(output_data[0][0])
76
+
77
+ return jsonify({'confidence_score': confidence_score})
78
+
79
+ return jsonify({'error': 'No valid detections found'})
80
+
81
+ return jsonify({'error': 'Invalid request'})
82
+
83
+ if __name__ == '__main__':
84
+ app.run()
best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:09e02b1d3c1c2bcf75634fb5b5238047a999c1f53b49129a84960d5ca35ce7b6
3
+ size 18508438
index.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function uploadImage() {
2
+ const file = imageInput.files[0];
3
+ if (!file) {
4
+ alert("Please select an image to upload.");
5
+ return;
6
+ }
7
+
8
+ const formData = new FormData();
9
+ formData.append("file", file);
10
+
11
+ fetch("/predict", {
12
+ method: "POST",
13
+ body: formData,
14
+ })
15
+ .then((response) => response.json())
16
+ .then((data) => {
17
+ if (data.confidence_score !== undefined) {
18
+ const reader = new FileReader();
19
+ reader.onload = function (e) {
20
+ resultsImg.src = e.target.result;
21
+ };
22
+ reader.readAsDataURL(file);
23
+ alert("Confidence Score: " + data.confidence_score);
24
+ } else {
25
+ alert(data.error);
26
+ }
27
+ })
28
+ .catch((error) => {
29
+ console.error("Error:", error);
30
+ });
31
+ }
latest.tflite ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4a0f601040489fc2a82c6a2bbd478ba713734f7ceea615dcc6863fc7f68a3888
3
+ size 3473672
model_chip_v4.tflite ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3ff8d2fcc750530de42125fb26059085f14a7559b9e706749739b22382f99e94
3
+ size 4927824
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ Flask
2
+ Gunicorn
3
+ tensorflow
4
+ numpy
5
+ pandas
6
+ opencv-python
7
+ ultralytics
templates/index.html ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Image Prediction</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
+ <link
10
+ href="https://fonts.googleapis.com/css2?family=Quicksand:wght@300..700&display=swap"
11
+ rel="stylesheet"
12
+ />
13
+ <style>
14
+ html {
15
+ font-family: "Quicksand", sans-serif;
16
+ }
17
+ .camera-container {
18
+ display: flex;
19
+ flex-direction: column;
20
+ align-items: center;
21
+ margin-bottom: 20px;
22
+ }
23
+
24
+ .results-container {
25
+ margin-top: 20px;
26
+ display: flex;
27
+ flex-direction: column;
28
+ align-items: center;
29
+ justify-content: center;
30
+ }
31
+
32
+ #camera {
33
+ width: 100%;
34
+ max-width: 600px;
35
+ border: 2px solid #ccc;
36
+ }
37
+
38
+ #results {
39
+ width: 100%;
40
+ max-width: 600px;
41
+ border: 2px solid #ccc;
42
+ }
43
+
44
+ .btn-container {
45
+ display: flex;
46
+ justify-content: center;
47
+ margin-top: 20px;
48
+ }
49
+
50
+ .btn {
51
+ margin: 5px;
52
+ padding: 10px 20px;
53
+ background-color: #1864ab;
54
+ color: white;
55
+ border: none;
56
+ cursor: pointer;
57
+ border-radius: 12px;
58
+ }
59
+
60
+ .btn:hover {
61
+ background-color: #45a049;
62
+ }
63
+
64
+ .upload-form {
65
+ display: flex;
66
+ justify-content: center;
67
+ margin-top: 20px;
68
+ }
69
+
70
+ #imageInput {
71
+ margin-right: 10px;
72
+ }
73
+ </style>
74
+ <script src="index.js" defer></script>
75
+ </head>
76
+ <body>
77
+ <div class="camera-container">
78
+ <h1>Capture Image</h1>
79
+ <video id="camera" autoplay></video>
80
+ <canvas id="canvas" style="display: none"></canvas>
81
+ <div class="btn-container">
82
+ <button class="btn" id="capture-btn">Capture</button>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="upload-form">
87
+ <form id="uploadForm">
88
+ <input type="file" id="imageInput" accept="image/*" required />
89
+ <button type="button" class="btn" onclick="uploadImage()">
90
+ Upload Image
91
+ </button>
92
+ </form>
93
+ </div>
94
+
95
+ <div class="results-container">
96
+ <h2>Results</h2>
97
+ <img id="results" src="" />
98
+ </div>
99
+
100
+ <script>
101
+ const video = document.getElementById("camera");
102
+ const canvas = document.getElementById("canvas");
103
+ const captureBtn = document.getElementById("capture-btn");
104
+ const imageInput = document.getElementById("imageInput");
105
+ const resultsImg = document.getElementById("results");
106
+
107
+ // Access the webcam
108
+ navigator.mediaDevices
109
+ .getUserMedia({ video: true })
110
+ .then((stream) => {
111
+ video.srcObject = stream;
112
+ })
113
+ .catch((err) => {
114
+ console.error("Error accessing webcam: ", err);
115
+ });
116
+
117
+ // Capture the image
118
+ captureBtn.addEventListener("click", () => {
119
+ const context = canvas.getContext("2d");
120
+ canvas.width = video.videoWidth;
121
+ canvas.height = video.videoHeight;
122
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
123
+
124
+ canvas.toBlob((blob) => {
125
+ const formData = new FormData();
126
+ formData.append("file", blob, "captured_image.png");
127
+
128
+ fetch("/predict", {
129
+ method: "POST",
130
+ body: formData,
131
+ })
132
+ .then((response) => response.json())
133
+ .then((data) => {
134
+ if (data.confidence_score !== undefined) {
135
+ resultsImg.src = canvas.toDataURL("image/png");
136
+ alert("Confidence Score: " + data.confidence_score);
137
+ } else {
138
+ alert(data.error);
139
+ }
140
+ })
141
+ .catch((error) => {
142
+ console.error("Error:", error);
143
+ });
144
+ }, "image/png");
145
+ });
146
+
147
+ // Upload the selected image
148
+ function uploadImage() {
149
+ const file = imageInput.files[0];
150
+ if (!file) {
151
+ alert("Please select an image to upload.");
152
+ return;
153
+ }
154
+
155
+ const formData = new FormData();
156
+ formData.append("file", file);
157
+
158
+ fetch("/predict", {
159
+ method: "POST",
160
+ body: formData,
161
+ })
162
+ .then((response) => response.json())
163
+ .then((data) => {
164
+ if (data.confidence_score !== undefined) {
165
+ const reader = new FileReader();
166
+ reader.onload = function (e) {
167
+ resultsImg.src = e.target.result;
168
+ };
169
+ reader.readAsDataURL(file);
170
+ alert("Confidence Score: " + data.confidence_score);
171
+ } else {
172
+ alert(data.error);
173
+ }
174
+ })
175
+ .catch((error) => {
176
+ console.error("Error:", error);
177
+ });
178
+ }
179
+ </script>
180
+ </body>
181
+ </html>