《深度学习:卷积神经网络从入门到精通》——3.7.2 交通路网的图像块分类
3.7.2 交通路网的图像块分类
本案例把交通路网的自动提取问题转化为图像块的局部分类问题,转化的方法是把原始图像分解为一系列较小的图像块,如果图像块的中心在路网上,就标记为正例(用1表示),否则就标记为反例(用0表示),从而就可以把路网看作正例图像块中心的集合。基于这种局部分类的思路,本小节把11幅训练遥感图像,按每幅从左到右、从上到下的顺序扫描,抽取所有25×25大小的图像块,并进行正反例标注。对于一幅大小为m×n的图像,共可抽取(m?-?24)(n?-?24)个图像块,其中可能包含数目不等的正例和反例。为了防止正例和反例的数目差别太大,需要对它们的比例进行控制,本案例控制比例约为1∶9。下面是抽取图像块的Matlab程序(sample.m和scan.m)和构造训练测试集的Python程序(getImageList.py)。
1.?sample.m的代码
clc;clear;
imageDir = './images/trainImages/'; % 训练图像的存放目录
labelDir = './images/labels/'; % 训练图像的对应标注图像所在目录
savePath = './data/' % 正反例图像块的存放目录
labelFile = dir(fullfile(labelDir,'*.bmp'));
wdSize = {[25,25]}; % 图像块的大小
for i=1:length(labelFile)
L = imread([labelDir,labelFile(i).name]); % 读取第i个标注图像
I = imread([imageDir,labelFile(i).name]); % 读取第i个训练图像
disp(['process:',labelDir,labelFile(i).name]);
scan(L,I,wdSize,savePath); % 调用scan函数抽取图像块
end
2.?scan.m的代码
function [ ] = scan(L,I,wdSize,savePath)
% L是标注图像,I是原始图像,wdSize是扫描窗口大小
L = L(:,:,1); % 读取标注图像的R通道,若要读取G(B)通道,把“1”改为“2(3)”
l_h = size(L,1); % 原始图像的高
l_w = size(L,2); % 原始图像的宽
p_num = length(dir(fullfile(savePath,'1/','*.bmp'))); % 当前存储的正例图像块数量
n_num = length(dir(fullfile(savePath,'0/','*.bmp'))); % 当前存储的反例图像块数量
disp([num2str(p_num),' | ',num2str(n_num)]);
wd_h = wdSize{1}(1); % wdSize = {[25,25]},wd_h为扫描窗口的高
wd_w = wdSize{1}(2); % wd_w为扫描窗口的宽
for i=1:1:l_h-wd_h
for j=1:1:l_w-wd_w
patch = L(i:i+wd_h,j:j+wd_w); % 抽取标注图像块
if patch(13,13)==255 % 判断patch的中心是否在路网上
p_num = p_num + 1; % 增加正例图像块的统计计数
obj = I(i:i+wd_h-1,j:j+wd_w-1,:); % 抽取原始图像块
imwrite(obj,[savePath,'1/','1_',num2str(p_num),'.bmp']);
% 保存在./data/1/文件夹下
elseif length(find(patch(14:22,14:22)==255))==0
% patch中心的9×9区域无路网穿过
n_num = n_num + 1; % 增加反例图像块的统计计数
rnd = randi(80,1,1); % 生成一个1~80的随机整数
if rnd==1; % 随机整数个数等于1,存储该反例,相当于按1/80概率抽取反例
bcg = I(i:i+wd_h-1,j:j+wd_w-1,:);
imwrite(bcg,[savePath,'0/','0_',num2str(n_num),'.bmp']);
?% 保存在./data/0/文件夹下
end
end
end
end
end
3.?getImageList.py的代码
#!/user/bin/python
#!conding=utf8
import os
import random
root = 'data'
dir = os.listdir(root) # 根目录
l = 0;
filelist = []; # 空列表
for d in dir: # 用d遍历dir下的文件夹,这里仅包括0和1文件夹
files = os.listdir(root+'/'+d) # files指向data里的0或者1文件夹
for f in files:
filelist.append('/'+root + '/' + d + '/' + f + ' ' + d + '\n')
# 在文件名后加标签
l = l + 1
random.shuffle(filelist) # 随机打乱filelist中的排序
txt = file('imglist_train.txt','w+') # 准备写入
txt.writelines(filelist[0:int(len(filelist)*0.90)]) # 选择90%带标签的图像块构造训练集
txt.close()
txt = file('imglist_test.txt','w+')
txt.writelines(filelist[int(len(filelist)*0.90):len(filelist)])
# 选择剩余的10%构造测试集
txt.close()
依次运行程序sample.m、scan.m和getImageList.py,就可以得到局部分类的图像块训练集和测试集,有关路径及标签分别保存在imglist_train.txt和imglist_test.txt这两个文件中。其中,训练集和测试集按照9∶1的比例划分,训练集包含121?257幅图像,测试集包含13?474幅图像。
方框3.7 批处理文件trainleveldb.bat的内容
SET GLOG_logtostderr=1
convert_imageset.exe --backend=leveldb ./ ./imglist_train.txt ./ldb/trainldb
pause
方框3.8 批处理文件testleveldb.bat的内容
SET GLOG_logtostderr=1
convert_imageset.exe --backend=leveldb ./ ./imglist_test.txt ./ldb/testldb
pause
为了得到Caffe能够识别的训练集和测试集,还需要参照3.6.1节利用convert_imageset.exe把imglist_train.txt和imglist_test.txt中涉及的数据转换成LEVELDB格式。具体的转换过程可以通过两个批处理文件完成:trainleveldb.bat和testleveldb.bat。文件的内容分别见方框3.7和方框3.8。
- 点赞
- 收藏
- 关注作者
评论(0)