做PASCAL VOC语义分割数据集的时候,
1、标注工具使用labelme,我是在anaconda下新建了一个名字为labelme的虚拟环境,将labelme安装在了这个环境下面,具体的安装一堆教程。标注之后会有一个json文件,将json文件转换为标签,我这里只有单个json转换的例子。
1、首先进入你的labelme环境中:
activate labelme
2、然后再cd到你的json文件所在的文件夹。记得这时候json文件和原图要在一个文件夹下:
cd /d ”你的json文件所在路径“
3、进入路径之后输入:(下面的文件名.json是你的json文件的名字)
labelme_json_to_dataset “文件名”.json
4、然后就可以看见路径下有新生成的文件夹,里面包含了标签等等。
2、生成的标签是单通道的,我们所需要的PASCAL VOC的数据集的标签也是单通道8位图。接下来只需要将所得的标签切分为我们想要的尺寸就可以了。但是这中间会有些问题,生成的标签虽然有颜色,但是它本身是单通道,有颜色是因为使用了调色板的缘故。这时候进行切分可能切之后的小图都是24位且全黑的。我们只需要在切分程序中加入调色板函数就可以了。
这里提供一个matlab的滑窗切分图片的代码。
image_sliding_window.m
,注意下面的调色板函数VOClabelcolormap.m
要一起
clear all
clc
%get the image batch
dirction = 'C:\Users\admin\Desktop\**\';
Path = dir(fullfile(dirction,'*.png')); ###这里根据自己的情况选择是png还是jpg
img_size = 500;stride =400;counter =1; ##img_size是切分的图片尺寸,stride是滑窗的步长,counter为图片命名的起始数字
cmap=VOClabelcolormap(255);###调色板函数
for k = 1:numel(Path)
imPath = fullfile(dirction,Path(k).name);
img = imread(imPath);
[H,W,C] = size(img);
row_num = fix((H-img_size)/stride)+1;
column_num = fix((W-img_size)/stride)+1;
for i = 1:row_num
for j = 1:column_num
H_start = 1+(i-1)*stride;
H_end = H_start+img_size-1;
W_start = 1+(j-1)*stride;
W_end = W_start+img_size-1;
img_chip = img(H_start:H_end,W_start:W_end,:);
%%----------想要生成的图片是三通道就加上这一句,单通道标签不需要
% if C==1
% img_chip=cat(3,img_chip,img_chip,img_chip);
% end
%%--------------
% img_chip = cat(3,img_chip,img_chip,img_chip);
file_name = ['C:\Users\admin\Desktop\ab\**\',num2str(counter,'%04d'),'.png'];
counter = counter+1;
imwrite(img_chip,cmap,file_name);
% imwrite(img_chip,file_name);
end
end
end
对应的调色板函数为:记得要保存为VOClabelcolormap.m
。
% VOCLABELCOLORMAP Creates a label color map such that adjacent indices have different
% colors. Useful for reading and writing index images which contain large indices,
% by encoding them as RGB images.
%
% CMAP = VOCLABELCOLORMAP(N) creates a label color map with N entries.
function cmap = labelcolormap(N)
if nargin==0
N=256
end
cmap = zeros(N,3);
for i=1:N
id = i-1; r=0;g=0;b=0;
for j=0:7
r = bitor(r, bitshift(bitget(id,1),7 - j));
g = bitor(g, bitshift(bitget(id,2),7 - j));
b = bitor(b, bitshift(bitget(id,3),7 - j));
id = bitshift(id,-3);
end
cmap(i,1)=r; cmap(i,2)=g; cmap(i,3)=b;
end
cmap = cmap / 255;
这样就可以看到切分之后有颜色的单通道标签了。
3、图片切分之后,数据集有了,在下面就是按照VOC的数据集格式来进行操作了。如下图所示,JPEGImages
文件夹下是数据集原图,SegmentationClass
文件夹下是对应的标签。
VOC数据集的格式一般都是这样,进入到ImageSets
文件夹下是这样的:
其中的train.txt中是训练集的图片名称数据,val.txt中是验证集的图片名称数据,下面是从文件夹中提取文件名称到txt中的程序:
import os
dir1='D:\\**\\SegmentationClass'#图片文件存放地址
txt1 = 'D:\\**\\train.txt'#图片文件名存放txt文件地址
f1 = open(txt1,'a')#打开文件流
for filename in os.listdir(dir1):
f1.write(filename.rstrip('.png'))#只保存名字,去除后缀.png
f1.write("\n")#换行
f1.close()#关闭文件流
这样txt文本就生成了。
4、还有可能你需要对其中一部分数据进行数据增强,从标签文件夹下选出来需要进行增强的图片之后,还需要把对应的原图图片挑选出来进行增强,这里提供一个根据txt文本提取文件夹中图片的程序,可以挑出来想要进行增强的标签图片,然后将其名称生成txt文本(txt中的图片名字最好不要包含.png这些,方便进行各种格式图片的提取),进而通过下面的程序直接提取出对应的原图图片。
# -*- coding: UTF-8 -*-
# !/usr/bin/env python 根据txt中的名字提取对应名字的图片
import sys
import re
from PIL import Image
import numpy as np
data = []
for line in open('D:\\**\\tiqu.txt', "r"): # 这里是需要读取的txt文本
data.append(line)
for a in data:
im = Image.open('D:\\**\\y_qie\\{}'.format(a[:-1]+'.jpg')) # 需要提取图片的文件夹路径
im.save('D:\\**\\y_zq\\{}'.format(a[:-1]+'.jpg')) # 把文件夹中指定的文件名称的图片另存到该路径下
至此,VOC格式的数据集制作所需要的程序应该都有可以用的了。可能不需要这么麻烦,但是我的二分类需要对其中的目标数据进行增强,这是我想到的相对比较合适的办法。如果有更好的,阔以分享啦!!!