关于像素级移除复制-移动篡改边界像素的F-measure计算的Matlab实现问询
复制-移动伪造定位的F-score计算问题:边界像素排除的实现
我正在做复制-移动伪造(copy-move forgery)定位研究,需要计算F-score。已经拿到输出图和真值(ground-truth)图像,但计算结果和现有文献不符。其中一篇文献提到:“在像素层面,我们从F-measure计算中移除复制-伪造区域与背景之间的所有边界像素”,我不清楚这句话的含义,也不知道怎么在Matlab中实现,求专业帮助。
现有计算代码
function [tpr,fpr,acc,fs]=calculate_statis(technique_binary_image, ground_truth) technique_binary_image = technique_binary_image./255.0; ground_truth = ground_truth./255.0; false_positives=0; false_negatives=0; true_positives=0; true_negatives=0; totalClone = 0; totalNormal = 0; for i=1:size(technique_binary_image,1) for j=1:size(technique_binary_image,2) if technique_binary_image(i,j)==ground_truth(i,j) && ground_truth(i,j)~=0 true_positives=true_positives+1; end if technique_binary_image(i,j)==ground_truth(i,j) && ground_truth(i,j)==0 true_negatives=true_negatives+1; end if technique_binary_image(i,j)~=ground_truth(i,j) && ground_truth(i,j)~=0 false_negatives=false_negatives+1; end if technique_binary_image(i,j)~=ground_truth(i,j) && ground_truth(i,j)==0 false_positives=false_positives+1; end if ground_truth(i,j)~=0 totalClone = totalClone + 1; end if ground_truth(i,j)==0 totalNormal = totalNormal + 1; end end end tpr=(true_positives)/totalClone; fpr=(false_positives)/totalNormal; acc = (tpr + (1 - fpr))/2; pres=(true_positives)/(true_positives + false_positives); %fs=2*tpr*pres/(pres + tpr); %fs=(2*tpr)/(tpr+fpr+1); fs=(2*true_positives)/((2*true_positives)+false_positives+false_negatives); end
文献表述含义
这里的“边界像素”指两类:
- 属于伪造区域(真值中为1)但周围存在背景像素(真值中为0)的边缘像素;
- 属于背景(真值中为0)但周围存在伪造区域像素的紧邻背景像素。
这类像素在伪造定位任务中极易出现误判,文献将它们从F-score计算的样本池里剔除,就是为了避免边界的模糊误差干扰最终指标的准确性。
Matlab实现方案
核心思路
- 从真值图中识别出所有边界像素;
- 生成掩码标记这些边界像素;
- 遍历统计时跳过掩码标记的像素,只计算非边界区域的TP/TN/FP/FN。
修改后的完整代码
function [tpr,fpr,acc,fs]=calculate_statis(technique_binary_image, ground_truth) % 归一化图像到0-1区间 technique_binary_image = technique_binary_image./255.0; ground_truth = ground_truth./255.0; % 提取真值中的边界像素 % 用3x3圆盘结构元素做膨胀,膨胀后与原图的差值就是边界 se = strel('disk', 1); % 伪造区域的边界:膨胀后的伪造区域 - 原伪造区域 gt_dilated = imdilate(ground_truth, se); gt_boundary = gt_dilated - ground_truth; % 背景的边界:膨胀后的背景 - 原背景 bg_gt = 1 - ground_truth; bg_dilated = imdilate(bg_gt, se); bg_boundary = bg_dilated - bg_gt; % 合并两类边界,得到总边界掩码 total_boundary = gt_boundary | bg_boundary; false_positives=0; false_negatives=0; true_positives=0; true_negatives=0; totalClone = 0; totalNormal = 0; % 遍历图像,跳过边界像素 [rows, cols] = size(technique_binary_image); for i=1:rows for j=1:cols if total_boundary(i,j) == 1 continue; % 跳过边界像素,不参与统计 end if technique_binary_image(i,j)==ground_truth(i,j) && ground_truth(i,j)~=0 true_positives=true_positives+1; end if technique_binary_image(i,j)==ground_truth(i,j) && ground_truth(i,j)==0 true_negatives=true_negatives+1; end if technique_binary_image(i,j)~=ground_truth(i,j) && ground_truth(i,j)~=0 false_negatives=false_negatives+1; end if technique_binary_image(i,j)~=ground_truth(i,j) && ground_truth(i,j)==0 false_positives=false_positives+1; end if ground_truth(i,j)~=0 totalClone = totalClone + 1; end if ground_truth(i,j)==0 totalNormal = totalNormal + 1; end end end % 计算各项指标 tpr=(true_positives)/totalClone; fpr=(false_positives)/totalNormal; acc = (tpr + (1 - fpr))/2; pres=(true_positives)/(true_positives + false_positives); fs=(2*true_positives)/((2*true_positives)+false_positives+false_negatives); end
代码说明
strel('disk',1)生成3x3的圆盘结构元素,用来做膨胀操作,确保能捕获到所有相邻的边界像素;total_boundary掩码会把所有需要排除的边界像素标记为1,遍历的时候直接跳过这些像素;- 其余指标计算逻辑和原代码完全一致,只是排除了边界像素的统计,这样就能和文献中的计算方式对齐。
内容的提问来源于stack exchange,提问作者sama
相关产品推荐
相关产品推荐

