Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

readme.md #216

Open
wants to merge 45 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a4f5e24
Change video to end by breaking instead of error
theAIGuysCode Jul 8, 2020
6b0aa1a
Changing name of file to detect_video.py
theAIGuysCode Jul 8, 2020
f90e15d
Adding YAML file for Conda GPU environment
theAIGuysCode Jul 8, 2020
f70ff83
Add YAML for Conda CPU environment
theAIGuysCode Jul 8, 2020
9fda8e4
Change name of conda gpu env
theAIGuysCode Jul 8, 2020
bfb0ae4
Update README.md
theAIGuysCode Jul 9, 2020
994e24b
Add images folder
theAIGuysCode Jul 10, 2020
5947072
Delete girl.png
theAIGuysCode Jul 10, 2020
9e51859
Add files via upload
theAIGuysCode Jul 10, 2020
a32549a
Delete kite.jpg
theAIGuysCode Jul 10, 2020
84943a5
Add video folder
theAIGuysCode Jul 10, 2020
6c73940
Move road video to video folder.
theAIGuysCode Jul 10, 2020
d6da36c
Delete road.mp4
theAIGuysCode Jul 10, 2020
f25f216
Add helpers folder to store extra images.
theAIGuysCode Jul 10, 2020
ae9671a
Delete helpers
theAIGuysCode Jul 10, 2020
3f96343
Add helpers folder to store misc. photos.
theAIGuysCode Jul 10, 2020
12abf90
Move photos to helpers folder
theAIGuysCode Jul 10, 2020
22db370
Delete result.png
theAIGuysCode Jul 10, 2020
1f3530d
Delete result-int8.png
theAIGuysCode Jul 10, 2020
c13e177
Delete performance.png
theAIGuysCode Jul 10, 2020
bdff118
Update README with new image locations
theAIGuysCode Jul 10, 2020
0bf4748
Enable detections on multiple photos
theAIGuysCode Jul 10, 2020
9ac8ce0
Update demo commands
theAIGuysCode Jul 10, 2020
2b4e213
Update benchmarks.py
theAIGuysCode Jul 10, 2020
a4d9f59
Update README.md
theAIGuysCode Jul 11, 2020
145eff0
Add extra test image dog.jpg
theAIGuysCode Jul 11, 2020
6bbbc3b
Creating detections folder to save detections.
theAIGuysCode Jul 11, 2020
0224d0a
Upload test detection
theAIGuysCode Jul 11, 2020
f2130e8
Delete detection1.jpg
theAIGuysCode Jul 11, 2020
fb09481
Upload better test video
theAIGuysCode Jul 11, 2020
edfa56a
Allow webcam and saving of detection video.
theAIGuysCode Jul 11, 2020
919cb2e
Add helper image and video
theAIGuysCode Jul 11, 2020
97eb440
Upload custom model result
theAIGuysCode Jul 11, 2020
83ddfbc
Update README with all current commands
theAIGuysCode Jul 11, 2020
57f2f81
Update README.md
theAIGuysCode Jul 11, 2020
9ce7023
Update README.md
theAIGuysCode Jul 11, 2020
c9fa464
Update README.md
theAIGuysCode Jul 11, 2020
2fd2a45
Merge branch 'master' of https://github.com/hunglc007/tensorflow-yolo…
theAIGuysCode Jul 12, 2020
5d7294b
Merge branch 'master' of https://github.com/hunglc007/tensorflow-yolo…
theAIGuysCode Jul 24, 2020
25f4b5c
Update README.md
theAIGuysCode Jul 25, 2020
f21b61e
Update README.md
theAIGuysCode Jul 27, 2020
bb1ab51
Update README.md
theAIGuysCode Jul 27, 2020
d06d87d
Update detect.py with dont_show flag.
theAIGuysCode Aug 2, 2020
70e5c0f
Update detect_video.py with dont_show flag.
theAIGuysCode Aug 2, 2020
8340587
Enable filtering of allowed classes for images
theAIGuysCode Dec 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 164 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,62 +3,142 @@

YOLOv4, YOLOv4-tiny Implemented in Tensorflow 2.0.
Convert YOLO v4, YOLOv3, YOLO tiny .weights to .pb, .tflite and trt format for tensorflow, tensorflow lite, tensorRT.
<p align="center"><img src="data/helpers/demo.gif"\></p>

