MsChabane commited on
Commit
84402c7
·
verified ·
1 Parent(s): 5376ca8
.dockerignore ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ .env
6
+ *.db
7
+ .git
8
+ .gitignore
9
+ Dockerfile
10
+ .dockerignore
11
+ *.log
.gitattributes CHANGED
@@ -33,3 +33,4 @@ 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
+ app/models/MobileNetV3_rust_classifier.keras filter=lfs diff=lfs merge=lfs -text
DockerFile ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+
4
+ WORKDIR /app
5
+
6
+ COPY . .
7
+
8
+
9
+ RUN pip install --upgrade pip
10
+ RUN pip install -r requirements.txt
11
+
12
+
13
+
14
+
15
+ EXPOSE 7860
16
+
17
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
app/__init__.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+
4
+
5
+
6
+ app = FastAPI(title="Corrosion Detection API")
7
+
8
+
9
+ app.add_middleware(
10
+ CORSMiddleware,
11
+ allow_origins=["*"],
12
+ allow_methods=["*"],
13
+ allow_headers=["*"],
14
+ )
15
+
16
+
17
+ from FastAPI.app import routes
app/models/MobileNetV3_rust_classifier.keras ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:70b352bc6190b00457c115d366334da322b8657ec51dbb243b41713d4637af45
3
+ size 14252422
app/models/Yolo.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:76b28a4116797da8b5c4f724c335f154d28043201398ec6d9e3c60d8cc288978
3
+ size 40835739
app/process.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ from ultralytics import YOLO
4
+ from tensorflow.keras.preprocessing.image import img_to_array
5
+ import numpy as np
6
+ import cv2
7
+ from tensorflow.keras.models import load_model
8
+ from tensorflow.keras.applications.mobilenet_v3 import preprocess_input
9
+ import PIL.Image as Image
10
+ import io
11
+ import base64
12
+ import os
13
+
14
+ BASE_DIR = os.path.dirname(os.path.abspath(__file__))
15
+ YOLO_PATH= os.join(BASE_DIR,"models",'Yolo.pt')
16
+ MOBILENET_PATH= os.join(BASE_DIR,"models",'MobileNetV3_rust_classifier.keras')
17
+
18
+ YOLO_MODEL=YOLO(YOLO_PATH)
19
+ MOBILENET_MODEL=load_model(MOBILENET_PATH)
20
+
21
+
22
+
23
+ def predict(image_bytes):
24
+ img = Image.open(io.BytesIO(image_bytes)).resize((224, 224))
25
+ x = img_to_array(img)
26
+ x = np.expand_dims(x, axis=0)
27
+ x = preprocess_input(x)
28
+ proba = MOBILENET_MODEL.predict(x)[0]
29
+ prediction = np.argmax(proba)
30
+ return prediction,proba[prediction]
31
+
32
+
33
+ def detect(image_bytes):
34
+ image = Image.open(io.BytesIO(image_bytes)).convert("RGB")
35
+ result = YOLO_MODEL(image)[0]
36
+ img_result= Image.fromarray(result.plot())
37
+ buffer=io.BytesIO()
38
+ img_result.save(buffer,format="PNG")
39
+ base64_str = base64.b64encode(buffer.getvalue()).decode('utf-8')
40
+ uri =f"data:image/png;base64,{base64_str}"
41
+ return uri
42
+
43
+
44
+
45
+
46
+
47
+
48
+
app/routes.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from app import app
2
+ from fastapi.responses import JSONResponse
3
+ from fastapi import UploadFile,File
4
+ from app.process import detect,predict
5
+
6
+ SUPPORTED_FILES =['png','jpeg','jpg']
7
+ CLASSES = {0:'no rust',1:'rust'}
8
+
9
+ @app.get("/")
10
+ def index():
11
+ return JSONResponse({
12
+ "app":"Rust detection",
13
+ "version":"1.0.0",
14
+ "models":[{
15
+ "Mobilenet":{
16
+ "size":"Large",
17
+ "version":3,
18
+ "accuracy":92.0
19
+ },
20
+ "Yolo":{
21
+ "size":"Medium",
22
+ "version":9,
23
+ },
24
+
25
+ }]
26
+ })
27
+
28
+ @app.post("predict",response_class=JSONResponse)
29
+ def upload(image:UploadFile=File(...)):
30
+ extension = image.filename.split(".")[-1]
31
+ if extension not in SUPPORTED_FILES:
32
+ return JSONResponse(content={"error": "Unsupported file type"},status_code=400)
33
+
34
+ image_bytes = image.file.read()
35
+ try:
36
+ class_number,probability =predict(image_bytes)
37
+ uri =None
38
+ if class_number ==1 :
39
+ uri =detect(image_bytes)
40
+ response ={
41
+ "prediction":CLASSES[class_number],
42
+ "probability":round(probability,4)*100,
43
+ "uri":uri
44
+ }
45
+ return JSONResponse(content=response,status_code=200)
46
+ except Exception as exp:
47
+ print(f"[ERROR] {str(exp)}")
48
+ return JSONResponse(content={
49
+ "error":"internal Server error"
50
+ },status_code=500)
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
requirements.txt ADDED
Binary file (156 Bytes). View file