在夜间微弱的灯光下,摄像头拍摄的画质非常差,基于夜间场景的识别模型训练有助于夜间安防。本项目基于ExDark数据集、PicoDet、EdgeBoard飞桨开发套件和PyQt5进行夜间场景特定物品检测模型的训练和部署。
! unzip -oq data/data129450/ExDark.zip
# 克隆PaddleDetection仓库
import os
if not ists('PaddleDetection'):!git clone .git# 安装其他依赖
%cd PaddleDetection
! pip install -# 编译安装paddledet
! python setup.py install
# 测试一下PaddleDet环境有没有准备好
! python ppdet/modeling/tests/test_architectures.py
将数据格式调整为voc格式,并且准备paddledet需要的文件
正所谓是闻名不如见面吗,不熟悉voc格式的小伙伴可以通过以下语句查看一个voc格式的示例~
%cd ~
! wget .tar
! tar -xvf /home/aistudio/roadsign_voc.tar
# ExDark转voc
%cd ~# thanks to
import xml.dom.minidom as minidom
import cv2def convert2xml(img_dir,annotation_dir,save_dir):img = cv2.imread(img_dir)h,w,c = img.shapedom = DOMImplementation().createDocument(None,'annotations',None)root = dom.documentElementelement = ateElement('filename')element.ateTextNode(img_dir.split('/')[-1]))root.appendChild(element)element = ateElement('size')element_c = ateElement('width')element_c.ateTextNode(str(w)))element.appendChild(element_c)element_c = ateElement('height')element_c.ateTextNode(str(h)))element.appendChild(element_c)element_c = ateElement('depth')element_c.ateTextNode(str(c)))element.appendChild(element_c)root.appendChild(element)with open(annotation_dir) as f:for line adlines():if '% bbGt' in line:continueelse:element = ateElement('object')name = line.split(' ')[0]xmin = int(line.split(' ')[1])ymin = int(line.split(' ')[2])xlen = int(line.split(' ')[3])ylen = int(line.split(' ')[4])element_c = ateElement('name')element_c.ateTextNode(name))element.appendChild(element_c)element_c = ateElement('bndbox')element.appendChild(element_c)element_cc = ateElement('xmin')element_cc.ateTextNode(str(xmin)))element_c.appendChild(element_cc)element_cc = ateElement('ymin')element_cc.ateTextNode(str(ymin)))element_c.appendChild(element_cc)element_cc = ateElement('xmax')element_cc.ateTextNode(str(xmin+xlen)))element_c.appendChild(element_cc)element_cc = ateElement('ymax')element_cc.ateTextNode(str(ymin+ylen)))element_c.appendChild(element_cc)root.appendChild(element)with open(save_dir, 'w', encoding='utf-8') as f:dom.writexml(f, addindent='t', newl='n',encoding='utf-8')convert2xml('ExDark/images/Bicycle/2015_00001.png','ExDark/Annnotations/Bicycle/2015_',l')
/home/aistudio
# thanks to .html
# 用一个记录数据
%cd ~
import os
! mkdir -p ExDark/annotations
with open(','w') as f:for root, dirs, files in os.walk("ExDark/images", topdown=False):for name in files:img_dir = os.path.join(root, name)if 'ipynb_checkpoints' in img_dir:continueannotation_dir = place('images','Annnotations')+'.txt'save_dir = 'ExDark/annotations/'+img_dir.split('/')[-1]+'.xml'try:convert2xml(img_dir,annotation_dir,save_dir)except:continuef.write(img_dir+' '+save_dir+'n')
# 准备标签文件
%cd ~
with open('','w') as f:for item in os.listdir("ExDark/images"):f.write(item+'n')
/home/aistudio
在PaddleDetection/configs/picodet/目录下准备一个名为l的文件,内容为
_BASE_: ['../l','../l','_base_/l','_base_/l','_base_/picodet_l',
]pretrain_weights: .pdparams
weights: output/picodet_xs_320_coco/best_model
find_unused_parameters: True
use_ema: true
epoch: 8
snapshot_epoch: 2LCNet:scale: 0.35feature_maps: [3, 4, 5]LCPAN:out_channels: 96PicoHeadV2:conv_feat:name: PicoFeatfeat_in: 96feat_out: 96num_convs: 2num_fpn_stride: 4norm_type: bnshare_cls_reg: Trueuse_se: Truefeat_in_chan: 96TrainReader:batch_size: 64LearningRate:base_lr: 0.32schedulers:- !CosineDecaymax_epochs: 300- !LinearWarmupstart_factor: 0.1steps: 300
将PaddleDetection/configs/l修改为如下内容
metric: VOC
map_type: 11point
num_classes: 12TrainDataset:!VOCDataSetdataset_dir: /home/aistudioanno_path: /home/label_list: /home/aistudio/data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']EvalDataset:!VOCDataSetdataset_dir: /home/aistudioanno_path: /home/label_list: /home/aistudio/data_fields: ['image', 'gt_bbox', 'gt_class', 'difficult']TestDataset:!ImageFolderanno_path: /home/aistudio/
10 epoch 24 min
%cd ~/PaddleDetection
! export CUDA_VISIBLE_DEVICES=0 #windows和Mac下不需要执行该命令
! python tools/train.py -c configs/l
预测一下看看结果吧,如果啥也没检测到就修改threshold,毕竟是黑暗场景~调低一点就能看到了。
结果展示:
# 预测代码
%cd ~/PaddleDetection
! export CUDA_VISIBLE_DEVICES=0 #windows和Mac下不需要执行该命令
! python tools/infer.py -c configs/l --infer_img=/home/aistudio/ExDark/images/Bicycle/2015_00001.png --output_dir=infer_output/ --draw_threshold=0.5 -o weights=output/myPicodetXsVoc/model_final --use_vdl=False
/home/aistudio/PaddleDetection
W0910 18:38:48.325160 14436 gpu_resources:61] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W0910 18:38:48.328585 14436 gpu_resources:91] device: 0, cuDNN Version: 8.2.
[09/10 18:38:48] ppdet.utils.checkpoint INFO: Finish loading model weights: output/myPicodetXsVoc/model_final.pdparams
100%|█████████████████████████████████████████████| 1/1 [00:01<00:00, 1.99s/it]
[09/10 18:38:50] ine INFO: Detection bbox results save in infer_output/2015_00001.png
%cd ~/PaddleDetection
! python tools/export_model.py -c configs/l --output_dir=./inference_model -o weights=output/myPicodetXsVoc/model_final TestReader.inputs_def.image_shape=[3,320,320]
/home/aistudio/PaddleDetection
[09/06 20:38:43] ppdet.utils.checkpoint INFO: Finish loading model weights: output/myPicodetXsVoc/model_final.pdparams
[09/06 20:38:43] ine INFO: Export inference config file to ./inference_model/myPicodetXsVoc/l
[09/06 20:38:48] ine INFO: Export model and saved in ./inference_model/myPicodetXsVoc
Fork项目EdgeBoard飞桨开发套件,根据项目内说明,执行即可。
需要注意以下两点:
转化后的模型为一个tar文件。
将转化后的.tar文件放在EdgeBoard指定路径下,并修改对应Config信息即可(具体参考EdgeBoard飞桨开发套件)。
具体的EB推理代码如下(由于使用了pyqt5和摄像头需要在本地运行):
#!/usr/bin/python3
# -*- coding: utf-8 -*-"""
Thanks to
zetcode
/
"""import sys
import cv2
import numpy as np
import math
import time
import collections
import os
import sys
from PyQt5.QtWidgets import QWidget, QDesktopWidget, QApplication, QPushButton, QFileDialog, QLabel, QTextEdit, QGridLayout, QFrame, QColorDialog
from PyQt5.QtCore import QTimer, QUrl
from PyQt5.QtGui import QColor, QImage, QPixmap"""Demo for ppnc runtime on board"""
import json# add python path of ppnc/python to sys.path
parent_path = os.path.abspath(os.path.join(__file__, *(['..'] * 2)))
sys.path.insert(0, parent_path + '/python')from ppnc import PPNCPredictordef parse_config(config_file):"""parse config"""with open(config_file, "r") as f:config = json.load(f)return configdef preprocess(img, input_size=(320, 320)):"""parse imageArgs:img_path (str): pathinput_size (tuple, optional): h x w. Defaults to (320, 320)."""input = {}# img = cv2.imread(img_path)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)scale_factor = [input_size[0] / img.shape[0], input_size[1] / img.shape[1]]factor = np.array(scale_factor, dtype=np.float32)input['scale_factor'] = shape((1, 2))img = size(img, input_size, interpolation=2)mean = np.array([0.485, 0.456, 0.406])[np.newaxis, np.newaxis, :]std = np.array([0.229, 0.224, 0.225])[np.newaxis, np.newaxis, :]img = img / 255img -= meanimg /= stdimg = img.astype(np.float32, copy=False)img = anspose((2, 0, 1))img = waxis, :]input['image'] = imgreturn inputdef draw_box(img, res, threshold=0.35):"""draw boxArgs:img_path (str): image pathres (numpy): outputthreshold (float, optional): . Defaults to 0.2."""# img = cv2.imread(img_path)label_list = ['Boat','People','bottle','Chair','Table','Cat','Dog','Motorbike','Bicycle','Cup','Car','Bus']for i in res:label = int(i[0])score = i[1]if score < threshold:continueprint("Something exists! It is ", end="")print(label_list[label])xmin, ymin, xmax, ymax = i[2:]angle(img, (int(xmin), int(ymin)), (int(xmax), int(ymax)), (0, 255, 0))return imgclass Example(QWidget):def __init__(self,config):super().__init__()fig = configself.img_width, self.img_height = [120 * x for x in [4, 3]]self.initCamera()self.initUI()self.initModel()def initCamera(self):# 开启视频通道self.camera_id = 0 # 为0时表示视频流来自摄像头self.camera = cv2.VideoCapture() # 视频流self.camera.open(self.camera_id)# 通过定时器读取数据self.flush_clock = QTimer() # 定义定时器,用于控制显示视频的帧率self.flush_clock.start(60) # 定时器开始计时30ms,结果是每过30ms从摄像头中取一帧显示self.flush_t(self.show_frame) # 若定时器结束,show_frame()def initModel(self):# Step 2: initialize ppnc predictorself.predictor = fig)self.predictor.load()def initUI(self):grid = QGridLayout()self.setLayout(grid)self.Img_Box = QLabel() # 定义显示视频的Labelself.Img_Box.setFixedSize(self.img_width, self.img_height)grid.addWidget(self.Img_Box, 0, 0, 20, 20)self.setWindowTitle('test')self.show()def show_frame(self):# self.player.play()_, img = ad() # 从视频流中读取# print(img.shape)try:feeds = preprocess(img)self.predictor.set_inputs(feeds)self.predictor.run()res = _output(0)img = draw_box(img, res)except:print('infer error')img = size(img, (self.img_width, self.img_height)) # 把读到的帧的大小重新设置为 640x480showImage = QImage(img, img.shape[1], img.shape[0], QImage.Format_RGB888)self.Img_Box.setPixmap(QPixmap.fromImage(showImage))if __name__ == '__main__':# Step 1: parse config fileassert len(sys.argv) >= 3, "config and image file must be provided"config_file = sys.argv[1]image_file = sys.argv[2]config = parse_config(config_file)app = QApplication(sys.argv)ex = Example(_())
最后简单展示一下部署效果:
检测环境 | 检测结果 |
---|---|
检测环境看着可能比较亮,但实际上很暗,除了屏幕和开发板的指示灯外,没有太多光源。可以看到确实能够检测到水杯的出现~
请点击此处查看本环境基本用法.
Please click here for more detailed instructions.
此文章为搬运
原项目链接
本文发布于:2024-01-28 23:11:23,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170645468810977.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |