我试图实现拷贝封面(拷贝移动)图像伪造检测算法,我似乎遗漏了什么。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不是在我的舵手,我相信上面的代码是无效的,但老实说,我只是想让它发挥作用。有人对我做错了什么有什么建议吗?
注意:图片的副本可以找到这里 (我不想发布,因为我不知道图像的版权问题),只需复制粘贴几个81x81大小的图像块周围。
我还包括了我自己的照片,可用于测试。



发布于 2014-03-27 09:33:50
这里的主要问题似乎是算法链接的第6点。上面写着:
但你有:
找到找到的坐标的频率(数一数)
您正在将值对的出现与对之间的偏移发生混淆。这很容易解决。将有关部分改为:
if z > Nd
offset = [xi-xj yi-yj];
P = [P;[xi yi xj yj xi-xj yi-yj]];然后,您希望找出哪些偏移发生得最多,也就是说,哪些偏移发生得最多。然后,xi的值就是那些被检测为被复制的值。您可以使用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结果是

如果你想更进一步:你可能想要清理流浪像素(也就是那些没有邻居的像素)。图像中复制的区域没有被完全覆盖,因为每个值对应的整个块都没有被屏蔽。
https://stackoverflow.com/questions/22517140
复制相似问题