之前去弄硬件和3d打印鸽了很久,现在的话继续上次的利用PaddleDetection的使用说明,
这一篇的目的是调用摄像头进行目标检测,所以要使用opencv.
值得提醒的是,由于版本的变化,在python安装opencv用pip安装的话是pip install opencv-python,而不是pip install opencv,
并且在引用包的时候要写成import cv2,而不是import opencv的形式.
第一步:准备权重文件
在之前的博客里我们已经,训练出了权重文件了,如下图的样子(这里名字是best_model,选取的权重文件不同名字也会不同,上篇博客中输出模型文件夹为inference_model)
现在我们需要对这三个权重文件进行再处理,这里我们需要调用,tools文件夹下的export_model.py文件,
使用命令如下:
python tools/export_model.py -c configs/yolov3_mobilenet_v1_fruit.yml -o weights=inference_model/yolov3_mobilenet_v1_fruit
其中:(记得把要处理的权重文件的名字加上去!)
之后会输出这三个文件
输出路径默认的是output\yolov3_mobilenet_v1_fruit其中(yolov3_mobilenet_v1_fruit是你选择的模型的名字命名的文件夹)
要输出指定位置的在命令行后加上--output_dir
和你要输出的路径
值得注意的是,得到的三个文件中,使用记事本打开看看infer_cfg.yml
检查下里面的标签是不是你自己的标签,不是的话改过来,
我这边有出现了程序使用代码自带的默认标签的情况(如bicycle之类的,具体原因是处理标签的那部分代码出错了,系统就默认用之前预设的值了,至于出错的部分,最近忙懒得找,大家直接改输出的infer_cfg.yml文件吧,亲测效果一样的)
第二部,修改infer文件
在修改infer文件之前,我们可以使用其来输入视频(MP4 avi之类的),看能不能输出标注好位置的视频文件,来进行验证得到的权重文件的准确性(一般你图像预测可以,视频的话就没什么问题的)
python deploy/python/infer.py --model_dir=output/yolov3_mobilenet_v1_fruit/ --video_file=../../work/test.mp4 --use_gpu=True --thresh=0.2
其中:
–model_dir=后面跟你之前第一步得到的那三个文件的路径
–video_file=后面跟你测试的视频文件的路径(注意相对路径和绝对路径的问题,建议用绝对路径)
–use_gpu=True和False决定是否开启GPU运算帮助加速
–thresh=后跟识别的限制阈值,越高则就要满足更高的相似度才能被识别到,建议0.2左右嘛
(哦,突然记起来,如果是linux环境的老铁,记得加在调用命令的前面加感叹号 !
不然可能权限不够,不运行,在百度al studio就得加)
以上输出预测视频没问题之后,建议备份一下infer文件,然后我们就可以开始修改了.
按照以下的部分,我们将默认的video_file参数由字符串类型修改为整形,并将默认值设置为0 (我记得外置摄像头就是0,内置是1)
然后,我们找到源程序部分进行修改如下
由于自己做项目摸索,程序改来改去的地方多,忽略左边的行数哈
由上图一样,我们通过之前的video_file变量找过去,实际修改的是predict_video这个函数(方法)
其实就是简单的将视频流的路径替换成了,摄像头的,以下的反正用以下我修改后的predict_video替换掉原来的就是了
def predict_video():
print("predict_video")
detector = Detector(
FLAGS.model_dir, use_gpu=FLAGS.use_gpu, run_mode=FLAGS.run_mode)
print("打印下")
print(FLAGS.video_file)
capture = cv2.VideoCapture(FLAGS.video_file)
capture.set(3, 640)
capture.set(4, 480) # 360
# capture.set(3, 320)
# capture.set(4, 180)
# capture.set(3, 1280)
# capture.set(4, 720)
# capture.set(3, 160)
# capture.set(4, 90)
# fps = 30
# width = int(capture.get(cv2.CAP_PROP_FRAME_WIDTH))
# height = int(capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
# fourcc = cv2.VideoWriter_fourcc(*'mp4v')
index = 1
while (1):
ret, frame = capture.read()
if not ret:
break
print('detect frame:%d' % (index))
index += 1
results = detector.predict(frame, FLAGS.threshold) # 坐標得到..............
if (results == 0):
im = frame
else:
im = visualize_box_mask(
frame,
results,
detector.config.labels,
mask_resolution=detector.config.mask_resolution)
im = np.array(im)
cv2.imshow("capture", im)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
调用的命令是
python deploy/python/infer.py --model_dir==这里填存放之前转出来的三个文件的文件夹的路径 --thresh=0.2
这时其实你就可以在运行的画面上看到视频图像了
如图:
然后些温馨提示了,代码注释掉的部分可以替换已用的部分来改变视频的分辨率,和帧数.
想将识别的视频进行录制保存的话参考这里的代码修改几行(这个博主写得注释还很详细的)传送门
最后再写点,是关于取得识别物体的坐标数据的,我这边通过打印的数据,与标记后的图片进行对比,发现这里的坐标数据是放在了results[“boxes”]中的
如下:
paddledetection中,字典results[“boxes”][0][1]输出的值为相似度,剩下的分别是图片标记的两个坐标点,即左上角与右下角两个,通过这两个坐标点对视频流中的物体进行标注框选的操作
以下的代码就是将相似度与坐标点提取出来的方法.
sim1 = results["boxes"][0][1] # 相似度0.8213138,
left_up_x1 = results["boxes"][0][2] # x轴,左上(左上为零点)10.143881 ,
right_down_x1 = results["boxes"][0][4] # x轴,左上(左上为零点)44.352264
left_up_y1 = results["boxes"][0][3] # y轴,右下(左上为零点)294.28348
right_down_y1 = results["boxes"][0][5] # y轴,右下(左上为零点)328.0142
哦,记得点赞