Upload 2 files
Browse files- function.yaml +64 -0
- main.py +47 -0
function.yaml
ADDED
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
metadata:
|
2 |
+
name: custom-model-yolov8
|
3 |
+
namespace: cvat
|
4 |
+
annotations:
|
5 |
+
name: custom-model-yolov8
|
6 |
+
type: detector
|
7 |
+
framework: pytorch
|
8 |
+
# change this accordingly to your model output/classes
|
9 |
+
spec: |
|
10 |
+
[
|
11 |
+
{"id": 0, "name": "tench"},
|
12 |
+
{"id": 1, "name": "goldfish"},
|
13 |
+
.
|
14 |
+
.
|
15 |
+
.
|
16 |
+
.
|
17 |
+
{"id": 998, "name": "ear"},
|
18 |
+
{"id": 999, "name": "toilet paper"}
|
19 |
+
]
|
20 |
+
spec:
|
21 |
+
description: custom-model-yolov8
|
22 |
+
runtime: 'python:3.9'
|
23 |
+
handler: main:handler
|
24 |
+
eventTimeout: 30s
|
25 |
+
|
26 |
+
build:
|
27 |
+
image: custom-model-yolov8
|
28 |
+
baseImage: ubuntu:22.04
|
29 |
+
|
30 |
+
directives:
|
31 |
+
preCopy:
|
32 |
+
- kind: ENV
|
33 |
+
value: DEBIAN_FRONTEND=noninteractive
|
34 |
+
- kind: RUN
|
35 |
+
value: apt-get update && apt-get -y install curl git python3 python3-pip
|
36 |
+
- kind: RUN
|
37 |
+
value: apt-get -y install libgl1-mesa-glx libglib2.0-dev
|
38 |
+
- kind: WORKDIR
|
39 |
+
value: /opt/nuclio
|
40 |
+
#
|
41 |
+
# make sure that for the next step (at least) the ultralytics package version
|
42 |
+
# is compatible to that of the the ultralytics package used to train the custom model
|
43 |
+
- kind: RUN
|
44 |
+
value: pip3 install ultralytics==8.0.114 opencv-python==4.7.0.72 numpy==1.24.3
|
45 |
+
#
|
46 |
+
- kind: RUN
|
47 |
+
value: ln -s /usr/bin/pip3 /usr/local/bin/pip
|
48 |
+
- kind: RUN
|
49 |
+
value: ln -s /usr/bin/python3 /usr/local/bin/python
|
50 |
+
|
51 |
+
triggers:
|
52 |
+
myHttpTrigger:
|
53 |
+
maxWorkers: 1
|
54 |
+
kind: 'http'
|
55 |
+
workerAvailabilityTimeoutMilliseconds: 10000
|
56 |
+
attributes:
|
57 |
+
maxRequestBodySize: 33554432 # 32MB
|
58 |
+
|
59 |
+
platform:
|
60 |
+
attributes:
|
61 |
+
restartPolicy:
|
62 |
+
name: always
|
63 |
+
maximumRetryCount: 3
|
64 |
+
mountMode: volume
|
main.py
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
import io
|
3 |
+
import base64
|
4 |
+
import json
|
5 |
+
|
6 |
+
import cv2
|
7 |
+
import numpy as np
|
8 |
+
from ultralytics import YOLO
|
9 |
+
|
10 |
+
# Initialize your model
|
11 |
+
def init_context(context):
|
12 |
+
context.logger.info('Init context... 0%')
|
13 |
+
model = YOLO('custom-yolov8n.pt')
|
14 |
+
context.user_data.model_handler = model
|
15 |
+
context.logger.info('Init context...100%')
|
16 |
+
|
17 |
+
# Inference endpoint
|
18 |
+
def handler(context, event):
|
19 |
+
context.logger.info('Run custom yolov8 model')
|
20 |
+
data = event.body
|
21 |
+
image_buffer = io.BytesIO(base64.b64decode(data['image']))
|
22 |
+
image = cv2.imdecode(np.frombuffer(image_buffer.getvalue(), np.uint8), cv2.IMREAD_COLOR)
|
23 |
+
|
24 |
+
results = context.user_data.model_handler(image)
|
25 |
+
result = results[0]
|
26 |
+
|
27 |
+
boxes = result.boxes.data[:,:4]
|
28 |
+
confs = result.boxes.conf
|
29 |
+
clss = result.boxes.cls
|
30 |
+
class_name = result.names
|
31 |
+
|
32 |
+
detections = []
|
33 |
+
threshold = 0.1
|
34 |
+
for box, conf, cls in zip(boxes, confs, clss):
|
35 |
+
label = class_name[int(cls)]
|
36 |
+
if conf >= threshold:
|
37 |
+
# must be in this format
|
38 |
+
detections.append({
|
39 |
+
'confidence': str(float(conf)),
|
40 |
+
'label': label,
|
41 |
+
'points': box.tolist(),
|
42 |
+
'type': 'rectangle',
|
43 |
+
})
|
44 |
+
|
45 |
+
return context.Response(body=json.dumps(detections), headers={},
|
46 |
+
content_type='application/json', status_code=200)
|
47 |
+
|