Download yolov4.weights file: https://drive.google.com/open?id=1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT
## Getting Started
### Conda (Recommended)

```bash
# Tensorflow CPU
conda env create -f conda-cpu.yml
conda activate yolov4-cpu

# Tensorflow GPU
conda env create -f conda-gpu.yml
conda activate yolov4-gpu
```

### Prerequisites
* Tensorflow 2.3.0rc0
### Pip
```bash
# TensorFlow CPU
pip install -r requirements.txt

# TensorFlow GPU
pip install -r requirements-gpu.txt
```
### Nvidia Driver (For GPU, if you are not using Conda Environment and haven't set up CUDA yet)
Make sure to use CUDA Toolkit version 10.1 as it is the proper version for the TensorFlow version used in this repository.
https://developer.nvidia.com/cuda-10.1-download-archive-update2

### Performance
<p align="center"><img src="data/performance.png" width="640"\></p>
Check out how YOLOv4 compares to other object detection systems.

<p align="center"><img src="data/helpers/performance.png" width="640"\></p>

## Downloading Official Pre-trained Weights
YOLOv4 comes pre-trained and able to detect 80 classes. For easy demo purposes we will use the pre-trained weights.
Download pre-trained yolov4.weights file: https://drive.google.com/open?id=1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT

Copy and paste yolov4.weights from your downloads folder into the 'data' folder of this repository.

If you want to use yolov4-tiny.weights, a smaller model that is faster at running detections but less accurate, download file here: https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v4_pre/yolov4-tiny.weights

## Using Custom Trained YOLOv4 Weights
<strong>Learn How To Train Custom YOLOv4 Weights here: https://www.youtube.com/watch?v=mmj3nxGT2YQ </strong>

USE MY LICENSE PLATE TRAINED CUSTOM WEIGHTS: https://drive.google.com/file/d/1EUPtbtdF0bjRtNjGv436vDY28EN5DXDH/view?usp=sharing

Copy and paste your custom .weights file into the 'data' folder and copy and paste your custom .names into the 'data/classes/' folder.

The only change within the code you need to make in order for your custom model to work is on line 14 of 'core/config.py' file.
Update the code to point at your custom .names file as seen below. (my custom .names file is called custom.names but yours might be named differently)
<p align="center"><img src="data/helpers/custom_config.png" width="640"\></p>

### Demo
<strong>Note:</strong> If you are using the pre-trained yolov4 then make sure that line 14 remains <strong>coco.names</strong>.

## YOLOv4 Using Tensorflow (tf, .pb model)
To implement YOLOv4 using TensorFlow, first we convert the .weights into the corresponding TensorFlow model files and then run the model.
```bash
# Convert darknet weights to tensorflow
## yolov4
python save_model.py --weights ./data/yolov4.weights --output ./checkpoints/yolov4-416 --input_size 416 --model yolov4

## yolov4-tiny
# yolov4-tiny
python save_model.py --weights ./data/yolov4-tiny.weights --output ./checkpoints/yolov4-tiny-416 --input_size 416 --model yolov4 --tiny

# Run demo tensorflow
python detect.py --weights ./checkpoints/yolov4-416 --size 416 --model yolov4 --image ./data/kite.jpg
# custom yolov4
python save_model.py --weights ./data/custom.weights --output ./checkpoints/custom-416 --input_size 416 --model yolov4

python detect.py --weights ./checkpoints/yolov4-tiny-416 --size 416 --model yolov4 --image ./data/kite.jpg --tiny
# Run yolov4 tensorflow model
python detect.py --weights ./checkpoints/yolov4-416 --size 416 --model yolov4 --images ./data/images/kite.jpg

# Run yolov4-tiny tensorflow model
python detect.py --weights ./checkpoints/yolov4-tiny-416 --size 416 --model yolov4 --images ./data/images/kite.jpg --tiny

# Run custom yolov4 tensorflow model
python detect.py --weights ./checkpoints/custom-416 --size 416 --model yolov4 --images ./data/images/car.jpg

# Run yolov4 on video
python detect_video.py --weights ./checkpoints/yolov4-416 --size 416 --model yolov4 --video ./data/video/video.mp4 --output ./detections/results.avi

# Run custom yolov4 model on video
python detect_video.py --weights ./checkpoints/custom-416 --size 416 --model yolov4 --video ./data/video/cars.mp4 --output ./detections/results.avi

# Run yolov4 on webcam
python detect_video.py --weights ./checkpoints/yolov4-416 --size 416 --model yolov4 --video 0 --output ./detections/results.avi
```
If you want to run yolov3 or yolov3-tiny change ``--model yolov3`` in command
If you want to run yolov3 or yolov3-tiny change ``--model yolov3`` and .weights file in above commands.

