利用yolov3目标检测的功能对探地雷达数据进行检测。具有一定的研究意义。
环境准备:ubuntu18.04,darknet平台,python3.7,CUDA10.0,GTX1050Ti
仿真数据需要安装gprMax3,gprMax3是生成gpr数据的工具,可到官网下载,它是一个开源工具也可以访问github仓库进行安装,官方安装教程。
由于只是简单的做下实验,对于仿真数据没有太高的要求所以,笔者利用python 脚本生成了100个in文件实现代码如下:
import os
import math
import random
filePrefix = 'data_' #文件前缀
fileSuffix = '.in' #文件后缀
for i in range(100):
filename = filePrefix+str(i)+fileSuffix
e1 = random.randint(1,10) #Mate1的介电常数
e2 = random.randint(1,10) #Mate2的介电常数
x = random.uniform(0.20,0.70)#目标的中心x坐标
x = round(x,2)
y = random.uniform(0.10,0.40)#目标的中心y坐标
y = round(y,2)
Twindows = (0.2*math.sqrt(e1)+0.24*math.sqrt(e2))/3e8*2
# Twindows = round(Twindows,2)
fl = open(filename,'w')
fl.write('#title: '+filename+'\n')
fl.write('#domain: 1 0.5 0.002\n')
fl.write('#dx_dy_dz: 0.002 0.002 0.002\n')
fl.write('时间窗可手动修改\n')
fl.write('#time_window: '+str(Twindows)+'\n')
fl.write('以下参数可手动修改\n\n')
fl.write('#material: '+str(e1)+' 0 1 0 Mate1\n'
'#material: '+str(e2)+' 0 1 0 Mate2\n\n'
'#waveform: ricker 1 1.5e9 my_ricker\n'
'#hertzian_dipole: z 0.05 0.49 0 my_ricker\n\n'
'#rx: 0.055 0.49 0\n\n'
'#src_steps: 0.01 0 0\n'
'#rx_steps: 0.01 0 0\n\n'
'#box: 0 0.24 0 1 0.44 0.002 Mate1\n'
'#box: 0 0 0 1 0.24 0.002 Mate2\n'
'#cylindrical_sector: z '+str(x)+' '+str(y)+' 0 0.002 0.02 180 180 pec\n\n'
'geometry_view: 0 0 0 1 0.5 0.002 0.002 0.002 0.002 mytest n\n')
fl.close()
批量生成的in文件都是单目标的如果想生成多目标可以适当修改,此外如果想生成几何文件也需要修改,个人建议在批量生成之前要先调试几个random参数,看是否合理,最好看下几何文件如何,因为这次只是简单的实验,这里的变化参数只有四个,如果想实现更多的可能性,可以设置更多变化参数,前提是每个参数的变化范围合理。
在这里首先感谢师兄提供的帮助,由于笔者编程能力垃圾以及对于gprmax应用的不太熟练,导致自己搞了很久也没搞定,感谢师兄指导,话不多说直接贴上师兄的博客。由于yolov3最终是对jpg图片进行处理(笔者的yolo没有安装opencv,安装的小伙伴可以忽略),所以对于师兄的代码可以将==.png改成.jpg==。
在这里还存在一些小问题,就是师兄在代码中么没有使用gpu进行训练,笔者的gprMax3.0可以使用gpu所以笔者将api函数改下
api(filename, n=num_scan, geometry_only=geo_only,gpu=[0]) #geometry_only:仅几何图形结果报错了,最后使用了cpu生成B-scan数据
直达波会使得目标图像不明显最好是去掉直接上图
没有去除直达波如上图
去除直达波后如上图,去除方式我使用了最暴力的方法直接将数据做了切片处理丢弃前300行数据
之后对数据进行加噪声,这里再次感谢师兄指导!在这里我是指定数据加噪声,最好是随机加噪声将信噪比随机,加噪声对象随机。实现代码如下:
import os
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
path = os.getcwd()
def Add_noise(x,snr):#传入的是信噪比dB
'''snr(db) = 10log10(ps/pn)'''
snr = 10 ** (snr / 10.0)
xpower = np.sum(x ** 2) / np.size(x)
npower = xpower / snr
noise = np.random.randn(x.shape[0], x.shape[1]) * np.sqrt(npower)
x_noise = x + noise
return x_noise
for item in range(100):
recordArray = np.loadtxt(path+'/out_data/data_'+str(item)+'.txt')
recordArray = recordArray[300:]#切片去除直达波
#部分数据加噪声
if item>=10 and item<20:
recordArray = Add_noise(recordArray, 30)
elif item>=30 and item<40:
recordArray = Add_noise(recordArray, 50)
elif item >= 60 and item < 70:
recordArray = Add_noise(recordArray, 70)
# recordArray= recordArray.astype(np.float)
# print(recordArray)
np.savetxt('/media/rose/Rose/data/out_data/data_'+str(item)+'.txt',recordArray)
plt.imshow(recordArray, extent=[0, recordArray.shape[1], recordArray.shape[0], 0], interpolation='nearest',
aspect='auto', cmap='gray',
vmin=-np.amax(np.abs(recordArray)), vmax=np.amax(np.abs(recordArray)))
plt.savefig('/media/rose/Rose/data/out_image/data_' +str(item)+ '.jpg', dpi=300) # 保存图片
接下来制作yolov3能够处理的数据集,标记数据集需要用到标注工具labelImag
labelImg安装
笔者计算机系统为ubuntu18.04直接打开终端输入:
pip install labelImg (如果下载太慢可以换源运行下面一条命令)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple labelImg
labelImag使用
终端输入:
labelImg
制作好标签数据之后就可以进行训练了yolov3的训练主要参考链接。
由于笔者已经安装好了darknet-yolov3,并且制作好了yolo数据集直接跳过链接中的 一,二步,到第三步第1点之后首先按照相应要求建立好文件夹具体如下:
在darknet目录运行命令
在这里我没有建立Annotations目录因为我在生成标签数据的时候已经选择yolo标签所以不需要去转换为darknet可以运行的数据
mkdir myData
cd myData
mkdir JPEGImages ImageSets/Main labels
将图片复制到JPEGImages目录下
运行链接中第三步第1点的代码:
import os
import random
trainval_percent = 0.1
train_percent = 0.9
xmlfilepath = 'Annotations'
txtsavepath = 'ImageSets\Main'
total_xml = os.listdir(xmlfilepath)
num = len(total_xml)
list = range(num)
tv = int(num * trainval_percent)
tr = int(tv * train_percent)
trainval = random.sample(list, tv)
train = random.sample(trainval, tr)
ftrainval = open('ImageSets/Main/trainval.txt', 'w')
ftest = open('ImageSets/Main/test.txt', 'w')
ftrain = open('ImageSets/Main/train.txt', 'w')
fval = open('ImageSets/Main/val.txt', 'w')
for i in list:
name = total_xml[i][:-4] + '\n'
if i in trainval:
ftrainval.write(name)
if i in train:
ftest.write(name)
else:
fval.write(name)
else:
ftrain.write(name)
ftrainval.close()
ftrain.close()
fval.close()
ftest.close()
如上所述,我们在执行链接第三步第2点时不需要按照他所说的来直接将已经标记好的标签文件复制到labels目录下如图
进入到darknet/cfg目录下运行终端
cp voc.data my_data.data
cp yolov3.cfg my_yolov3.cfg
修改 my_data.data
classes= 1 ##改为自己的分类个数
##下面都改为自己的路径
train = /home/XXX/darknet/myData/myData_train.txt
names = /home/XXX/darknet/myData/myData.names #稍后需要创建这个文件
backup = /home/XXX/darknet/myData/weights
修改my_yolov3.cfg
/yolo, 总共会搜出3个含有yolo的地方。
每个地方都必须要改2处, filters:3*(5+len(classes));
其中:classes: len(classes) = 1,这里以我的工程为例
filters = 18
classes = 1
可修改:random = 0:原来是1,显存小改为0。(是否要多尺度输出。)
修改训练批次
将测试的代码注释,使用训练的代码,在这里我将训练改动如下
batch=2
subdivisions = 2
max_batches = 5000
steps = 4000,4500
[net]
# Testing ### 测试模式
# batch=1
# subdivisions=1
# Training ### 训练模式,每次前向的图片数目 = batch/subdivisions
batch=2
subdivisions=2
width=416 ### 网络的输入宽、高、通道数
height=416
channels=3
momentum=0.9 ### 动量
decay=0.0005 ### 权重衰减
angle=0
saturation = 1.5 ### 饱和度
exposure = 1.5 ### 曝光度
hue=.1 ### 色调
learning_rate=0.001 ### 学习率
burn_in=1000 ### 学习率控制的参数
max_batches = 5000 ### 迭代次数
policy=steps ### 学习率策略
steps=4000,4500 ### 学习率变动步长
在myData目录下新建myDatanames并输入
line(我定义的标签名,只有一种类别)
在darknet目录下进行打开终端
wget https://pjreddie.com/media/files/darknet53.conv.74
./darknet detector train cfg/my_data.data cfg/my_yolov3.cfg darknet53.conv.74
./darknet detect cfg/my_yolov3.cfg myData/weights/my_yolov3_final.weights data_24.jpg