从github上下载了keras-yolo3项目代码,体验了一下,感觉还不错,代码全是用python写的,字面语句很好理解。
作为一个简单的体验,我写了一个小小的测试程序,打开笔记本摄像头,实时使用YOLO检测。
编写文件 usb-camera.py,并把文件放在keras-yolo3 目录下面。
# -*- coding: utf-8 -*-
"""
Created on Tue May 7 15:07:52 2019
@author: vector
"""
import cv2
import sys
import argparse
from yolo import YOLO, detect_video
from PIL import Image
import numpy as np
#这一段抄的yolo-video.py中的函数
def CreateYOLO():
# class YOLO defines the default value, so suppress any default here
parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
'''
Command line options
'''
parser.add_argument(
'--model', type=str,
help='path to model weight file, default ' + YOLO.get_defaults("model_path")
)
parser.add_argument(
'--anchors', type=str,
help='path to anchor definitions, default ' + YOLO.get_defaults("anchors_path")
)
parser.add_argument(
'--classes', type=str,
help='path to class definitions, default ' + YOLO.get_defaults("classes_path")
)
parser.add_argument(
'--gpu_num', type=int,
help='Number of GPU to use, default ' + str(YOLO.get_defaults("gpu_num"))
)
parser.add_argument(
'--image', default=False, action="store_true",
help='Image detection mode, will ignore all positional arguments'
)
'''
Command line positional arguments -- for video detection mode
'''
parser.add_argument(
"--input", nargs='?', type=str,required=False,default='./path2your_video',
help = "Video input path"
)
parser.add_argument(
"--output", nargs='?', type=str, default="",
help = "[Optional] Video output path"
)
FLAGS = parser.parse_args()
yolo=YOLO(**vars(FLAGS))
return yolo
cap = cv2.VideoCapture(0)#打开相机
#yolo=YOLO()
'''
image = Image.open("1.jpg")
r_image = yolo.detect_image(image)
r_image.show()
input("ok")
'''
while(True):
ret,frame = cap.read()#捕获一帧图像
#cv2.imshow('frame',frame)
print(frame.shape)
img = Image.frombytes('RGB',(frame.shape[1], frame.shape[0]),frame,'raw', 'BGR')
img.save('hehe.jpg')
#break
yolo=CreateYOLO()
r_image = yolo.detect_image(img)
rawimg=np.array(r_image)
print("raw img :" + str(rawimg.shape))
cv2.imshow('check',rawimg)
#断按键,如果按键为q,退出循环
if cv2.waitKey(1) & 0xFF == ord('q'):
break
print("cap bef")
cap.release()#关闭相机
print("cap afx")
cv2.destroyAllWindows()
以上代码中有函数def CreateYOLO(): 这是抄的yolo-video.py里面的,主要是用来生成YOLO类,其实我是想去掉各个需要输入的参数 yolo=YOLO(**vars(FLAGS)),但是看了半天没看懂 这个**vars(FLAGS) 该怎样写死一个默认的值(python也刚开始看)。所以,没办法,我又改了yolo.py文件下的 class YOLO 的 init 函数,目的只是把默认值设定上,就不用再输入了。如下:
def __init__(self, **kwargs):
self.__dict__.update(self._defaults) # set up default values
self.__dict__.update(kwargs) # and update with user overrides
self.class_names = self._get_class()
self.anchors = self._get_anchors()
self.sess = K.get_session()
self.boxes, self.scores, self.classes = self.generate()
self.model_path='model_data/yolo.h5'
self.anchors_path='model_data/yolo_anchors.txt'
self.classes_path='model_data/coco_classes.txt'
self.gpu_num=1
self.model_image_size=(416,416)
在usb-camera.py 中,img = Image.frombytes('RGB',(frame.shape[1], frame.shape[0]),frame,'raw', 'BGR') 是将使用cv2 模块读出的 rawdata 转为image 类型,为什么要转呢?因为,class YOLO 中detect_image()函数 就需要这种类型,其实可以改一下这个函数,让它接收rawdata就好了,但是我不会改,那就用Image.frombytes转换一下吧。同样的道理,在detect_image()输出之后 使用rawimg=np.array(r_image) 函数,将image 转为rawdata,再送给cv2模块 进行显示。
我在自己的电脑上试了一下(并没有使用GPU加速)。大概得需要7秒钟 才能处理一帧。所以看到画面非常卡顿。