Image Gradient Vector Field in Python
Question: I am trying to get the [Gradient Vector
Field](http://upload.wikimedia.org/wikipedia/commons/thumb/0/0f/Gradient2.svg/566px-
Gradient2.svg.png) of an image using Python (similar to [this matlab
question](http://stackoverflow.com/questions/10416918/compute-gradient-vector-
field-of-an-image)).

This is the original image: ![http:/
/dcc.fceia.unr.edu.ar/~rbaravalle/gradient/test.png](http://i.stack.imgur.com/y7XgK.png)

Here is my code:

    
    
    import numpy as np
    import matplotlib.pyplot as plt
    import Image
    from PIL import ImageFilter
    
    I = Image.open('test.png').transpose(Image.FLIP_TOP_BOTTOM)
    I = I.filter(ImageFilter.BLUR)
    p = np.asarray(I)
    w,h = I.size
    y, x = np.mgrid[0:h:500j, 0:w:500j]
    
    dy, dx = np.gradient(p)
    skip = (slice(None, None, 3), slice(None, None, 3))
    
    fig, ax = plt.subplots()
    im = ax.imshow(I, extent=[x.min(), x.max(), y.min(), y.max()])
    ax.quiver(x[skip], y[skip], dx[skip], dy[skip])
    
    ax.set(aspect=1, title='Quiver Plot')
    plt.show()
    

This is the result:
![http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/result.png](http://i.stack.imgur.com/gGiEe.png)

The problem is that the vectors seem to be incorrect. This point gets more
clear when you zoom in the image:

![http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/result2.png](http://i.stack.imgur.com/DWuwY.png)

Why do some of the vectors point to the center as expected, while others do
not?

Maybe there is an issue with the result of the call to `np.gradient`?


Answer: I think your strange results are, at least in part, because p is of type
`uint8`. Even numpy diff results in clearly incorrect values for an array of
this dtype. If you convert to signed integer by replacing the definition of
`p` with the following: `p = np.asarray(I).astype(int8)` then the results of
diff are correct. The following code gives me what looks like a reasonable
field,

    
    
    import numpy as np
    import matplotlib.pyplot as plt
    import Image
    from PIL import ImageFilter
    
    I = Image.open('./test.png')
    I = I.filter(ImageFilter.BLUR)
    p = np.asarray(I).astype('int8')
    w,h = I.size
    x, y = np.mgrid[0:h:500j, 0:w:500j]
    
    dy, dx = np.gradient(p)
    skip = (slice(None, None, 3), slice(None, None, 3))
    
    fig, ax = plt.subplots()
    im = ax.imshow(I.transpose(Image.FLIP_TOP_BOTTOM), 
                   extent=[x.min(), x.max(), y.min(), y.max()])
    plt.colorbar(im)
    ax.quiver(x[skip], y[skip], dx[skip].T, dy[skip].T)
    
    ax.set(aspect=1, title='Quiver Plot')
    plt.show()
    

This gives the following:

![Solution](http://i.stack.imgur.com/j1h8A.png)

and close up this looks like you'd expect,

![enter image description here](http://i.stack.imgur.com/6pnOH.png)

