Spaces:
Runtime error
Runtime error
Commit
·
7bf08cb
1
Parent(s):
82df0e1
move custom library to code
Browse files- Dockerfile +0 -2
- app/custom_mmcv/color.py +52 -0
- libs/image.py → app/custom_mmcv/main.py +4 -57
- app/routers/image.py +5 -4
Dockerfile
CHANGED
@@ -19,8 +19,6 @@ COPY --chown=user . .
|
|
19 |
|
20 |
RUN pip install -r ./app/requirements.txt
|
21 |
|
22 |
-
COPY ./libs/image.py /home/user/.local/lib/python3.8/site-packages/mmcv/visualization/image.py
|
23 |
-
|
24 |
EXPOSE 3000
|
25 |
|
26 |
CMD [ "uvicorn", "app.main:app", "--host" ,"0.0.0.0" ,"--port", "3000"]
|
|
|
19 |
|
20 |
RUN pip install -r ./app/requirements.txt
|
21 |
|
|
|
|
|
22 |
EXPOSE 3000
|
23 |
|
24 |
CMD [ "uvicorn", "app.main:app", "--host" ,"0.0.0.0" ,"--port", "3000"]
|
app/custom_mmcv/color.py
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Copyright (c) OpenMMLab. All rights reserved.
|
2 |
+
from enum import Enum
|
3 |
+
from typing import Union
|
4 |
+
|
5 |
+
import numpy as np
|
6 |
+
from mmengine.utils import is_str
|
7 |
+
|
8 |
+
|
9 |
+
class Color(Enum):
|
10 |
+
"""An enum that defines common colors.
|
11 |
+
|
12 |
+
Contains red, green, blue, cyan, yellow, magenta, white and black.
|
13 |
+
"""
|
14 |
+
|
15 |
+
red = (0, 0, 255)
|
16 |
+
green = (0, 255, 0)
|
17 |
+
blue = (255, 0, 0)
|
18 |
+
cyan = (255, 255, 0)
|
19 |
+
yellow = (0, 255, 255)
|
20 |
+
magenta = (255, 0, 255)
|
21 |
+
white = (255, 255, 255)
|
22 |
+
black = (0, 0, 0)
|
23 |
+
|
24 |
+
|
25 |
+
def color_val(color: Union[Color, str, tuple, int, np.ndarray]) -> tuple:
|
26 |
+
"""Convert various input to color tuples.
|
27 |
+
|
28 |
+
Args:
|
29 |
+
color (:obj:`Color`/str/tuple/int/ndarray): Color inputs
|
30 |
+
|
31 |
+
Returns:
|
32 |
+
tuple[int]: A tuple of 3 integers indicating BGR channels.
|
33 |
+
"""
|
34 |
+
if is_str(color):
|
35 |
+
return Color[color].value # type: ignore
|
36 |
+
elif isinstance(color, Color):
|
37 |
+
return color.value
|
38 |
+
elif isinstance(color, tuple):
|
39 |
+
assert len(color) == 3
|
40 |
+
for channel in color:
|
41 |
+
assert 0 <= channel <= 255
|
42 |
+
return color
|
43 |
+
elif isinstance(color, int):
|
44 |
+
assert 0 <= color <= 255
|
45 |
+
return color, color, color
|
46 |
+
elif isinstance(color, np.ndarray):
|
47 |
+
assert color.ndim == 1 and color.size == 3
|
48 |
+
assert np.all((color >= 0) & (color <= 255))
|
49 |
+
color = color.astype(np.uint8)
|
50 |
+
return tuple(color)
|
51 |
+
else:
|
52 |
+
raise TypeError(f"Invalid type for color: {type(color)}")
|
libs/image.py → app/custom_mmcv/main.py
RENAMED
@@ -1,4 +1,6 @@
|
|
|
|
1 |
# Copyright (c) OpenMMLab. All rights reserved.
|
|
|
2 |
from typing import List, Optional, Union
|
3 |
|
4 |
import cv2
|
@@ -32,61 +34,6 @@ def imshow(img: Union[str, np.ndarray], win_name: str = "", wait_time: int = 0):
|
|
32 |
ret = cv2.waitKey(wait_time)
|
33 |
|
34 |
|
35 |
-
def imshow_bboxes(
|
36 |
-
img: Union[str, np.ndarray],
|
37 |
-
bboxes: Union[list, np.ndarray],
|
38 |
-
colors: ColorType = "green",
|
39 |
-
top_k: int = -1,
|
40 |
-
thickness: int = 1,
|
41 |
-
show: bool = True,
|
42 |
-
win_name: str = "",
|
43 |
-
wait_time: int = 0,
|
44 |
-
out_file: Optional[str] = None,
|
45 |
-
):
|
46 |
-
"""Draw bboxes on an image.
|
47 |
-
|
48 |
-
Args:
|
49 |
-
img (str or ndarray): The image to be displayed.
|
50 |
-
bboxes (list or ndarray): A list of ndarray of shape (k, 4).
|
51 |
-
colors (Color or str or tuple or int or ndarray): A list of colors.
|
52 |
-
top_k (int): Plot the first k bboxes only if set positive.
|
53 |
-
thickness (int): Thickness of lines.
|
54 |
-
show (bool): Whether to show the image.
|
55 |
-
win_name (str): The window name.
|
56 |
-
wait_time (int): Value of waitKey param.
|
57 |
-
out_file (str, optional): The filename to write the image.
|
58 |
-
|
59 |
-
Returns:
|
60 |
-
ndarray: The image with bboxes drawn on it.
|
61 |
-
"""
|
62 |
-
img = imread(img)
|
63 |
-
img = np.ascontiguousarray(img)
|
64 |
-
|
65 |
-
if isinstance(bboxes, np.ndarray):
|
66 |
-
bboxes = [bboxes]
|
67 |
-
if not isinstance(colors, list):
|
68 |
-
colors = [colors for _ in range(len(bboxes))]
|
69 |
-
colors = [color_val(c) for c in colors]
|
70 |
-
assert len(bboxes) == len(colors)
|
71 |
-
|
72 |
-
for i, _bboxes in enumerate(bboxes):
|
73 |
-
_bboxes = _bboxes.astype(np.int32)
|
74 |
-
if top_k <= 0:
|
75 |
-
_top_k = _bboxes.shape[0]
|
76 |
-
else:
|
77 |
-
_top_k = min(top_k, _bboxes.shape[0])
|
78 |
-
for j in range(_top_k):
|
79 |
-
left_top = (_bboxes[j, 0], _bboxes[j, 1])
|
80 |
-
right_bottom = (_bboxes[j, 2], _bboxes[j, 3])
|
81 |
-
cv2.rectangle(img, left_top, right_bottom, colors[i], thickness=thickness)
|
82 |
-
|
83 |
-
if show:
|
84 |
-
imshow(img, win_name, wait_time)
|
85 |
-
if out_file is not None:
|
86 |
-
imwrite(img, out_file)
|
87 |
-
return img
|
88 |
-
|
89 |
-
|
90 |
def imshow_det_bboxes(
|
91 |
img: Union[str, np.ndarray],
|
92 |
bboxes: np.ndarray,
|
@@ -132,7 +79,7 @@ def imshow_det_bboxes(
|
|
132 |
assert bboxes.shape[0] == labels.shape[0]
|
133 |
assert bboxes.shape[1] == 4 or bboxes.shape[1] == 5
|
134 |
img = imread(img)
|
135 |
-
|
136 |
if score_thr > 0:
|
137 |
assert bboxes.shape[1] == 5
|
138 |
scores = bboxes[:, -1]
|
@@ -160,7 +107,7 @@ def imshow_det_bboxes(
|
|
160 |
cv2.FONT_HERSHEY_TRIPLEX,
|
161 |
font_scale,
|
162 |
text_color,
|
163 |
-
4
|
164 |
)
|
165 |
|
166 |
if show:
|
|
|
1 |
+
# THE ORIGINAL mmcv.imshow_det_bboxes
|
2 |
# Copyright (c) OpenMMLab. All rights reserved.
|
3 |
+
|
4 |
from typing import List, Optional, Union
|
5 |
|
6 |
import cv2
|
|
|
34 |
ret = cv2.waitKey(wait_time)
|
35 |
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
def imshow_det_bboxes(
|
38 |
img: Union[str, np.ndarray],
|
39 |
bboxes: np.ndarray,
|
|
|
79 |
assert bboxes.shape[0] == labels.shape[0]
|
80 |
assert bboxes.shape[1] == 4 or bboxes.shape[1] == 5
|
81 |
img = imread(img)
|
82 |
+
|
83 |
if score_thr > 0:
|
84 |
assert bboxes.shape[1] == 5
|
85 |
scores = bboxes[:, -1]
|
|
|
107 |
cv2.FONT_HERSHEY_TRIPLEX,
|
108 |
font_scale,
|
109 |
text_color,
|
110 |
+
4,
|
111 |
)
|
112 |
|
113 |
if show:
|
app/routers/image.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1 |
from fastapi import APIRouter, File, Response, WebSocket, WebSocketDisconnect
|
2 |
-
import mmcv
|
3 |
import cv2
|
4 |
import numpy as np
|
5 |
from app.constants import classNames, colors
|
6 |
from app import detector
|
7 |
|
|
|
|
|
8 |
|
9 |
router = APIRouter(prefix="/image")
|
10 |
|
@@ -15,7 +16,7 @@ async def handleImageRequest(
|
|
15 |
threshold: float = 0.3,
|
16 |
raw: bool = False,
|
17 |
):
|
18 |
-
img =
|
19 |
if raw:
|
20 |
bboxes, labels = inferenceImage(img, threshold, raw)
|
21 |
return {"bboxes": bboxes.tolist(), "labels": labels.tolist()}
|
@@ -42,7 +43,7 @@ def inferenceImage(img, threshold: float, isRaw: bool = False):
|
|
42 |
labels = np.delete(labels, removeIndexs)
|
43 |
|
44 |
return bboxes, labels
|
45 |
-
return
|
46 |
img=img,
|
47 |
bboxes=bboxes,
|
48 |
labels=labels,
|
@@ -59,7 +60,7 @@ async def websocketEndpoint(websocket: WebSocket, threshold: float = 0.3):
|
|
59 |
try:
|
60 |
while True:
|
61 |
data = await websocket.receive_bytes()
|
62 |
-
img =
|
63 |
bboxes, labels = inferenceImage(img, threshold, True)
|
64 |
await websocket.send_json(
|
65 |
{"bboxes": bboxes.tolist(), "labels": labels.tolist()}
|
|
|
1 |
from fastapi import APIRouter, File, Response, WebSocket, WebSocketDisconnect
|
|
|
2 |
import cv2
|
3 |
import numpy as np
|
4 |
from app.constants import classNames, colors
|
5 |
from app import detector
|
6 |
|
7 |
+
from mmcv import imfrombytes
|
8 |
+
from app.custom_mmcv.main import imshow_det_bboxes
|
9 |
|
10 |
router = APIRouter(prefix="/image")
|
11 |
|
|
|
16 |
threshold: float = 0.3,
|
17 |
raw: bool = False,
|
18 |
):
|
19 |
+
img = imfrombytes(file, cv2.IMREAD_COLOR)
|
20 |
if raw:
|
21 |
bboxes, labels = inferenceImage(img, threshold, raw)
|
22 |
return {"bboxes": bboxes.tolist(), "labels": labels.tolist()}
|
|
|
43 |
labels = np.delete(labels, removeIndexs)
|
44 |
|
45 |
return bboxes, labels
|
46 |
+
return imshow_det_bboxes(
|
47 |
img=img,
|
48 |
bboxes=bboxes,
|
49 |
labels=labels,
|
|
|
60 |
try:
|
61 |
while True:
|
62 |
data = await websocket.receive_bytes()
|
63 |
+
img = imfrombytes(data, cv2.IMREAD_COLOR)
|
64 |
bboxes, labels = inferenceImage(img, threshold, True)
|
65 |
await websocket.send_json(
|
66 |
{"bboxes": bboxes.tolist(), "labels": labels.tolist()}
|