复制移动算法不起作用

时间:2014-03-19 20:16:41

标签: image matlab

我正在尝试实施复制封面(复制 - 移动)图像伪造检测algorithm,我似乎错过了一些东西。 matlab程序运行没有任何错误,但我得到的输出几乎包括整个图像。

基本算法(据我所知):

  1. 创建PCA值的Nb x Nc矩阵,其中Nb =(sqrt(N) - * sqrt(b)+1)^ 2且Nc为27
  2. 按行排序
  3. 循环排序数组和| i-j | < Nn处理项目(行彼此相邻)
  4. 查找正在处理的像素的偏移量并丢弃彼此不相邻的像素
  5. 找到找到的坐标的频率(计算它们)
  6. 将最高数量的点绘制到新图像上。
  7. 注意:这仅适用于灰度图像(我正在使用),除非你打破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大小的图像块。

    我还附上了我自己的照片,可用于测试。

    Original Image Forged Image Output of findings

1 个答案:

答案 0 :(得分:4)

这里的主要问题似乎是链接算法的第6点。它说:

  
      
  1. 找出具有最高偏移频率的坐标对
  2.   

但你有:

  

找到找到的坐标的频率(计算它们)

您将值对的出现与对之间出现的偏移混淆。 这很容易修复。将相关部分更改为:

    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

结果是

image with areas copied blacked out

如果你想进一步: 您可能想要清理杂散像素(即没有邻居的像素)。复制在图像中的区域并未完全覆盖,因为与每个值对应的整个块未被屏蔽掉。