Skip to content

Commit 65808e8

Browse files
authored
Merge pull request #5 from BMW-InnovationLab/dev
Yolov4-v3 OPENCV inference
2 parents c97d84c + 79553d2 commit 65808e8

File tree

11 files changed

+120
-42
lines changed

11 files changed

+120
-42
lines changed

README.md

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# YOLO v3 CPU Inference API for Windows and Linux
1+
# YOLO v4-v3 CPU Inference API for Windows and Linux
22

3-
This is a repository for an object detection inference API using the Yolov3 Opencv.
3+
This is a repository for an object detection inference API using the Yolov4 and Yolo v3 Opencv.
44

55
The inference REST API works on CPU and doesn't require any GPU usage. It's supported on both Windows and Linux Operating systems.
66

7-
Models trained using our training Yolov3 repository can be deployed in this API. Several object detection models can be loaded and used at the same time.
7+
Models trained using our training Yolov4 or Yolov3 repository can be deployed in this API. Several object detection models can be loaded and used at the same time.
88

99
![predict image](./docs/4.gif)
1010

@@ -44,13 +44,12 @@ To [install Docker on Windows](https://docs.docker.com/docker-for-windows/instal
4444
In order to build the project run the following command from the project's root directory:
4545

4646
```sh
47-
sudo docker build -t yolov3_inference_api_cpu -f ./docker/dockerfile .
47+
sudo docker build -t yolov4_inference_api_cpu -f ./docker/dockerfile .
4848
```
4949
### Behind a proxy
5050

5151
```sh
52-
sudo docker build --build-arg http_proxy='' --build-arg https_proxy='' -t yolov3_inference_api_cpu -f ./docker/dockerfile .
53-
52+
sudo docker build --build-arg http_proxy='' --build-arg https_proxy='' -t yolov4_inference_api_cpu -f ./docker/dockerfile .
5453
```
5554

5655
## Run The Docker Container
@@ -60,12 +59,12 @@ To run the API, go the to the API's directory and run the following:
6059
#### Using Linux based docker:
6160

6261
```sh
63-
sudo docker run -itv $(pwd)/models:/models -p <docker_host_port>:7770 yolov3_inference_api_cpu
62+
sudo docker run -itv $(pwd)/models:/models -p <docker_host_port>:7770 yolov4_inference_api_cpu
6463
```
6564
#### Using Windows based docker:
6665

6766
```sh
68-
docker run -itv ${PWD}/models:/models -p <docker_host_port>:7770 yolov3_inference_api_cpu
67+
docker run -itv ${PWD}/models:/models -p <docker_host_port>:7770 yolov4_inference_api_cpu
6968
```
7069

7170
The <docker_host_port> can be any unique port of your choice.
@@ -150,7 +149,7 @@ Inside each subfolder there should be a:
150149

151150
```json
152151
{
153-
"inference_engine_name": "yolov3_opencv_cpu_detection",
152+
"inference_engine_name": "yolov4_opencv_cpu_detection",
154153
"confidence": 60,
155154
"nms_threshold": 0.6,
156155
"image": {
@@ -171,6 +170,9 @@ Inside each subfolder there should be a:
171170
}
172171
```
173172
P.S
173+
174+
- You can choose **"inference_engine_name"**: between **yolov4_opencv_cpu_detection** and **yolov3_opencv_cpu_detection** depending on the model you have.
175+
174176
- You can change confidence and nms_threshold values while running the API
175177
- The API will return bounding boxes with a confidence higher than the "confidence" value. A high "confidence" can show you only accurate predictions
176178

@@ -180,26 +182,23 @@ Inside each subfolder there should be a:
180182
<thead align="center">
181183
<tr>
182184
<th></th>
183-
<th>Windows</th>
184185
<th colspan=3>Ubuntu</th>
185186
</tr>
186187
</thead>
187188
<thead align="center">
188189
<tr>
189190
<th>Network\Hardware</th>
190191
<th>Intel Xeon CPU 2.3 GHz</th>
191-
<th>Intel Xeon CPU 2.3 GHz</th>
192192
<th>Intel Core i9-7900 3.3 GHZ</th>
193-
<th>GeForce GTX 1080</th>
193+
<th>Tesla V100</th>
194194
</tr>
195195
</thead>
196196
<tbody align="center">
197197
<tr>
198-
<td>pascalvoc_dataset</td>
199-
<td>0.885 seconds/image</td>
200-
<td>0.793 seconds/image</td>
201-
<td>0.295 seconds/image</td>
202-
<td>0.0592 seconds/image</td>
198+
<td>COCO Dataset</td>
199+
<td>0.259 seconds/image</td>
200+
<td>0.281 seconds/image</td>
201+
<td>0.0691 seconds/image</td>
203202
</tr>
204203
</tbody>
205204
</table>
@@ -213,3 +212,5 @@ Inside each subfolder there should be a:
213212
Antoine Charbel, inmind.ai , Beirut, Lebanon
214213

215214
Daniel Anani, inmind.ai, Beirut, Lebanon
215+
216+
Hadi Koubeissy, Beirut, Lebanon

docker/dockerfile

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,51 @@ FROM python:3.6
33
LABEL maintainer="[email protected]"
44

55
COPY docker/requirements.txt .
6+
ENV HOME /root
67

78
COPY src/main /main
89

10+
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y --no-install-recommends install \
11+
locales \
12+
wget \
13+
software-properties-common \
14+
ca-certificates \
15+
build-essential \
16+
cmake \
17+
git \
18+
libopencv-dev \
19+
python3-dev \
20+
python3-pip \
21+
libgtk2.0-dev\
22+
pkg-config\
23+
&& apt-get -y autoremove \
24+
&& apt-get clean \
25+
&& pip3 install setuptools wheel \
26+
&& rm -rf /var/lib/apt/lists/{apt,dpkg,cache,log} /tmp/* /var/tmp/*
27+
928
RUN pip install -r requirements.txt
1029

11-
WORKDIR /main
1230

31+
WORKDIR ${HOME}
32+
#Checkout version should be 4.4.0 when the new version is released
33+
RUN git clone http://github.com/opencv/opencv.git && cd opencv \
34+
&& git checkout 4.4.0 \
35+
&& mkdir build && cd build \
36+
&& cmake -D CMAKE_BUILD_TYPE=RELEASE \
37+
-D CMAKE_INSTALL_PREFIX=/usr/local \
38+
-D WITH_CUDA=OFF \
39+
-D WITH_OPENCL=OFF \
40+
-D ENABLE_FAST_MATH=1 \
41+
-D CUDA_FAST_MATH=1 \
42+
-D WITH_CUBLAS=1 \
43+
-D BUILD_DOCS=OFF \
44+
-D BUILD_PERF_TESTS=OFF \
45+
-D BUILD_TESTS=OFF \
46+
.. \
47+
&& make -j `nproc` \
48+
&& make install \
49+
&& cd ${HOME} && rm -rf ./opencv/
50+
51+
52+
WORKDIR /main
1353
CMD ["uvicorn", "start:app", "--host", "0.0.0.0", "--port", "7770"]

docs/1.gif

-195 KB
Loading

docs/2.gif

291 KB
Loading

docs/3.gif

2.22 MB
Loading

docs/4.gif

7.7 MB
Loading

src/.DS_Store

6 KB
Binary file not shown.

src/main/deep_learning_service.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ def get_labels(self, model_name):
130130
:param model_name: Model name
131131
:return: List of model labels
132132
"""
133+
if model_name not in self.models_hash_dict and model_name not in self.models_hash_dict.values():
134+
raise ModelNotFound
133135
if not self.model_loaded(model_name):
134136
self.load_model(model_name)
135137
return self.models_dict[model_name].labels
@@ -140,6 +142,8 @@ def get_labels_custom(self, model_name):
140142
:param model_name: Model name
141143
:return: A list of mode's labels with their hashed values
142144
"""
145+
if model_name not in self.models_hash_dict and model_name not in self.models_hash_dict.values():
146+
raise ModelNotFound
143147
if re.match(r'[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}', model_name,
144148
flags=0):
145149
for key, value in self.models_hash_dict.items():
@@ -162,6 +166,8 @@ def get_config(self, model_name):
162166
:param model_name: Model name
163167
:return: List of model's configuration
164168
"""
169+
if model_name not in self.models_hash_dict and model_name not in self.models_hash_dict.values():
170+
raise ModelNotFound
165171
if not self.model_loaded(model_name):
166172
self.load_model(model_name)
167173
return self.models_dict[model_name].configuration

src/main/inference/inference_engines_factory.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ def get_engine(path_to_model):
2626
try:
2727
# import one of the available inference engine class (in this project there's only one), and return a
2828
# model instance
29-
return getattr(__import__(inference_engine_name), 'InferenceEngine')(path_to_model)
29+
if inference_engine_name=='yolov3_opencv_cpu_detection' or inference_engine_name=='yolov4_opencv_cpu_detection':
30+
return getattr(__import__("yolo_opencv_cpu_detection"), 'InferenceEngine')(path_to_model)
3031
except ApplicationError as e:
3132
raise e
3233
except Exception as e:

src/main/inference/yolov3_opencv_cpu_detection.py renamed to src/main/inference/yolo_opencv_cpu_detection.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def load(self):
3636
with open(os.path.join(self.model_path, 'obj.names'), 'r') as f:
3737
self.labels = [line.strip() for line in f.readlines()]
3838
self.net = cv2.dnn.readNet(os.path.join(self.model_path, 'yolo-obj.cfg'),
39-
os.path.join(self.model_path, 'yolo-obj.weights'))
39+
os.path.join(self.model_path, 'yolo-obj.weights'),'darknet')
4040

4141
async def infer(self, input_data, draw, predict_batch):
4242
await asyncio.sleep(0.00001)
@@ -55,10 +55,10 @@ async def infer(self, input_data, draw, predict_batch):
5555
height, width, depth = np_image.shape
5656
# create input blob
5757
blob = cv2.dnn.blobFromImage(
58-
np_image, self.scale, (self.image_width, self.image_height), (self.R_mean, self.G_mean, self.B_mean),
59-
self.swapRB, self.crop)
58+
np_image, size=(self.image_width, self.image_height), swapRB=self.swapRB, ddepth=cv2.CV_8U)
59+
6060
# feed the blob to the network
61-
self.net.setInput(blob)
61+
self.net.setInput(blob, scalefactor=self.scale, mean=[self.R_mean,self.G_mean,self.B_mean])
6262
# get the output layers
6363
output_layers = self.net.forward(self.__get_output_layers__())
6464
# for each detection from each output layer
@@ -87,13 +87,7 @@ async def infer(self, input_data, draw, predict_batch):
8787
remaining_indices = cv2.dnn.NMSBoxes(
8888
boxes, confidences, conf_threshold, nms_threshold)
8989

90-
for i in range(len(boxes)):
91-
# i = i[0]
92-
box = boxes[i]
93-
x = box[0]
94-
y = box[1]
95-
w = box[2]
96-
h = box[3]
90+
9791

9892
# release resources
9993
cv2.destroyAllWindows()
@@ -115,7 +109,7 @@ async def infer(self, input_data, draw, predict_batch):
115109

116110
if (left < 0):
117111
left = 0
118-
if (right > height- 1):
112+
if (right > width- 1):
119113
right = width - 1
120114
if (top < 0):
121115
top = 0

0 commit comments

Comments
 (0)