#### Output
<strong>Note:</strong> You can also run the detector on multiple images at once by changing the --images flag like such ``--images "./data/images/kite.jpg, ./data/images/dog.jpg"``

##### Yolov4 original weight
<p align="center"><img src="result.png" width="640"\></p>
### Result Image(s) (Regular TensorFlow)
You can find the outputted image(s) showing the detections saved within the 'detections' folder.
#### Pre-trained YOLOv4 Model Example
<p align="center"><img src="data/helpers/result.png" width="640"\></p>

##### Yolov4 tflite int8
<p align="center"><img src="result-int8.png" width="640"\></p>
#### Custom YOLOv4 Model Example (see video link above to train this model)
<p align="center"><img src="data/helpers/custom_result.png" width="640"\></p>

### Convert to tflite
### Result Video
Video saves wherever you point --output flag to. If you don't set the flag then your video will not be saved with detections on it.
<p align="center"><img src="data/helpers/demo.gif"\></p>

## YOLOv4 Using TensorFlow Lite (.tflite model)
Can also implement YOLOv4 using TensorFlow Lite. TensorFlow Lite is a much smaller model and perfect for mobile or edge devices (raspberry pi, etc).
```bash
# Save tf model for tflite converting
python save_model.py --weights ./data/yolov4.weights --output ./checkpoints/yolov4-416 --input_size 416 --model yolov4 --framework tflite

# Save custom yolov4 tf model for tflite converting
python save_model.py --weights ./data/custom.weights --output ./checkpoints/custom-416 --input_size 416 --model yolov4 --framework tflite

# yolov4
python convert_tflite.py --weights ./checkpoints/yolov4-416 --output ./checkpoints/yolov4-416.tflite

# convert custom yolov4 tflite model
python convert_tflite.py --weights ./checkpoints/custom-416 --output ./checkpoints/custom-416.tflite

# yolov4 quantize float16
python convert_tflite.py --weights ./checkpoints/yolov4-416 --output ./checkpoints/yolov4-416-fp16.tflite --quantize_mode float16

# yolov4 quantize int8
python convert_tflite.py --weights ./checkpoints/yolov4-416 --output ./checkpoints/yolov4-416-int8.tflite --quantize_mode int8 --dataset ./coco_dataset/coco/val207.txt

# Run demo tflite model
python detect.py --weights ./checkpoints/yolov4-416.tflite --size 416 --model yolov4 --image ./data/kite.jpg --framework tflite
# Run tflite model
python detect.py --weights ./checkpoints/yolov4-416.tflite --size 416 --model yolov4 --images ./data/images/kite.jpg --framework tflite

# Run custom tflite model
python detect.py --weights ./checkpoints/custom-416.tflite --size 416 --model yolov4 --images ./data/images/car.jpg --framework tflite
```
### Result Image (TensorFlow Lite)
You can find the outputted image(s) showing the detections saved within the 'detections' folder.
#### TensorFlow Lite int8 Example
<p align="center"><img src="data/helpers/result-int8.png" width="640"\></p>

Yolov4 and Yolov4-tiny int8 quantization have some issues. I will try to fix that. You can try Yolov3 and Yolov3-tiny int8 quantization
### Convert to TensorRT

