# Shock filtering using structure tensor

my name is niladri, I am new to image processing(actually this is my first code). I want to implement shock filter using structure tensor. I have rough idea of what structure tensor is and implemented in MATLAB. But to design a shock I need to calculate the sign using the dominating eigenvector. But as for my understanding dominating eigenvector will be number(real and complex) for any matrix and structure tensor is basically a 2X2 matrix for each point(x,y). please correct me if my understanding is wrong. My code so far is Edit:11/08/16: I have completed the Code but still not getting the correct response. I am unable to understand my misconception

 clc;
clear all;

[m,n] = size(I);
struct_scale = 3;
%inte_scale = 5;

x = -2*struct_scale:2*struct_scale;
g  = exp(-0.5*(x/struct_scale).^2);
g  = g/sum(g);
gd = -x.*g/(struct_scale^2);
Ix = conv2(g', conv2(gd, double(I)));

Iy = conv2(g, conv2(gd', double(I)));

sx = Ix^2;
sxy = Ix*Iy;
sy = Iy^2;

%fileID = fopen('D:\IP\test.txt','w');
fileID1 = fopen('D:\IP\test2.txt','w');

for i = 1:512
for j = 1:512
s = [sx(i,j) sxy(i,j);sxy(i,j) sy(i,j)];
%[v ,d] = sort(eigs(s));
[v1, d1] = sort(diag(real(eig(s))));
%[u , s1, d] = svd(s);
v_perp = [0 -1;1 0 ]*v1(:,1);
t = abs(dot(v1(:,1),v_perp));

if v1(dot(v_perp, u(:,1)))>1E-9
disp(t);
end

c  = [v1(:,1),v_perp];
temp = det(c);

if temp > 0
res = 1;
elseif temp < 0
res = 0;
end

fprintf(fileID1,'%1d',res);
end
fprintf(fileID1,'\n');
end
fclose(fileID1);


I think that the question here is "how is the dominant direction of the local slope actually estimated?" with the outlook of using it in a shock filter.

A Shock Filter is applied iteratively and each time it propagates grayscale values along the direction of an edge but not across the edge, therefore, progressively, the edge is preserved but the area towards the broad direction of the structure is "filled". This is similar to applying dilation or erosion but taking into account the local contrast gradient. The edge can be defined at various scale levels, which results to the average direction of an edge defined over a bigger area surrounding a pixel of interest $(x,y)$.

The code seems alright, in that it sets up the normalised Gaussian g and then derives its first order derivative in gd. It uses that to obtain the gradients Ix,Iy but sx, sxy should be pointwise, rather than matrix, operations. Otherwise, Ix, Iy, "filter" each other. By controlling for the variance parameter of g (and by extension, gd too), we control how big the area around the pixel of interest $(x,y)$ is (or, in terms of dilation and erosion, how big the disk -or structuring element- is).

At this point, Ix, Iy could be used to estimate the local contrast gradient but if we come across areas with roughly opposite slopes, then averaging their components would result to 0 and the (false) perception that the area is flat. Instead, the Structure Tensor is used and more specifically the eigenvector that corresponds to the largest eigenvalue (and there is one of those for each $(x,y)$ pair). For more information please see this link and specifically sections 2, 3 and 4.

So, with that vector indicating the direction of the gradient of an edge, we find the perpendicular vector (with that sign flipping) and propagate values in that direction.

Hope this helps.

• Thank you for response. But the link you have send I am trying to implement the same(I am following the same paper). But how can I find the perpendicular vector in terms code with the sign flipping?? Aug 1 '16 at 19:21
• Thanks for letting me know, if you feel that you were helped by this response you might want to consider upvoting it or accepting it as an answer to the given question. As far as perpendicular vectors are concerned, please see this link and this link
– A_A
Aug 1 '16 at 19:44
• Sorry for delayed response. Correct me if i am wrong, for the eigenvector corresponding to the largest eigenvalue. I need to calculate the vector perpendicular to it and find the cross product of the two vector and this vector will be positive to Z-axis then the sign will +ve and if along negative Z-axis then the sign will be -ve. But I have a question,in matlab cross product of 2 matrix will give another matrix. How this matrix will give a sign. I have used Gram-Schmidt to calculate the perpendicular vector for the corresponding eigenvector. Aug 6 '16 at 13:06
• I am not sure I understand the "problem" because, recovering the perpendicular vector is probably the easiest step of the whole process. One way could be to rotate the given vector by 90 degrees and another to transpose coords and negate one...(?)
– A_A
Aug 6 '16 at 14:47
• Sorry sir I can get the perpendicular Matrix of the given Eigen vector by just rotating in 90 to get the resultant vector. But to find the croos product of the two vector what method I should use?? Aug 7 '16 at 4:15