1、数据的处理部分
首先,通过我们训练好的网络,我们可以得到训练后的test图像、以及训练集的GT
由于原benchmark是针对于BSDS数据集进行评价,我们先进行一些数据的处理。
将GT中的图片格式转换为.mat格式,如果是jpg/png图片可以参考以下python代码:(非原创在csdn找的,如侵权后续找到出处会加注)
只需要将src_dir和save_dir换成自己的即可,这样转化得到的就是对应的.mat格式,其本质是一个二值图像,但是为了对应BSDS数据集的格式还需要将其中的255换成1,这步应该也有批量操作的方法,但是我的测试集数据不多,就直接在.mat格式的基础上用excel操作的,这步做完会得到相应数量的.mat文件,其中只有0和1(非边缘和边缘)。
import os
import re
import glob
import numpy as np
from PIL import Image
import scipy.io as io
src_dir = 'G:/jigou_experiment/jigou_dataset_test/gt_clip/'
save_dir = 'G:/jigou_experiment/jigou_dataset_test/gt_clip_mat/'
all_file = os.walk(src_dir)
fileNum = 0
for root, dirs, files in all_file:
#print(root, end=',')
for file in files:
fileNum = fileNum + 1
print(src_dir+file)
file_ext = os.path.splitext(file)
front, ext = file_ext
#print(front) #获取图片名字前缀
#print(ext) # 获取图片后缀
img = Image.open(src_dir+file)
#保存为.npy
res = np.array(img, dtype='uint16')
if not os.path.exists(save_dir):
os.mkdir(save_dir)
np.save(save_dir+front+'.npy', res)
#保存为.mat
numpy_file = np.load(save_dir+front+'.npy')
#io.savemat(save_dir+front+'.mat', {'data': numpy_file})
io.savemat(save_dir+front+'.mat', {'groundTruth':[{'Boundaries':numpy_file}]})
#删除中间文件mat
delete_command ='rm -rf '+save_dir+'*.npy'
print(delete_command)
os.system(delete_command)
print('共转化了'+ str(fileNum)+'张')
2、由于深度神经网络输出的边缘一般都比较宽,因此大多数方法会在测评之前加上一步后处理也就是nms抑制,这步的代码在RCF的caffe版本代码中有写,https://github.com/yun-liu/RCF/blob/master/examples/rcf/edge_nms.m
为了方便直接贴在此处,运行所有matlab代码建议使用2016及之前的版本,新版本会产生函数冲突,之后发生许多不可言说的错误。。。。。。(一把血汗泪)
其中path_to_pdollar就是你安装pdollar工具箱的路径,运行这些评价代码需要安装pdollar toolbox和pdollar_edges两个工具箱。
其中input即为你自己的训练结果,output就是你希望保存的位置
clear; clc;
path_to_pdollar = 'C:/Users/ERMIAO/AppData/Roaming/MathWorks/MATLAB Add-Ons/Collections/pdollar_edges';
path_to_input = 'G:/jigou_experiment/jigou_multiRCF_test_bestepoch/ex_bound_clip/';
path_to_output = 'G:/jigou_experiment/jigou_multiRCF_test_bestepoch/ex_bound_clip_nms/';
addpath(genpath(path_to_pdollar));
mkdir(path_to_output);
iids = dir(fullfile(path_to_input, '*_fuse.png'));
for i = 1:length(iids)
edge = imread(fullfile(path_to_input, iids(i).name));
edge = 1-single(edge)/255;
%edge = single(edge)/255;
[Ox, Oy] = gradient2(convTri(edge, 4));
[Oxx, ~] = gradient2(Ox);
[Oxy, Oyy] = gradient2(Oy);
O = mod(atan(Oyy .* sign(-Oxy) ./ (Oxx + 1e-5)), pi);
% 2 for BSDS500 and Multi-cue datasets, 4 for NYUD dataset
edge = edgesNmsMex(edge, O, 2, 5, 1.01, 8);
imwrite(edge, fullfile(path_to_output, [iids(i).name(1:end-9) '.png']));
end
有些人会出现运行后边缘反而变得很宽,这说明灰度反了,将这两句换一下即可。
edge = 1-single(edge)/255;
%edge = single(edge)/255;
以上操作完你就会得到一个nms抑制处理过的边缘概率图像,效果就是边缘更细。
3、第三步就是进行评价,这里我对比了多种方法,我运行成功的是hed中给出的评价代码,别问我为什么不用hed的nms抑制方法,问就是我当时已经运行出来了!!!!!
GitHub - xwjabc/hed: A PyTorch reimplementation of Holistically-Nested Edge Detection
将其中的eval文件夹下载下来放在matlab中,把eval_edge.m改成这个样子,因为我已经nms操作过了,所以只需要section2。
% Command to run.
% (echo "data_dir = '../output/epoch-x-test'"; cat eval_edge.m)|matlab -nodisplay -nodesktop -nosplash
% Data directory data_dir should be defined outside.
%fprintf('Data dir: %s\n', data_dir);
addpath(genpath('./edges'));
addpath(genpath('./toolbox.badacost.public'));
% Section 2: Evaluate the edges (formerly EvalEdge.m from HED repo).
disp('Evaluate the edges...');
gtDir = 'G:/jigou_experiment/jigou_dataset_test/gt_clip_mat_byNum_bin/';
resDir = 'G:/jigou_experiment/jigou_RCF_test_bestepoch/test_out_bestepoch_nms_byNum/';
edgesEvalDir('resDir',resDir,'gtDir',gtDir, 'thin', 1, 'pDistr',{{'type','parfor'}},'maxDist',0.0075);
figure; edgesEvalPlot(resDir,'RCF');
这回如果你运气好的话就可以得到你想要的ODS、OIS、AP以及绘制好的PR曲线了。
虽然我觉得我这一套流程应该不会有什么问题了。。。(又是血和泪的一套教训)
4、如果你想要绘制多个方法的曲线在一张图上的话参考一下
https://github.com/yun-liu/plot-edge-pr-curves
大家肯定都很厉害,,只是我当初做这个的时候很希望能有一套完善的教程教教我,so,如果你和我一样可以参考一下我的碎碎念,祝大家实验顺利!
哈哈哈哈,第一篇博文,附上我的狗子