## YOLOv4 Using TensorRT
Can also implement YOLOv4 using TensorFlow's TensorRT. TensorRT is a high-performance inference optimizer and runtime that can be used to perform inference in lower precision (FP16 and INT8) on GPUs. TensorRT can allow up to 8x higher performance than regular TensorFlow.
```bash# yolov3
python save_model.py --weights ./data/yolov3.weights --output ./checkpoints/yolov3.tf --input_size 416 --model yolov3
python convert_trt.py --weights ./checkpoints/yolov3.tf --quantize_mode float16 --output ./checkpoints/yolov3-trt-fp16-416
Expand All @@ -70,9 +150,70 @@ python convert_trt.py --weights ./checkpoints/yolov3-tiny.tf --quantize_mode flo
# yolov4
python save_model.py --weights ./data/yolov4.weights --output ./checkpoints/yolov4.tf --input_size 416 --model yolov4
python convert_trt.py --weights ./checkpoints/yolov4.tf --quantize_mode float16 --output ./checkpoints/yolov4-trt-fp16-416
python detect.py --weights ./checkpoints/yolov4-trt-fp16-416 --model yolov4 --images ./data/images/kite.jpg --framework trt
```

### Evaluate on COCO 2017 Dataset
## Command Line Args Reference

```bash
save_model.py:
--weights: path to weights file
(default: './data/yolov4.weights')
--output: path to output
(default: './checkpoints/yolov4-416')
--[no]tiny: yolov4 or yolov4-tiny
(default: 'False')
--input_size: define input size of export model
(default: 416)
--framework: what framework to use (tf, trt, tflite)
(default: tf)
--model: yolov3 or yolov4
(default: yolov4)

detect.py:
--images: path to input images as a string with images separated by ","
(default: './data/images/kite.jpg')
--output: path to output folder
(default: './detections/')
--[no]tiny: yolov4 or yolov4-tiny
(default: 'False')
--weights: path to weights file
(default: './checkpoints/yolov4-416')
--framework: what framework to use (tf, trt, tflite)
(default: tf)
--model: yolov3 or yolov4
(default: yolov4)
--size: resize images to
(default: 416)
--iou: iou threshold
(default: 0.45)
--score: confidence threshold
(default: 0.25)

detect_video.py:
--video: path to input video (use 0 for webcam)
(default: './data/video/video.mp4')
--output: path to output video (remember to set right codec for given format. e.g. XVID for .avi)
(default: None)
--output_format: codec used in VideoWriter when saving video to file
(default: 'XVID)
--[no]tiny: yolov4 or yolov4-tiny
(default: 'false')
--weights: path to weights file
(default: './checkpoints/yolov4-416')
--framework: what framework to use (tf, trt, tflite)
(default: tf)
--model: yolov3 or yolov4
(default: yolov4)
--size: resize images to
(default: 416)
--iou: iou threshold
(default: 0.45)
--score: confidence threshold
(default: 0.25)
```

