我正在尝试实施复制封面(复制 - 移动)图像伪造检测algorithm,我似乎错过了一些东西。 matlab程序运行没有任何错误,但我得到的输出几乎包括整个图像。
基本算法(据我所知):
注意:这仅适用于灰度图像(我正在使用),除非你打破RGB颜色。
matlab代码:
%L = imread('images/lena3.jpg');
L = imread('images/Toronto2_F.png');
L=rgb2gray(L);
figure(1);
imshow(L);
b=256; % block size used to look for duplicates
b1=sqrt(b);
Nn = 5; % how many close rows to check
Nd = 15; %Threashold
Nc=26; % Truncate PCA at this length
Nt=26;
% calculate the total size of the image
n = numel(L);
b2 = sqrt(n)-sqrt(b)+1;
% calculate Nb
Nb= power((sqrt(n)-sqrt(b)+1),2);
% the matix of Nc plus the position
M=zeros(Nb, Nc);
% temp index array
Mi = zeros(Nb, 2);
i=1;
disp('Starting PCA');
for r = 1:b2
for c = 1:b2
% Extract each block
B = L(r:r+b1-1,c:c+b1-1);
[pc, latent, explained] = pcacov(cov(double(B)));
%[pc, latent, explained] = princomp(double(B), 'NumComponents', Nc);
Z = pc(1:Nc);
Mi(i,:) = [r c];
M(i,:) = Z;
i = i+1;
end
end
disp('Sorting M -> S');
%Sort M array in lexicographic order -> S
[S, index] = sortrows(M);
P= zeros(1,3);
disp('Finding Duplicates');
for i = 1:Nb
iv = index(i);
xi=mod(iv,b2) + 1;
yi=ceil(iv/b2);
j = i+1;
while j < Nb && abs(i - j) < Nn
jv=index(j);
xj=mod(jv,b2) + 1;
yj=ceil(jv/b2);
z=sqrt(power(xi-xj,2) + power(yi-yj,2));
% only process those whose size is above Nd
if z > Nd
idx = find(P(:,1)== xi & P(:,2)==yi, 1, 'last');
if isempty(idx)==1
P = [P; [xi, yi, 1]];
else
P(idx,3) = P(idx,3) + 1;
end
idx = find(P(:,1)== xi & P(:,2)==yi, 1, 'last');
if isempty(idx)==1
P = [P; [xj, yj, 1]];
else
P(idx,3) = P(idx,3) + 1;
end
end
j = j + 1;
end
end
disp('Sorting findings');
rows = size(P,1);
% sort descending order
P = sortrows(P, -3);
% Mark the found blocks
disp('Creating Image');
idx = 1;
% Create a black image
RI = zeros(sqrt(n), sqrt(n));
while idx < rows && P(idx,3) > 5
x = P(idx,1);
y = P(idx,2);
RI(x,y) = 1;
idx = idx + 1;
end
figure(2);
imshow(RI);
matlab不在我的驾驶室中,我确信上面的代码并不高效,但说实话,我只是想让它发挥作用。任何人都有任何建议我可能做错了吗?
注意:可以找到图像的副本here(我不想发布,因为我不知道图像周围的版权问题),只需复制粘贴几个81x81大小的图像块。
我还附上了我自己的照片,可用于测试。
答案 0 :(得分:4)
这里的主要问题似乎是链接算法的第6点。它说:
- 找出具有最高偏移频率的坐标对
醇>
但你有:
找到找到的坐标的频率(计算它们)
您将值对的出现与对之间出现的偏移混淆。 这很容易修复。将相关部分更改为:
if z > Nd
offset = [xi-xj yi-yj];
P = [P;[xi yi xj yj xi-xj yi-yj]];
然后,您想要找到哪个偏移最多,哪个是[xi-xj yi-yj]最多出现的。然后,值[xi yi xj yj]是被检测为被复制的值。您可以使用matlab函数模式查找数组中最常出现的元素,但是您必须将2个偏移值组合成一个。然后,您可以屏蔽图像以找到检测到的区域:
rows = size(P,1);
P(:,6) = P(:,6) - min(P(:,6));
P(:,5) = P(:,5) - min(P(:,5));
maxValP = max(P(:,6)) + 1;
P(:,5) = maxValP .* P(:,5) + P(:,6);
mostfrequentval = mode(P(:,5));
disp('Creating Image');
idx = 2;
% Create a copy of the image and mask it
RI = L;
while idx < rows
x1 = P(idx,1);
y1 = P(idx,2);
x2 = P(idx,3);
y2 = P(idx,4);
if (P(idx,5) == mostfrequentval)
RI(y1:y1,x1:x1) = 0;
RI(y2:y2,x2:x2) = 0;
end
idx = idx + 1;
end
结果是
如果你想进一步: 您可能想要清理杂散像素(即没有邻居的像素)。复制在图像中的区域并未完全覆盖,因为与每个值对应的整个块未被屏蔽掉。