边缘检测BSDS500数据集处理|边缘检测评判标准-PR曲线

一、边缘检测BSDS500数据集处理

数据集下载下来以后label是以.m格式保存的,需要处理成.jpg或.png格式。

代码如下:

from scipy import io
import scipy
import imageio
import os

#读取mat文件中所有数据
#mat文件里面是以字典形式存储的数据
#包括 dict_keys(['__globals__', 'groundTruth', '__header__', '__version__'])
#我们要用到'groundTruth']中的轮廓
#x['groundTruth'][0][0][0][0][1]为轮廓
#x['groundTruth'][0][0][0][0][0]为分割图


def bsds_trans(root, num_anno):
    PATH = os.path.join(root, 'data\\groundTruth')
    for sub_dir_name in ['train','test','val']:
        sub_pth = os.path.join(PATH,sub_dir_name)
        ##为生成的图片新建个文件夹保存
        save_pth = os.path.join(root,'data\\GT_convert_{}'.format(num_anno),sub_dir_name)
        os.makedirs(save_pth,exist_ok=True)

        print('开始转换'+sub_dir_name+'文件夹中内容')
        for index in range(len(os.listdir(sub_pth))):
            filename = os.listdir(sub_pth)[index]
            data = io.loadmat(os.path.join(sub_pth,filename))
            try:
                if len(data['groundTruth'][0]) < num_anno+1: raise IndexError
                edge_data = data['groundTruth'][0][num_anno][0][0][1]
                edge_data_255 = edge_data * 255
                new_img_name = filename.split('.')[0]+'.jpg'
                print(new_img_name)
                imageio.imsave(os.path.join(save_pth,new_img_name), edge_data_255)
                
            except IndexError:
                index = min(len(os.listdir(sub_pth))-1, index+1)
                filename = os.listdir(sub_pth)[index]


if __name__ == '__main__':
    #运行时需要改变root值为BSD500所在的相应根目录
    root = 'D:\\桌面\\bsds500\\BSR\\BSDS500'
    #选取不同标注者标注的label,范围(0,5)
    num_anno = 5
    bsds_trans(root, num_anno)

说明:1.这个数据集并非一人标注完成,有好几个标注者,更改函数的num_anno参数就可以得到不同标注者标注的label。

二、PR曲线

PR曲线参数的核心Matlab代码

如下:

for k = 1:K
  % threshhold and thin E
  E1 = double(E>=max(eps,thrs(k)));
  if(thin), E1=double(bwmorph(E1,'thin',inf)); end
  % compare to each ground truth in turn and accumualte
  Z=zeros(size(E)); matchE=Z; matchG=Z; allG=Z;
  for g = 1:n
    [matchE1,matchG1] = correspondPixels(E1,G{g},maxDist);
    matchE = matchE | matchE1>0;
    matchG = matchG + double(matchG1>0);
    allG = allG + G{g};
  end
  % compute recall (summed over each gt image)
  cntR(k) = sum(matchG(:)); sumR(k) = sum(allG(:));
  % compute precision (edges can match any gt image)
  cntP(k) = nnz(matchE); sumP(k) = nnz(E1);
  % optinally create visualization of matches
  if(nargout<6), continue; end; cs=[1 0 0; 0 .7 0; .7 .8 1]; cs=cs-1;
  FP=E1-matchE; TP=matchE; FN=(allG-matchG)/n;
  for g=1:3, V(:,:,g,k)=max(0,1+FN*cs(1,g)+TP*cs(2,g)+FP*cs(3,g)); end
  V(:,2:end,:,k) = min(V(:,2:end,:,k),V(:,1:end-1,:,k));
  V(2:end,:,:,k) = min(V(2:end,:,:,k),V(1:end-1,:,:,k));
end

 E1:所有边缘图(手工标注的真值,共6个)二值化的结果(大于阈值的为1,反之为0)

matchE:预测正确的边缘为1,否则为0(预测为边缘的点,在6个真值中存在至少一个对应点为边缘),所以TP=matchE。也就是说预测的边缘点在6个真值中的对应点有一个为边缘,就算你预测的对

matchG:你预测的边缘点在真值中的对应点也为边缘的数量(0~6),也就是说,matchE是matchG二值化的结果(非0值设为1)

allG:真值中把该点预测为边缘的数量(0~6)

cntR: cntR(k) = sum(matchG( : )) 表示对matchG中所有元素求和(即预测正确的点数,若groundTruth有多个子边界图则要把所有子边界图中预测对的求和)
sumR: sumR(k) = sum(allG( : )) 表示对allG中所有元素求和(即所有子边界图中真实边缘点的个数)
cntP: cntP(k) = nnz(matchE) 表示对matchE统计非0元素的个数(预测结果中预测正确的像素数)(nnz表示Number of nonzero,统计非0元素的个数)
sumP: sumP(k) = nnz(E1) 表示对E1统计非0元素的个数(即总边界图中真实边缘点的个数)

最后获得的有用参数为:[thrs cntR sumR cntP sumP],每张图片会在有一个[id]_evl.txt文件与之对应。有99行,分别对应99个不同阈值和相应的cntR sumR cntP sumP值

绘制PR曲线

参考文章

 1.  边缘检测BSDS500数据集处理

2.边缘检测评估指标

  • 13
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值