边缘检测评估指标
文章目录边缘检测评估指标一、边缘检测的具体评估指标二、目标检测分类中Precision(精确度)和Recall(召回率)的计算三、边缘检测任务中计算Precision和Recall代码中计算Precision和Recall四、边缘检测评估指标OIS、ODS、AP的计算1.PR曲线2.OIS-F值3.ODS-F值4.AP5.R50边缘检测评估指标最近在研究边缘提取,复现了文章Richer Convo
文章目录
边缘检测评估指标
最近在研究边缘提取,复现了文章Richer Convolutional Features for Edge Detection的代码,在做评估的时候遇到了一些问题,不知道在边缘检测中精确率和召回率到底是怎么计算的,终于搞明白后决定记录下来。本篇博客的记录所有出现的代码都源于这里。
一、边缘检测的具体评估指标
- Precision(精确率):在边缘检测中精确率表示机器生成的边界像素是真实边界像素的概率。
- Recall(召回率):在边缘检测中召回率表示检测到真实边界像素占所有真实边界像素的概率。
- PR曲线:精确率——召回率曲线
- F-Measure:F-Measure也叫F-Score(F值),是Precision和Recall的调和平均数,通过调整β的值来调整精确率和召回率的比重,
一般取β=1,此时F-Measure的取值为:
论文中使用的也是该公式。
- ODS和OIS:两者都是选定阈值的一种方法
ODS是optimal dataset scale的缩写,表示全局最优阈值,对数据集中的所有图像采用一个固定的阈值。也就是选取一个阈值使之运用于所有图片得到的F值最大。
OIS是optimal image scale的缩写,表示每幅图像的最佳阈值。也就是说它为每个图像选择一个最佳阈值使该图像的F值最大。 - AP:表示Average Precision,平均精确率,它是PR曲线的积分,也就是PR曲线下方的面积。
- R50:(RCF代码中出现的论文中没提到)在50%精确率下的召回率。
二、目标检测分类中Precision(精确度)和Recall(召回率)的计算
在目标检测、分类中,我们使用TP 、TN 、FP 、FN来计算Precision(精确度)和Recall(召回率):
精确率表示:预测为正例的结果中有多少是真的正例。强调预测的准确性。
召回率表示:所有真的正例中有多少被预测为正例。强调把多少真正的正例召唤回来。
三、边缘检测任务中计算Precision和Recall
在边缘检测中判断预测边界像素是否被正确预测需用到一个概念“距离容差”,它的作用是对预测结果tolerant,允许预测与真实边界图存在小的定位错误。
在correspondPixels算法中距离容差通过一个参数maxDist表示,代码默认该参数设置为0.0075。在自己求这个距离容差时,可以使用maxDist乘自己图片的大小(高或宽)。若你的图片为256481,则在行方向上允许2560.0075≈2像素的距离容差,在列方向上允许481*0.0075≈4像素的距离容差。也可以更改maxDist的值。
代码中计算Precision和Recall
有一些参数必须要知道:
-
E1:所有手工标注的真值边缘图(该image的groundTruth有多少个boundaries,就有多少个真值边缘图,我认为也可称为子边界图。例如BSDS500数据集中test集中的图片2018.jpg对应的groundTruth有5个边缘图)进行二值化后求“并”的结果(我认为这个结果可以称为总边界图)。有一个边缘图对应的像素点大于阈值就为1,否则为0。
举例说明:假如一张3*3的图片有三个真值边界图(在某一阈值下),
那么得到的E1就是:
计算过程如下:
-
matchE:预测的边缘点在所有真值map中有至少一个的对应点为边缘点就表示预测正确(也就是说在3个真值中,只要有一个与预测边缘点相对应,就可以认为预测正确)。预测正确的边缘点为1,否则为0。所以TP=matchE。
上例中的matchE应该为:
计算过程如下:
-
matchG:你预测的边缘点在真值中也为边缘点的点数(从0到真实边缘图
数)。在上例中,每一个像素可取的值为0-3。
计算过程如下:
可以看出,从matchG到matchE就是对每个元素进行二值化的结果,matchG中的非零值设为1,0值保持0. -
allG:在真值中把对应点预测为边缘点的点数(从0到真实边缘图数)。上例
中可取的值为0-3。
计算过程:
这几个变量都是二维矩阵,大小等于输入图像的高和宽。
此时,通过计算四个值:
- 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元素的个数(即总边界图中真实边缘点的个数)
在上例中:
cntR(k) =3 sumR(k)=7 cntP(k)=2 sumP(k)=5
求Precision:cntP /sumP
求Recall:cntR/ sumR
四、边缘检测评估指标OIS、ODS、AP的计算
1.PR曲线
通过上一步计算P和R,最后得到的有用的参数:[thrs cntR sumR cntP sumP], thrs表示阈值。每张图片会有一个[id]_evl.txt文件。有99行,分别对应99个不同阈值和相应的cntR sumR cntP sumP值。对于每一个阈值求相应的Precision和Recall就可画出PR曲线。
2.OIS-F值
将每张图片对应的txt文件读出来后,首先计算每一张图片的R、P、F,它们都是T行一列的矩阵,其中T为阈值个数。
代码:
function [R,P,F] = computeRPF(cntR,sumR,cntP,sumP)
% compute precision, recall and F measure given cnts and sums
R=cntR./max(eps,sumR);
P=cntP./max(eps,sumP);
F=2*P.*R./max(eps,P+R);
end
这样就能找到使F值最大的阈值k,也就是该张图片的最佳阈值。将得到的结果保存在eval_bdry_img.txt内。
代码:
function [bstR,bstP,bstF,bstT] = findBestRPF(T,R,P)
% linearly interpolate to find best thr for optimizing F
if(numel(T)==1), bstT=T; bstR=R; bstP=P;
bstF=2*P.*R./max(eps,P+R); return; end
A=linspace(0,1,100); B=1-A; bstF=-1;
for j = 2:numel(T)
Rj=R(j).*A+R(j-1).*B; Pj=P(j).*A+P(j-1).*B; Tj=T(j).*A+T(j-1).*B;
Fj=2.*Pj.*Rj./max(eps,Pj+Rj); [f,k]=max(Fj);
if(f>bstF), bstT=Tj(k); bstR=Rj(k); bstP=Pj(k); bstF=f; end
end
end
如果看不懂的话,可以参考一下我自己记录时画的图:
对每张图片计算[R,P,F] = computeRPF(cntR1,sumR1,cntP1,sumP1); [~,k]=max(F);这样就能找到使F值最大的阈值k,在计算PR曲线时得到的[id]_evl.txt文件中就能读出相应的cntR1(k),sumR1(k),cntP1(k),sumP1(k)。找到使每张图片F值最大的cntR,sumR,cntP,sumP,然后分别求和,使用computeRPF(cntR,sumR,cntP,sumP)求出对应的P、R、F就是OIS所需参数。
3.ODS-F值
直接按照阈值将所有图片的cntR,sumR,cntP,sumP分别求和,使用computeRPF(cntR,sumR,cntP,sumP)得到不同阈值下的T、R、P,然后利用findBestRPF(T,R,P)找到F取到最大值的那一组。对应的T就是ODS方法所取得应用于所有图片的阈值。
4.AP
平均准确率,是PR曲线的积分(即PR曲线下方的面积)。由于PR曲线很难积分,通常在PR曲线上采样求均值。
代码:
k=k(end:-1:1);
R=R(k);
P=P(k);
T=T(k);
F=F(k);
AP=0;
if(numel(R)>1),
AP=interp1(R,P,0:.01:1);%插值,来提高精确度
AP=sum(AP(~isnan(AP)))/100; %求均值
End
5.R50
论文中没有说这个指标,但是代码写到了,代码计算如下:
[~,o]=unique(P); R50=interp1(P(o),R(o),max(P(o(1)),.5));
记录到此结束了,若有错误请提出并见谅~
另外提供几个我参考的比较好的博客:
https://www.cnblogs.com/jiangnanyanyuchen/p/13868320.html
https://blog.csdn.net/AAAAshin/article/details/108042346
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)