Gradient field gradient image in Python

I am trying to get a Gradient vector field of an image using Python (similar to this question in mataba ).

This is the original image: http: / /dcc.fceia.unr.edu.ar/~rbaravalle/gradient/test.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

The problem is that the vectors seem to be wrong. This point becomes clearer when zooming in:

http://dcc.fceia.unr.edu.ar/~rbaravalle/gradient/result2.png

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

Perhaps there was a problem with the result of calling np.gradient ?

+8
python numpy image image-processing gradient
source share
1 answer

I think your strange results, at least in part, because p is of type uint8 . Even numpy diff results in obviously incorrect values ​​for the array of this dtype. If you convert to a signed integer, replacing the definition of p with the following: p = np.asarray(I).astype(int8) , then the diff results 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

and close it looks the way you expected

enter image description here

+7
source share

All Articles