4

I'm trying to calculate a 3d sobel filter in python. I have a pretty good code for 2d image which is below.

btw. my original image is uint8 type.

    preSobel = preSobel.astype('int32')
    dx = ndimage.sobel(preSobel, 0)  # horizontal derivative
    dy = ndimage.sobel(preSobel, 1)  # vertical derivative
    mag = numpy.hypot(dx, dy)  # magnitude
    mag *= 255.0 / numpy.max(mag)  # normalize (Q&D)
    img[i,:,:]=mag

but from my understanding of the wiki page for calculating 2d, i should have multiplied the 1d sobel results rather than hypot :confused

anyway, to go to 3d, I guess I need to calculate 1d sobel on each axis and then multiply all but I'm not sure... Is there any library out there that calculates 3d sobel faster ?

2
  • 1
    The wiki gives you the exact 3x3x3 convolution kernel to use, why not just use it? Commented Jun 29, 2012 at 20:04
  • Always good policy to implement algorithms from scratch to have a better understanding. But in case you want to use a library to solve the problem, or to compare your results, you find it already implemented from scikit. See scikit-image.org/docs/dev/user_guide/numpy_images.html under coordinate conventions. Commented Dec 8, 2016 at 9:09

1 Answer 1

5

First, in reference to your wikipedia link: The multiplication there is referring to the way to construct the sobel convolution kernel, not the end result.

For a 2D sobel filter you need a kernel to get the derivate in x direction, and another kernel to get the derivate in Y direction, e.g. enter image description here

This is essentially what your two commands do, so if you are using numpy you do not need to construct these kernels yourself.

dx = ndimage.sobel(preSobel, 0)  # horizontal derivative
dy = ndimage.sobel(preSobel, 1)  # vertical derivative

Now for the 3D case you need 3 operations with 3 kernels, one for dx, dy, dz. The linked wiki section is telling you how to construct the kernels by multiplying components. The finished sobel kernel for dZ for example is a 3x3x3 matrix that looks like this:

enter image description here

To get the magnitude you still have to take the square root of the squared derivatives (the hypotenuse) afterwards.

I do not have numpy but as far as I can tell from the documentation the ndimage sobel command can deal with any number of dimensions, so again, the kernels are already provided:

dx = ndimage.sobel(your3Dmatrix, 0)  # x derivative
dy = ndimage.sobel(your3Dmatrix, 1)  # y derivative
dz = ndimage.sobel(your3Dmatrix, 2)  # z derivative

now the hypotenuse command probably only take 2 parameters, so you will have to find another way to efficiently calculate mag = sqrt(dxdx + dydy + dz*dz) . But NumPy should have everything you need for that.


Update

Actually, if you are only interested in the magnitude anyway, there is a complete function in numpy for this:

 mag = generic_gradient_magnitude(your3Dmatrix, sobel)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.