Search code examples
matlabimage-processingedge-detection

calculating the gradient of a 3D matrix


I have a 3D matrix and want to calculate the gradient for this matrix. The only step which I did is defining image gradient for a 2D image as follow:

sx = [-1 0 1; -2 0 2; -1 0 1];
sy = [1 2 1; 0 0 0; -1 -2 -1];
Gx = conv2(input, sx, 'same');
Gy = conv2(input, sy, 'same');


grdmg = sqrt(Gx.^2+Gy.^2);
grddr = atan2(Gy,Gx);

I am wondering that how I can extend this code to 3D? I know that in 3D matrix I should use convn, but do not know that how I should change the sx, sy and make sz.


Solution

  • If you want to calculate a 3D gradient, you would have to make your kernel 3D as well. Not only are you checking for changes in the ith slice of your matrix, but you also need to check the (i-1)th slice and the (i+1)th slice as well.

    As a minor comment, sy should be the transpose of sx, but you don't have that here. Make sure you change this before you do anything.

    Also, with the added dimension, you have three more possible kernels because you need to check for changes horizontally in each slice, vertically in each slice, or temporally. As such, you would simply make sz either by replicating sx along the third dimension three times, or replicating sy along the third dimension three times or making a temporal kernel where the first slice is all 1, the second slice is all zero and the third slice is all -1. Therefore, calling all of these kernels szx, szy and szz, you would create them as:

    szx = cat(3, sx, sx, sx);
    szy = cat(3, sy, sy, sy);
    szz = cat(3, ones(3,3), zeros(3,3), -ones(3,3));
    

    To compute the magnitude, you would simply find the magnitude of all of these components together and use convn as you have suggested:

    Gx = convn(input, szx, 'same');
    Gy = convn(input, szy, 'same');
    Gz = convn(input, szz, 'same');
    grdmg = sqrt(Gx.^2 + Gy.^2 + Gz.^2);
    

    As for the angle, this is very ambiguous because you now have three components, and if you want to find the angle, you would need to have two vectors in 3D space and find the angle in between those two vectors. For 2D this is well defined as you have already created 2 vectors, and so the angle is simply the arctan between the vertical and horizontal components. Because you have three components, and there are two to choose from, there are three possible angles you can compute, each with respect to either the x, y or z axis.

    I don't have an answer for you here in this case, but this particular example from Math StackExchange may give you further insight on how to calculate the angle using the 3D gradient. The important point is that you need to know which axis you are measuring the angle with respect to.

    https://math.stackexchange.com/questions/569019/how-do-you-get-3d-gradient-direction-and-magnitude


    Good luck!