I am trying to figure out the details on how to implement the structure tensor in Matlab and need some advice!
For an image $\ I(x,y) $ the structure tensor S is given by:
$$ S=\begin{pmatrix} W \ast I_x^2 & W \ast (I_xI_y)\\ W \ast (I_xI_y) & W \ast I_y^2 \end{pmatrix}$$ where W is a smoothing kernel, $\ \ast $ denotes convolution and subscript denotes partial derivative with respect to.
I want to use a Gaussian as smoothing kernel. This is separable: $$ W = G_{\sigma}*(G_{\sigma})^T$$ The constant $\ \sigma $ controls the outer/integration scale. E.g. if I truncate it at $\ +/- 2\sigma$ and use $\ \sigma = 1$ I get:
$$ G_{\sigma} = [0.0103,0.2076,0.5642,0.2076,0.0103] $$
However the input to the Gaussian might have a mean different from 0.
How do I compensate for this?
I was thinking substracting the mean first.
I could use central differences to estimate the partial derivatives: $$ I_x \approx [-0.5 \hspace{2 pt} 0 \hspace{2 pt} 0.5]*I $$ However since the image is noisy it is probably better to use a more robust differentian operator. The Sobel operator is such an operator. However according to wikipedia it is not perfectly rotational symmetric. The Scharr operators are supposed to be perfectly rotational symmetric and robust approximations of the partial derivatives:
$$ I_x \approx \frac{1}{32}\begin{pmatrix} -3 & 0 & 3\\ -10 & 0 & 10\\ -3 & 0 & 3 \end{pmatrix} * I$$
$$ I_y \approx \frac{1}{32}\begin{pmatrix} -3 & -10 & -3\\ 0 & 0 & 0\\ 3 & 10 & 3 \end{pmatrix} * I$$
The Scharr operators are separable: $$ \begin{pmatrix} -3 & 0 & 3\\ -10 & 0 & 10\\ -3 & 0 & 3 \end{pmatrix} = [-1,0,1]*[3,10,3]^T $$
$$ \begin{pmatrix} -3 & -10 & -3\\ 0 & 0 & 0\\ 3 & 10 & 3 \end{pmatrix} = [3,10,3]*[-1,0,1]^T$$
The elements of the structure tensor now becomes series of consecutive horizontal and vertical convolutions with the original image.
EDIT: Another option (thanks to nikie!) is the Gaussian derivative. Introducing $$ GD_{\sigma}=\frac{-x}{\sigma}G{\sigma}$$
Is this then correct? $$ Ix = G{\sigma}^T*(GD_{\sigma}*I) $$ $$ Iy = G{\sigma}*(GD_{\sigma}^T*I) $$
How do I Implement this easily in Matlab?
How about in C++?
Any comments regarding choice of smoothing kernel and differentiation operator?
EDIT 2: My Matlab code so far:
% I: image
% si: inner (differetiation) scale,
% so: outer (integration) scale
function [Sxx, Sxy, Syy] = structureTensor(I,si,so)
[m n] = size(I);
Sxx = NaN(m,n);
Sxy = NaN(m,n);
Syy = NaN(m,n);
% Robust differentiation by convolution with derivative of Gaussian:
x = -2*si:2*si;
g = exp(-0.5*(x/si).^2);
g = g/sum(g);
gd = -x.*g/si; % is this normalized?
Ix = conv2( g',conv2(gd,I) );
Iy = conv2( g,conv2(gd',I) );
Ixx = Ix.^2;
Ixy = Ix.*Iy;
Iyy = Iy.^2;
% Smoothing:
x = -2*so:2*so;
g = exp(-0.5*(x/so).^2);
Sxx = conv2( g',conv2(g,Ixx) );
Sxy = conv2( g',conv2(g,Ixy) );
Syy = conv2( g',conv2(g,Iyy) );
How do I normalize the Gaussian derivative?