Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create surface plot from greyscale image with Matplotlib?

Let's say I have a greyscale image (size: 550x150 px). I load the image with matplolib

import matplotlib.pyplot as plt
import matplotlib.image as mp_img
image = mp_img.imread("my-cat.png")
plt.imshow(image)
plt.show()

Now, plt.imshow displays the image on the screen. But what I want is a surface plot of the greyscale values, something like this:

.Colour is not really a necessity, but it would be helpful for the height lines. I know, that I need a function of the form f(x,y) -> z to create the surface plot. So, I want to use the greyscale value at (x_pixel,y_pixel) in my image to get the value of f. This leads to my problem:

  • I'd like to do some interpolation (e.g. smoothing) of my image values during plotting. This depends also on the size of my meshgrid, so how do I control this? And,
  • how do I make a surface plot of the greyscale values from my image?
like image 341
BlueLemon Avatar asked Aug 04 '15 09:08

BlueLemon


People also ask

How do I print a grayscale image in matplotlib?

Now open the image using PIL image method and convert it to L mode If you have an L mode image, that means it is a single-channel image – normally interpreted as grayscale. It only stores a grayscale, not color. Plotting the image as cmap = 'gray' converts the colors. All the work is done you can now see your image.

How do I plot a shaded area in matplotlib?

Plot x and y data points, with color=red and linewidth=2. To shade an area parallel to X-axis, initialize two variables, y1 and y2. To add horizontal span across the axes, use axhspan() method with y1, y2, green as shade color,and alpha for transprency of the shade. To display the figure, use show() method.


2 Answers

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import cv2

# generate some sample data
import scipy.misc
lena = cv2.imread("./data/lena.png", 0)

# downscaling has a "smoothing" effect
lena = cv2.resize(lena, (100,100))

# create the x and y coordinate arrays (here we just use pixel indices)
xx, yy = np.mgrid[0:lena.shape[0], 0:lena.shape[1]]

# create the figure
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(xx, yy, lena ,rstride=1, cstride=1, cmap=plt.cm.jet,
                linewidth=0)

# show it
plt.show()

If you want to get color plot, change the code to: "cmap=plt.cm.jet". So you can get something like this: color plot

like image 138
Trinh Nguyen Quoc Avatar answered Oct 09 '22 05:10

Trinh Nguyen Quoc


So this is pretty straightforward. Load the data, build the plot:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# generate some sample data
import scipy.misc
lena = scipy.misc.lena()

# downscaling has a "smoothing" effect
lena = scipy.misc.imresize(lena, 0.15, interp='cubic')

# create the x and y coordinate arrays (here we just use pixel indices)
xx, yy = np.mgrid[0:lena.shape[0], 0:lena.shape[1]]

# create the figure
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(xx, yy, lena ,rstride=1, cstride=1, cmap=plt.cm.gray,
        linewidth=0)

# show it
plt.show()

Result:

enter image description here

like image 29
hitzg Avatar answered Oct 09 '22 03:10

hitzg