Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to plot vector field on image?

In order to understand visually the involved vector, scalar fields of an image operation which involves calculating, gradient, divergence, laplacian etc, I am trying to plot them also on the image involved. I started with gradient as below, but

  1. getting the arrow set rotated (looks like so), compared to image underneath. What am I missing?
  2. Also how do I scale them nicely?

MWE:

test_img = cv2.imread('images/ring.png', cv2.IMREAD_GRAYSCALE)
r, c = test_img.shape
gd = 15

test_slice = test_img[::gd,::gd]  # every 15th point

X, Y = np.mgrid[0:r:gd, 0:c:gd]
dY, dX = np.gradient(test_slice)

plt.figure(figsize=(10,10))
plt.quiver(X, Y, dX, dY, color='y')
plt.imshow(test_img, cmap='gray')
plt.show()

Output:

enter image description here

Desired style : (vector field with image underneath instead):

enter image description here

Sample Image used: link

Note: I initially used a png, then then alpha area was giving a nan, so now I have the jpg uploaded.

like image 275
Parthiban Rajendran Avatar asked Jun 21 '26 01:06

Parthiban Rajendran


1 Answers

The short answer is: np.mgrid() is giving you a transposed (i.e. rotated) matrix, see this article for example.

In the following, I'm using matplotlib.image to load the image (which I first converted back into a .png). I flatten the image (i.e. remove the alpha channel) and use imshow with a fitting colormap ("Greys_r"). The important part however is in Y, X = np.mgrid[0:r:gd, 0:c:gd], which you probably would have spotted yourself if your image weren't square to begin with.

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

fname="/path/to/ring.png"
im = mpimg.imread(fname)
flat_image=(im[:,:,0]+im[:,:,1]+im[:,:,2])/3.

r, c = np.shape(flat_image)
gd = 4

test_slice = flat_image[::gd,::gd]  # sampling

fig,ax=plt.subplots(1,1)
the_image = ax.imshow(
                flat_image,
                zorder=0,alpha=1.0,
                cmap="Greys_r",
                origin="upper",
                interpolation="hermite",
            )
plt.colorbar(the_image)            
Y, X = np.mgrid[0:r:gd, 0:c:gd]
dY, dX = np.gradient(test_slice)
ax.quiver(X, Y, dX, dY, color='r')


plt.show()

The resulting image (with the colormap viridis, however) seems to do what you want. Image with quiver

like image 128
Asmus Avatar answered Jun 22 '26 14:06

Asmus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!