copy move forgery detection stuck with algorithm - matlab

I am trying to implement the paper detection of copy move forgery using histogram of oriented gradients.
The algorithm is:
Divide the image into overlapping blocks.
Calculate feature vectors for each block and store them in a matrix.
Sorting the matrix lexicographically
Using block matching to identify forged regions.
https://www.researchgate.net/publication/276518650_Detection_of_copy-move_image_forgery_using_histogram_of_orientated_gradients
I am stuck with the 3rd step and can't proceed.
The code I have implemented is:
clc;
clear all;
close all;
%read image
img = imread('006_F.png');
img=rgb2gray(img);
img=imresize(img, 1/4);
figure(1);
imshow(img);
b=16; %block size
nrc=5; %no. of rows to check
td=416; %threshold
[r, c]=size(img);%Rows and columns;
column=(r-b+1)*(c-b+1);
M= zeros(column,4);
Mi = zeros(1,2);
i=1;
disp('starting extraction of features');
for r1 = 1:r-b+1
for c1 = 1:c-b+1
% Extract each block
B = img(r1:r1+b-1,c1:c1+b-1);
features = extractHOGFeatures(B);%extracting features
M(i, :) = features;
Mi(i,:) = [r1 c1];
i=i+1;
end
end
[S, index] = sortrows(M , [ 1 2 3 4]);
P= zeros(1,6);
b2=r-b+1;
disp('Finding Duplicates');
for i = 1:column
iv = index(i);
xi=mod(iv,b2) + 1;
yi=ceil(iv/b2);
j = i+1;
while j < column && abs(i - j) < 5
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 > 16
offset = [xi-xj yi-yj];
P = [P;[xi yi xj yj xi-xj yi-yj]];
end
j = j + 1;
end
end
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 = img;
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;

After going through some references indicated in the paper you are working on (ref. [8] and [20]):
The lexicographic sorting is the equivalent of the alphabetical one, for numbers i.e., [1 1 1 1] < [1 1 2 1] < [2 3 4 5] < [2 4 4 5]
So, in your case, you case use the function sortrows() in the following way:
A = [1 1 1 1;1 1 1 2;1 1 1 4;1 2 2 2; 1 2 2 1; 1 4 6 3; 2 3 4 5; 2 3 6 6]; % sample matrix
[B,idx] = sortrows(A,[1 2 3 4]); % Explicit notation but it is the Matlab default setting so equivalent to sortrows(A)
It means: Sort the rows of A by first looking at the first column and, in case of equality, looking at the second one, and so on.
If your are looking for a reverse order, you specify '-' before the number of the column.
So in the end, your code is good and if the results are not as expected it has to come from another step of the implementation...
Edit: the parameter idx records the original index of the sorted rows.

Related

How to determine number of hops using a vector?

I have a MATLAB matrix like below:
column no: 1 2 3 4 5 6
matrix elements 1 1 2 3 6 2
Column numbers represent node ID and elements of the matrix represent the node towards which that node points. Please help me find hop count from a particular node to node 1. I have written the following code but it doesn't solve the problem.
x = ones(1, n);
checkbit = zeros(1, n);
nodedest = [1 1 2 3 6 2];
hopcount = zeros(1, n);
for i = 1:n
for j = 1:n
if nodedest(j) == 1 && checkbit(j) == 0
hopcount(j) = hopcount(j) + 1;
checkbit(j) = 1;
else
x(j) = nodedest(j);
end
if x(j) ~= 1
hopcount(j) = hopcount(j) + 1;
x(j) = nodedest(x(j));
end
end
end
You are looking for a breadth-first search to find the shortest path in your graph. Without touching the data in any way, you can do this in O(n) time per node, given the tree-like structure of your graph:
nodedest = [1 1 2 3 6 2];
hopcount = zeros(1, 6);
for n = 2:6
k = n
while k ~= 1
hopcount(n) = hopcount(n) + 1
k = nodedest(k)
end
end
If you are willing to reverse the sense of your edges (introducing a one-to-many relationship), you could accomplish the same thing in one pass, reducing the entire algorithm from O(n2) to O(n) time complexity. The trade-off would be that memory complexity would increase from O(1) to O(n):
nodedest = [1 1 2 3 6 2];
% Reverse the input
nodesource = cell(1, 6);
nodesource(:) = {[]}
for n = 2:6
k = nodedest(n);
nodesource{k} = [nodesource{k} n];
end
% implement bfs, using the assumption that the graph is a simple tree
hopcount = zeros(1, 6);
cache = [1];
hops = 0;
while ~isempty(cache)
next = []
for c = cache
hopcount(c) = hops;
next = [next nodesource(c)]
end
hops = hops + 1;
cache = next
end

How to oppositely order two vectors in Matlab?

