在Crowd counting领域,常用的训练方法是estimate density map,这种数据可利用高斯核函数得来,在MCNN论文中有具体过程;
也可参加这篇博客:https://blog.csdn.net/zxs0222/article/details/107900465
存储density map的文件目前有两种:.h5文件和.cvs文件,而数据集中常见的是.mat文件,其中记录着所有人头的中心坐标点。
利用.mat生成.h5的过程可参见这篇博客:https://blog.csdn.net/zxs0222/article/details/108910388
而有些代码中定义的是.cvs训练文件,因此本篇内容主要记录根据.mat生成.cvs的过程,根据不同的数据集,代码略有不同,本文以ShanghaiTech A/B、UCF_CC_50以及WorldExpo 50为例:
代码在 Matlab 中完成
1、高斯核函数,放在get_density_map_gaussian.m文件中,写好的函数,不用动:
function im_density = get_density_map_gaussian(im,points)
im_density = zeros(size(im));
[h,w] = size(im_density);
if(length(points)==0)
return;
end
if(length(points(:,1))==1)
x1 = max(1,min(w,round(points(1,1))));
y1 = max(1,min(h,round(points(1,2))));
im_density(y1,x1) = 255;
return;
end
for j = 1:length(points)
f_sz = 15;
sigma = 4.0;
H = fspecial('Gaussian',[f_sz, f_sz],sigma);
x = min(w,max(1,abs(int32(floor(points(j,1))))));
y = min(h,max(1,abs(int32(floor(points(j,2))))));
if(x > w || y > h)
continue;
end
x1 = x - int32(floor(f_sz/2)); y1 = y - int32(floor(f_sz/2));
x2 = x + int32(floor(f_sz/2)); y2 = y + int32(floor(f_sz/2));
dfx1 = 0; dfy1 = 0; dfx2 = 0; dfy2 = 0;
change_H = false;
if(x1 < 1)
dfx1 = abs(x1)+1;
x1 = 1;
change_H = true;
end
if(y1 < 1)
dfy1 = abs(y1)+1;
y1 = 1;
change_H = true;
end
if(x2 > w)
dfx2 = x2 - w;
x2 = w;
change_H = true;
end
if(y2 > h)
dfy2 = y2 - h;
y2 = h;
change_H = true;
end
x1h = 1+dfx1; y1h = 1+dfy1; x2h = f_sz - dfx2; y2h = f_sz - dfy2;
if (change_H == true)
H = fspecial('Gaussian',[double(y2h-y1h+1), double(x2h-x1h+1)],sigma);
end
im_density(y1:y2,x1:x2) = im_density(y1:y2,x1:x2) + H;
end
end
2、ShanghaiTech A/B 数据集:
图片IMG_1.jpg对应着其坐标标注文件:.GT_IMG_1.mat
用于将.mat生成.csv代码:
clc; clear all;
dataset = 'A/B'; % 这里可以更改A或者B
standard_size = [768,1024]; % 将图像全部调整为这个大小
att = 'test'; % 这里需要在生成csv时调整为train或者test
dataset_name = ['shanghaitech_part_' dataset];
path = ['F:/ShanghaiTech_Part_B/part_' dataset '_final/' att '_data/images/'];
output_path = 'F:/ShanghaiTech_Part_B/'; %保存生成后的csv文件
train_path_img = strcat(output_path, dataset_name,'/', att, '/img/');
train_path_den = strcat(output_path, dataset_name,'/', att, '/den/');
gt_path = ['F:/ShanghaiTech_Part_B/part_' dataset '_final/' att '_data/ground_truth/'];
mkdir(output_path)
mkdir(train_path_img);
mkdir(train_path_den);
if (dataset == 'A')
num_images = 300; % 这里更好的做法是用代码检测文件夹内文件数量;
else
num_images = 316;
end
for idx = 1:2
i = idx;
if (mod(idx,10)==0)
fprintf(1,'Processing %3d/%d files\n', idx, num_images);
end
load(strcat(gt_path, 'GT_IMG_',num2str(i),'.mat')) ;
input_img_name = strcat(path,'IMG_',num2str(i),'.jpg');
im = imread(input_img_name);
[h, w, c] = size(im);
annPoints = image_info{1}.location;
rate_h = standard_size(1)/h;
rate_w = standard_size(2)/w;
im = imresize(im,[standard_size(1),standard_size(2)]);
annPoints(:,1) = annPoints(:,1)*double(rate_w);
annPoints(:,2) = annPoints(:,2)*double(rate_h);
im_density = get_density_map_gaussian(im,annPoints);
im_density = im_density(:,:,1);
imwrite(im, [train_path_img num2str(idx) '.jpg']);
csvwrite([train_path_den num2str(idx) '.csv'], im_density);
end
3、UCF_CC_50数据集,这个数据集的1.jpg图像对应的.mat文件为:1_ann.mat
相应代码:
clc; clear all;
standard_size = [768,1024]; % 调整图像尺寸,全部统一
path ='F:\UCF_CC_50\';
output_path = './data/UCF_CC_50/';
train_path_img = strcat(output_path,'/', 'img/');
train_path_den = strcat(output_path,'/', 'den/');
train_path_seg = strcat(output_path,'/', 'seg/');
mkdir(output_path)
for i_folder = 1:5
mkdir([train_path_img, num2str(i_folder)]);
mkdir([train_path_den, num2str(i_folder)]);
mkdir([train_path_seg, num2str(i_folder)]);
end
cnt = zeros(5,1);
for idx = 1:50
i = idx;
if (mod(idx,10)==0)
fprintf(1,'Processing %3d/%d files\n', idx, 50);
end
load(strcat(path, num2str(i),'_ann.mat')) ;
input_img_name = strcat(path,num2str(i),'.jpg');
im = imread(input_img_name);
[h, w, c] = size(im);
if (c == 3)
im = rgb2gray(im);
end
rate_h = standard_size(1)/h;
rate_w = standard_size(2)/w;
im = imresize(im,[standard_size(1),standard_size(2)]);
annPoints(:,1) = annPoints(:,1)*double(rate_w);
annPoints(:,2) = annPoints(:,2)*double(rate_h);
im_density = get_density_map_gaussian(im,annPoints);
im_density = im_density(:,:,1);
i_corss = ceil(rand(1)*5);
while cnt(i_corss)>=10
i_corss = ceil(rand(1)*5);
end
cnt(i_corss) = cnt(i_corss) +1;
imwrite(im, [train_path_img num2str(i_corss) '/' num2str(idx) '.jpg']);
csvwrite([train_path_den num2str(i_corss) '/' num2str(idx) '.csv'], im_density);
end
4、WorldExpo 50 数据集,数据格式为:1.jpg对应着1.mat标注文件
代码:
clc; clear all;
fileFolder=fullfile('F:\World 10\WorldExpo10\train_label');
dirOutput=dir(fullfile(fileFolder,'*'));
fileNames={dirOutput.name}';
standard_size = [768,1024];
dataset_name = ['WorldExpo10'];
original_path = ['F:/World 10/WorldExpo10/'];
output_path = 'F:/World 10/data/';
att = 'test';
train_path_img = strcat(output_path, 'train_frame/');
mkdir(train_path_img);
for ii = 3:105 % 从3开始
gt_path = ['F:/World 10/WorldExpo10/train_label/' fileNames{ii} '/'];
train_path_den = strcat(output_path, 'train_lable/', fileNames{ii}, '/');
mkdir(train_path_den);
matFolder=fullfile(gt_path);
matdirOutput=dir(fullfile(matFolder,'*'));
matNames={matdirOutput.name}';
num_images=length(matdirOutput)-1;
for idx = 3:num_images
i = idx;
if (mod(idx,10)==0)
fprintf(1,'Processing %3d/%d files\n', idx, num_images);
end
load(strcat(gt_path, matNames{idx}));
input_img_name = strcat(original_path,'train_frame/',strrep(matNames{idx}, 'mat', 'jpg'));
im = imread(input_img_name);
[h, w, c] = size(im);
annPoints = point_position;
rate_h = standard_size(1)/h;
rate_w = standard_size(2)/w;
im = imresize(im,[standard_size(1),standard_size(2)]);
annPoints(:,1) = annPoints(:,1)*double(rate_w);
annPoints(:,2) = annPoints(:,2)*double(rate_h);
im_density = get_density_map_gaussian(im,annPoints); % 调用1. 中的高斯函数
im_density = im_density(:,:,1);
imwrite(im, [output_path 'train_frame/' strrep(matNames{idx}, 'mat', 'jpg')]);
csvwrite([output_path 'train_lable/' fileNames{ii} '/' strrep(matNames{idx}, 'mat', 'csv')], im_density);
end
end