YOLOv2是Joseph Redmon提出的针对YOLO算法不足的改进版本,作者使用了一系列的方法对原来的YOLO多目标检测框架进行了改进,在保持原有速度的优势之下,精度上得以提升,此外作者提出了一种目标分类与检测的联合训练方法,通过这种方法YOLO9000可以同时在COCO和ImageNet数据集中进行训练,训练后的模型可以实现多达9000种物体的实时检测。
Paper:https://arxiv.org/abs/1612.08242
Github:https://github.com/pjreddie/darknet
Website:https://pjreddie.com/darknet/yolo
作者为YOLO算法设计了独有的深度学习框架darknet,因此没有提供Python的接口。在实验中,我找到了两种在Python 3中使用YOLOv2网络的方法。
第一种:为darknet添加Python接口
Github:https://github.com/SidHard/py-yolo2
该项目使用了原始的darknet网络,需要使用cmake重新编译源码,因此在Linux上使用更为方便一些。
首先从git上下载该项目
git clone https://github.com/SidHard/py-yolo2.git
执行cmake生成项目
cmake .. && make
最后执行yolo.py测试项目,相应的网络结构.cfg文件保存在cfg文件夹中,权值.weight文件放在根目录下,这些可以从darknet的官方网站上下载使用。
第二种:使用keras
Github:https://github.com/allanzelener/YAD2K
该项目使用了keras与tensorflow-gpu,因此可以在任何使用该框架的环境下运行,我在自己的程序中使用的该种方法。
首先下载源文件并且配置环境,可以使用anaconda环境或者在全局安装。
git clone https://github.com/allanzelener/yad2k.git
cd yad2k
# [Option 1] To replicate the conda environment:
conda env create -f environment.yml
source activate yad2k
# [Option 2] Install everything globaly.
pip install numpy
pip install tensorflow-gpu # CPU-only: conda install -c conda-forge tensorflow
pip install keras # Possibly older release: conda install keras
快速开始
- 从Darknet官方下载model:official YOLO website.
wget http://pjreddie.com/media/files/yolo.weights
- 将 Darknet YOLO_v2 model转换为Keras model.
./yad2k.py cfg/yolo.cfg yolo.weights model_data/yolo.h5
- 测试图片位于
images/
文件夹.
./test_yolo.py model_data/yolo.h5
最后执行test_yolo就可以执行网络,在images/out/文件夹里可以看到执行效果。
dog.jpg eagle.jpg giraffe.jpg horses.jpg为了方便模型用于测试视频与图片,我对demo做了修改,相比原来的测试代码,能够直接移植到项目中去,对象化的程序也更易于修改,代码如下
#! /usr/bin/env python
"""Run a YOLO_v2 style detection model on test images."""
import cv2
import os
import time
import numpy as np
from keras import backend as K
from keras.models import load_model
from yad2k.models.keras_yolo import yolo_eval, yolo_head
class YOLO(object):
def __init__(self):
self.model_path = 'model_data/yolo.h5'
self.anchors_path = 'model_data/yolo_anchors.txt'
self.classes_path = 'model_data/coco_classes.txt'
self.score = 0.3
self.iou = 0.5
self.class_names = self._get_class()
self.anchors = self._get_anchors()
self.sess = K.get_session()
self.boxes, self.scores, self.classes = self.generate()
def _get_class(self):
classes_path = os.path.expanduser(self.classes_path)
with open(classes_path) as f:
class_names = f.readlines()
class_names = [c.strip() for c in class_names]
return class_names
def _get_anchors(self):
anchors_path = os.path.expanduser(self.anchors_path)
with open(anchors_path) as f:
anchors = f.readline()
anchors = [float(x) for x in anchors.split(',')]
anchors = np.array(anchors).reshape(-1, 2)
return anchors
def generate(self):
model_path = os.path.expanduser(self.model_path)
assert model_path.endswith('.h5'), 'Keras model must be a .h5 file.'
self.yolo_model = load_model(model_path)
# Verify model, anchors, and classes are compatible
num_classes = len(self.class_names)
num_anchors = len(self.anchors)
# TODO: Assumes dim ordering is channel last
model_output_channels = self.yolo_model.layers[-1].output_shape[-1]
assert model_output_channels == num_anchors * (num_classes + 5), \
'Mismatch between model and given anchor and class sizes'
print('{} model, anchors, and classes loaded.'.format(model_path))
# Check if model is fully convolutional, assuming channel last order.
self.model_image_size = self.yolo_model.layers[0].input_shape[1:3]
self.is_fixed_size = self.model_image_size != (None, None)
# Generate output tensor targets for filtered bounding boxes.
# TODO: Wrap these backend operations with Keras layers.
yolo_outputs = yolo_head(self.yolo_model.output, self.anchors, len(self.class_names))
self.input_image_shape = K.placeholder(shape=(2, ))
boxes, scores, classes = yolo_eval(yolo_outputs, self.input_image_shape, score_threshold=self.score, iou_threshold=self.iou)
return boxes, scores, classes
def detect_image(self, image):
start = time.time()
y, x, _ = image.shape
if self.is_fixed_size: # TODO: When resizing we can use minibatch input.
resized_image = cv2.resize(image, tuple(reversed(self.model_image_size)), interpolation=cv2.INTER_CUBIC)
image_data = np.array(resized_image, dtype='float32')
else:
image_data = np.array(image, dtype='float32')
image_data /= 255.
image_data = np.expand_dims(image_data, 0) # Add batch dimension.
out_boxes, out_scores, out_classes = self.sess.run(
[self.boxes, self.scores, self.classes],
feed_dict={
self.yolo_model.input: image_data,
self.input_image_shape: [image.shape[0], image.shape[1]],
K.learning_phase(): 0
})
print('Found {} boxes for {}'.format(len(out_boxes), 'img'))
for i, c in reversed(list(enumerate(out_classes))):
predicted_class = self.class_names[c]
box = out_boxes[i]
score = out_scores[i]
label = '{} {:.2f}'.format(predicted_class, score)
top, left, bottom, right = box
top = max(0, np.floor(top + 0.5).astype('int32'))
left = max(0, np.floor(left + 0.5).astype('int32'))
bottom = min(y, np.floor(bottom + 0.5).astype('int32'))
right = min(x, np.floor(right + 0.5).astype('int32'))
print(label, (left, top), (right, bottom))
cv2.rectangle(image, (left, top), (right, bottom), (255, 0, 0), 2)
cv2.putText(image, label, (left, int(top - 4)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1, cv2.LINE_AA)
end = time.time()
print(end - start)
return image
def close_session(self):
self.sess.close()
def detect_vedio(video, yolo):
camera = cv2.VideoCapture(video)
cv2.namedWindow("detection", cv2.WINDOW_NORMAL)
while True:
res, frame = camera.read()
if not res:
break
image = yolo.detect_image(frame)
cv2.imshow("detection", image)
if cv2.waitKey(110) & 0xff == 27:
break
yolo.close_session()
def detect_img(img, yolo):
image = cv2.imread(img)
r_image = yolo.detect_image(image)
cv2.namedWindow("detection")
while True:
cv2.imshow("detection", r_image)
if cv2.waitKey(110) & 0xff == 27:
break
yolo.close_session()
if __name__ == '__main__':
yolo = YOLO()
img = 'E:\Documents\Downloads\YAD2K-master\YAD2K-master\images\horses.jpg'
video = 'E:\Documents\Documents\python\Traffic\data\person.avi'
detect_img(img, yolo)
detect_vedio(video, yolo)
网友评论
File "yad2k.py", line 270, in
Loading weights.
Weights Header: [1936876918 544108393 1886680168 791624307]
Parsing Darknet config.
_main(parser.parse_args())
File "yad2k.py", line 91, in _main
cfg_parser.read_file(unique_config_file)
File "/opt/conda/lib/python3.6/configparser.py", line 718, in read_file
self._read(f, source)
File "/opt/conda/lib/python3.6/configparser.py", line 1080, in _read
raise MissingSectionHeaderError(fpname, lineno, line)
configparser.MissingSectionHeaderError: File contains no section headers.
file: '', line: 1
'version https://git-lfs.github.com/spec/v1\n'
请问下总是报这种错误,是yolo.weights文件有问题吗?
File "/home/god/anaconda3/envs/tensorflow/lib/python3.5/site-packages/numpy/core/numeric.py", line 531, in asarray
Convert a list into an array:
TypeError: float() argument must be a string or a number, not 'dict'
能帮我看看是什么错误吗?
warnings.warn('No training configuration found in save file: '作者你好,我在测试的时候会先报这个错误,然后就显示在图中没有找到boxes Found 0 boxes for dog.jpg请问这个问题应该怎么解决
Traceback (most recent call last):
File "F:/python/pycharm/workspace/YAD2K-master/retrain_yolo.py", line 367, in <module>
_main(args)
File "F:/python/pycharm/workspace/YAD2K-master/retrain_yolo.py", line 60, in _main
image_data, boxes = process_data(data)
File "F:/python/pycharm/workspace/YAD2K-master/retrain_yolo.py", line 166, in process_data
return np.array(processed_images), np.array(boxes)
ValueError: could not broadcast input array from shape (416,416,3) into shape (416,416)
这个问题该如何解决呢?
usage: test_yolo.py [-h] [-a ANCHORS_PATH] [-c CLASSES_PATH] [-t TEST_PATH]
[-o OUTPUT_PATH] [-s SCORE_THRESHOLD] [-iou IOU_THRESHOLD]
model_path
test_yolo.py: error: the following arguments are required: model_path
Process finished with exit code 2
楼主,我的这个报错是什么意思呀
Traceback (most recent call last):
File "test_yolo.py", line 190, in <module>
_main(parser.parse_args())
File "test_yolo.py", line 76, in _main
yolo_model = load_model(model_path)
File "F:\python\anaconda\lib\site-packages\keras\models.py", line 243, in load_model
model = model_from_config(model_config, custom_objects=custom_objects)
File "F:\python\anaconda\lib\site-packages\keras\models.py", line 317, in model_from_config
return layer_module.deserialize(config, custom_objects=custom_objects)
File "F:\python\anaconda\lib\site-packages\keras\layers\__init__.py", line 55, in deserialize
printable_module_name='layer')
File "F:\python\anaconda\lib\site-packages\keras\utils\generic_utils.py", line 144, in deserialize_keras_object
list(custom_objects.items())))
File "F:\python\anaconda\lib\site-packages\keras\engine\topology.py", line 2520, in from_config
process_node(layer, node_data)
File "F:\python\anaconda\lib\site-packages\keras\engine\topology.py", line 2479, in process_node
layer(input_tensors, **kwargs)
File "F:\python\anaconda\lib\site-packages\keras\engine\topology.py", line 617, in __call__
output = self.call(inputs, **kwargs)
File "F:\python\anaconda\lib\site-packages\keras\layers\core.py", line 663, in call
return self.function(inputs, **arguments)
File "F:\python\pycharm\workspace\YAD2K-master\yad2k\models\keras_yolo.py", line 199, in yolo_loss
# TODO: Remove extra computation shared with yolo_head.
NameError: name 'yolo_head' is not defined。这个应该如何解决呢。
car 0.75 (445, 74) (689, 174)
bicycle 0.79 (204, 150) (565, 431)
dog 0.89 (106, 196) (325, 541)
Found 1 boxes for eagle.jpg
bird 0.96 (114, 97) (614, 437)
Found 1 boxes for giraffe.jpg
horse 0.96 (151, 24) (435, 458)
Found 4 boxes for horses.jpg
horse 0.31 (14, 194) (145, 253)
horse 0.63 (243, 198) (431, 366)
cow 0.78 (425, 203) (596, 342)
horse 0.89 (4, 195) (318, 415)
Traceback (most recent call last):
File "test_yolo.py", line 194, in <module>
_main(parser.parse_args())
File "test_yolo.py", line 119, in _main
image_type = imghdr.what(os.path.join(test_path, image_file))
File "F:\python\anaconda\lib\imghdr.py", line 14, in what
f = open(file, 'rb')
PermissionError: [Errno 13] Permission denied: 'images\\out'
到第五张的person.jpg就报错,这里是有什么bug么?
warnings.warn('No training configuration found in save file: '
Found 4 boxes for img
horse 0.50 (5, 177) (150, 339)
horse 0.78 (247, 198) (436, 370)
horse 0.85 (0, 193) (311, 411)
horse 0.89 (434, 211) (600, 351)
0.8803145885467529
出来的结果是这样的,最后的这个0.88是时间吧,我没有细看程序呢
File "test_yolo.py", line 149, in <module>
detect_img(img, yolo)
File "test_yolo.py", line 136, in detect_img
r_image = yolo.detect_image(image)
File "test_yolo.py", line 75, in detect_image
y, x, _ = image.shape
AttributeError: 'NoneType' object has no attribute 'shape'用的tensorflow1.4.0 keras2.1 opencv3.3 。应该怎么解决呢?
还有用自己的weights和cfg权重转换的时候报错Traceback (most recent call last):
File "test_yolo-2.py", line 194, in <module>
_main(parser.parse_args())
File "test_yolo-2.py", line 87, in _main
'Mismatch between model and given anchor and class sizes. ' \
AssertionError: Mismatch between model and given anchor and class sizes. Specify matching anchors and classes with --anchors_path and --classes_path flags.
者需要把源码中的txt文件也要换掉吗?
0.738768,0.874946, 2.42204,2.65704, 4.30971,7.04493, 10.246,4.59428, 12.6868,11.8741
orig_size = np.array([images[0].width, images[0].height]) 应该改成:
orig_size = np.array([[image.width, image.height] for image in (images)])
并且
# boxes_xy = [boxxy / orig_size for boxxy in boxes_xy]
# boxes_wh = [boxwh / orig_size for boxwh in boxes_wh]
应该改成:
boxes_xy = [boxxy / orig_size[i] for i, boxxy in enumerate(boxes_xy)]
boxes_wh = [boxwh / orig_size[i] for i, boxwh in enumerate(boxes_wh)]
是不是有以上问题呢?
warnings.warn('No training configuration found in save file: '
model_data/yolo.h5 model, anchors, and classes loaded.
是否因为自己没有训练呢?怎么训练视频呢?您有训练过的cfg文件吗?谢谢。