I have the code below for oppositely ordering two vectors. It works, but I want to specify the line
B_diff(i) = B(i) - B(i+1);
to hold true not just for only
B_diff(i) = B(i) - B(i+1); but for
B_diff(i) = B(i) - B(i+k); where k can be any integer less than or equal to n. The same applies to "A". Any clues as to how I can achieve this in the program?
For example, I want to rearrange the first column of the matrix
A =
1 4
6 9
3 8
4 2
such that, the condition should hold true not only for
(a11-a12)(a21-a22)<=0;
but also for all
(a11-a13)(a21-a23)<=0;
(a11-a14)(a21-a24)<=0;
(a12-a13)(a22-a23)<=0;
(a12-a14)(a22-a24)<=0; and
(a13-a14)(a23-a24)<=0;
## MATLAB CODE ##
A = xlsread('column 1');
B = xlsread('column 2');
n = numel(A);
B_diff = zeros(n-1,1); %Vector to contain the differences between the elements of B
count_pos = 0; %To count the number of positive entries in B_diff
for i = 1:n-1
B_diff(i) = B(i) - B(i+1);
if B_diff(i) > 0
count_pos = count_pos + 1;
end
end
A_desc = sort(A,'descend'); %Sort the vector A in descending order
if count_pos > 0 %If B_diff contains positive entries, divide A_desc into two vectors
A_less = A_desc(count_pos+1:n);
A_great = sort(A_desc(1:count_pos),'ascend');
A_new = zeros(n,1); %To contain the sorted elements of A
else
A_new = A_desc; %This is then the sorted elements of A
end
if count_pos > 0
A_new(1) = A_less(1);
j = 2; %To keep track of the index for A_less
k = 1; %To keep track of the index for A_great
for i = 1:n-1
if B_diff(i) <= 0
A_new(i+1) = A_less(j);
j = j + 1;
else
A_new(i+1) = A_great(k);
k = k + 1;
end
end
end
A_diff = zeros(n-1,1);
for i = 1:n-1
A_diff(i) = A_new(i) - A_new(i+1);
end
diff = [A_diff B_diff]
prod = A_diff.*B_diff
The following code orders the first column of A opposite to the order of the second column.
A= [1 4; 6 9; 3 8; 4 2]; % sample matrix
[~,ix]=sort(A(:,2)); % ix is the sorting permutation of A(:,2)
inverse=zeros(size(ix));
inverse(ix) = numel(ix):-1:1; % the un-sorting permutation, reversed
B = sort(A(:,1)); % sort the first column
A(:,1)=B(inverse); % permute the first column according to inverse
Result:
A =
4 4
1 9
3 8
6 2

How to vectorize double loop in Matlab?

y = 0;
for m = 0:variable
for n = 0:m
y = y + f(n,m);
end
end
I vectorized the inner loop this way,
y = 0;
for m = 0:variable
n = 0:m
y = y + f(n,m);
end
This resulted in around 60% speed increase for my code. How do I also vectorize the outer loop?
You are probably looking for the meshgrid function. It is designed to fill in the sort of m by n combinations that it looks like you need. For example:
>> m = 1:4;
>> n = 1:3;
>> [mGridValues, nGridValues] = meshgrid(m,n)
mGridValues =
1 2 3 4
1 2 3 4
1 2 3 4
nGridValues =
1 1 1 1
2 2 2 2
3 3 3 3
This is a little more complicated since your inner loop depends on the value of your outer loop. So you will need to mask out the undesired [n, m] pairs (see below).
Modifying the prototype code that you have provided, you would end up with something like this:
[mValues, nValues] = meshgrid(0:variable, 0:variable); %Start with a full combination of values
mask = mValues >= nValues; %Identify all values where m >= n
mValues = mValues(mask); % And then remove pairs which do not
nValues = nValues(mask); % meet this criteria
y = f(nValues, mValues ); %Perform whatever work you are performing here

How to specific not converging criterion of an iteration in matlab?

Hi everyone this is What I did to carry out an iteration method(gauss seidel) and I want when iteration number greater than 30 it will stop and generate the corresponding result up to 30 iteration. But I wonder why the output result were so weird and I try to check the value on the command window by typing x_ans(:,1) it gives me the correct value. It really made me frustrated why the generate result were not the same. Or any other circumstance or function can be used to set for not converging condition. Sincerely thanks in advance for every single help.
clear;clc
A = [2 8 3 1;0 2 -1 4;7 -2 1 2;-1 0 5 2]
B = [-2;4;3;5]
Es = 1e-5
n = length(B);
x = zeros(n,1);
Ea = ones(n,1);
iter = 0;
while max(Ea) >= Es
if iter <= 30
iter = iter + 1;
x_old = x;
for i = 1:n
j = 1:n;
j(i) = [];
x_cal = x;
x_cal(i) = [];
x(i) = (B(i) - sum(A(i,j) * x_cal)) / A(i,i);
end
else
break
end
x_ans(:,iter) = x;
Ea(:,iter) =abs(( x - x_old) ./ x);
end
result = [1:iter; x_ans; Ea]'
I've gone through the formulas and they are all OK. On a side note, the sum is not necessary. The problem lies with your input data - try reordering! check for example the following, which works
A = [7 -2 1 2;
2 8 3 1;
-1 0 5 2;
0 2 -1 4;]
B = [3;-2;5;4]
see the wiki under convergence.

how to select specific index in 3rd matrix from third dimention in matlab

I know this is a simple question but difficult to formulate in one sentence to google the answer.So, I have a 3d matrix with size 2x2x3 like this
A(:,:,1) =[1 1; 1 1];
A(:,:,2) =[2 2; 2 2];
A(:,:,3) =[4 4; 4 4];
and matrix B with size 2x2
B = [ 1 2; 2 3];
What i need is to chose from each third dimension in A just one number using matrix B:
for i=1:2,
for j=1:2,
C(i,j) = A(i,j,B(i,j));
end
end
How to that in one line without a loop?
Not really a single line, but without a loop:
[I J] = ind2sub (size(B), 1:numel(B));
linInd = sub2ind (size (A), I, J, B(:)');
C = reshape (A(linInd), size(B));
Here is another variation:
[r,c,~] = size(A);
[J,I] = meshgrid(1:size(B,1), 1:size(B,2));
idx = reshape(I(:) + r*(J(:)-1) + r*c*(B(:)-1), size(B));
C = A(idx)