## Evaluate on COCO 2017 Dataset
```bash
# run script in /script/get_coco_dataset_2017.sh to download COCO 2017 Dataset
# preprocess coco dataset
Expand All @@ -98,7 +239,7 @@ python main.py --output results_yolov4_tf
| YoloV3 | 55.43 | 52.32 | |
| YoloV4 | 61.96 | 57.33 | |

### Benchmark
## Benchmark
```bash
python benchmarks.py --size 416 --model yolov4 --weights ./data/yolov4.weights
```
Expand Down Expand Up @@ -144,7 +285,7 @@ python benchmarks.py --size 416 --model yolov4 --weights ./data/yolov4.weights
| YoloV3 FPS | | | |
| YoloV4 FPS | | | |

### Traning your own model
## Traning your own model in TensorFlow
```bash
# Prepare your dataset
# If you want to train from scratch:
Expand All @@ -157,7 +298,7 @@ python train.py --weights ./data/yolov4.weights
```
The training performance is not fully reproduced yet, so I recommended to use Alex's [Darknet](https://github.com/AlexeyAB/darknet) to train your own data, then convert the .weights to tensorflow or tflite.


<strong>Use this video to train your own model easily in Google Colab: https://www.youtube.com/watch?v=mmj3nxGT2YQ </strong>

### TODO
* [x] Convert YOLOv4 to TensorRT
Expand Down
2 changes: 1 addition & 1 deletion benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
flags.DEFINE_string('framework', 'tf', '(tf, tflite, trt')
flags.DEFINE_string('model', 'yolov4', 'yolov3 or yolov4')
flags.DEFINE_string('weights', './data/yolov4.weights', 'path to weights file')
flags.DEFINE_string('image', './data/kite.jpg', 'path to input image')
flags.DEFINE_string('images', './data/images/kite.jpg', 'path to input image')
flags.DEFINE_integer('size', 416, 'resize images to')


Expand Down
15 changes: 15 additions & 0 deletions conda-cpu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: yolov4-cpu

dependencies:
- python==3.7
- pip
- matplotlib
- opencv
- pip:
- opencv-python==4.1.1.26
- lxml
- tqdm
- tensorflow==2.3.0rc0
- absl-py
- easydict
- pillow
17 changes: 17 additions & 0 deletions conda-gpu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: yolov4-gpu

dependencies:
- python==3.7
- pip
- matplotlib
- opencv
- cudnn
- cudatoolkit==10.1.243
- pip:
- tensorflow-gpu==2.3.0rc0
- opencv-python==4.1.1.26
- lxml
- tqdm
- absl-py
- easydict
- pillow
34 changes: 20 additions & 14 deletions core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def image_preprocess(image, target_size, gt_boxes=None):
gt_boxes[:, [1, 3]] = gt_boxes[:, [1, 3]] * scale + dh
return image_paded, gt_boxes

def draw_bbox(image, bboxes, classes=read_class_names(cfg.YOLO.CLASSES), show_label=True):
def draw_bbox(image, bboxes, classes=read_class_names(cfg.YOLO.CLASSES), allowed_classes=list(read_class_names(cfg.YOLO.CLASSES).values()), show_label=True):
num_classes = len(classes)
image_h, image_w, _ = image.shape
hsv_tuples = [(1.0 * x / num_classes, 1., 1.) for x in range(num_classes)]
Expand All @@ -147,19 +147,25 @@ def draw_bbox(image, bboxes, classes=read_class_names(cfg.YOLO.CLASSES), show_la
fontScale = 0.5
score = out_scores[0][i]
class_ind = int(out_classes[0][i])
bbox_color = colors[class_ind]
bbox_thick = int(0.6 * (image_h + image_w) / 600)
c1, c2 = (coor[1], coor[0]), (coor[3], coor[2])
cv2.rectangle(image, c1, c2, bbox_color, bbox_thick)

if show_label:
bbox_mess = '%s: %.2f' % (classes[class_ind], score)
t_size = cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)[0]
c3 = (c1[0] + t_size[0], c1[1] - t_size[1] - 3)
cv2.rectangle(image, c1, (np.float32(c3[0]), np.float32(c3[1])), bbox_color, -1) #filled

cv2.putText(image, bbox_mess, (c1[0], np.float32(c1[1] - 2)), cv2.FONT_HERSHEY_SIMPLEX,
fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA)
class_name = classes[class_ind]

# check if class is in allowed classes
if class_name not in allowed_classes:
continue
else:
bbox_color = colors[class_ind]
bbox_thick = int(0.6 * (image_h + image_w) / 600)
c1, c2 = (coor[1], coor[0]), (coor[3], coor[2])
cv2.rectangle(image, c1, c2, bbox_color, bbox_thick)

if show_label:
bbox_mess = '%s: %.2f' % (classes[class_ind], score)
t_size = cv2.getTextSize(bbox_mess, 0, fontScale, thickness=bbox_thick // 2)[0]
c3 = (c1[0] + t_size[0], c1[1] - t_size[1] - 3)
cv2.rectangle(image, c1, (np.float32(c3[0]), np.float32(c3[1])), bbox_color, -1) #filled

cv2.putText(image, bbox_mess, (c1[0], np.float32(c1[1] - 2)), cv2.FONT_HERSHEY_SIMPLEX,
fontScale, (0, 0, 0), bbox_thick // 2, lineType=cv2.LINE_AA)
return image

def bbox_iou(bboxes1, bboxes2):
Expand Down
Binary file removed data/girl.png
Binary file not shown.
Binary file added data/helpers/custom_config.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/helpers/custom_result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/helpers/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Binary file added data/helpers/result.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added data/images/dog.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes.
Binary file added data/video/video.mp4
Binary file not shown.
Loading