在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

huangapple go评论131阅读模式
英文:

More efficent way of plotting image on 3D plane in matplotlib than using a meshgrid

问题

有没有比这个更好的方法在matplotlib中绘制带有图像的3D平面:

  1. xx, yy = np.meshgrid(np.linspace(0, 1, img_size[1]), np.linspace(0, 1, img_size[0]))
  2. zz = np.ones((img_size[0],img_size[1]))
  3. ax.plot_surface(xx, yy, zz, rstride=1, cstride=1, facecolors=img / 255, shade=False)

我不想创建与像素数量相同的面,因为这相当低效。是否有更好的方法?

这是我的绘图效果:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

英文:

Is there a better way to plot a plane with image in 3D in matplotlib than this:

  1. xx, yy = np.meshgrid(np.linspace(0, 1, img_size[1]), np.linspace(0, 1, img_size[0]))
  2. zz = np.ones((img_size[0],img_size[1]))
  3. ax.plot_surface(xx, yy, zz, rstride=1, cstride=1, facecolors=img / 255, shade=False)

I dont want to create a surface with as many faces as I have pixels, since that quite inefficient.
Is there a better way to do so?

This is what my plot looks like:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

答案1

得分: 2

一个简单的一行方法是按如下方式进行子采样:img_smaller = img[::10, ::10, :]。这将使图像缩小10倍,但由于未应用插值,图像会看起来粗糙,如果尺寸不是10的倍数,则边缘可能会被剪切:

在降采样之前:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

使用数组切片进行降采样:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

另一种方法是在使用PIL加载图像后进行降采样。设置downsample=12,即12倍降采样:

PIL降采样:

  1. from PIL import Image
  2. #加载图像,或者创建一个测试图像
  3. np.random.seed(0)
  4. img = Image.fromarray( np.random.randint(0, 255, size=(100, 100, 3), dtype=np.ubyte))
  5. img = Image.open('.. /image.png')
  6. #进行12倍子采样并应用插值
  7. downsample = 12
  8. img_small = img.resize((img.height // downsample, img.width // downsample),
  9. resample=Image.BICUBIC)
  10. h, w = img_small.height, img_small.width
  11. img_small_arr = np.asarray(img_small)
  12. #绘图
  13. ax = plt.figure(figsize=(3, 3)).add_subplot(projection='3d')
  14. xx, yy = np.meshgrid(np.linspace(0, 1, w), np.linspace(0, 1, h))
  15. zz = np.ones((h, w))
  16. ax.plot_surface(xx, yy, zz, facecolors=img_small_arr / 255, shade=False)
  17. #facecolor=[0,0,0,0], linewidth=1) #可选添加'grid'效果

使用切片的一行方法:

  1. #使用切片进行降采样
  2. img_small_arr = np.asarray(img)[::10, ::10, :]
  3. #新尺寸
  4. h, w, _ = img_small_arr.shape
  5. #其余绘图部分与之前相同
  6. ax = plt.figure(figsize=(3, 3)).add_subplot(projection='3d')
  7. xx, yy = np.meshgrid(np.linspace(0, 1, w), np.linspace(0, 1, h))
  8. zz = np.ones((h, w))
  9. ax.plot_surface(xx, yy, zz, facecolors=img_small_arr / 255, shade=False)
英文:

A simple one-liner method is to subsample as follows: img_smaller = img[::10, ::10, :]. This will subsample it down 10x, but the image will look coarse as no interpolation was applied, and edges may look clipped if the dimensions aren't multiples of 10:

Before downsampling:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

Downsampling using array slicing:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

Another approach is to downsample the image after loading it using PIL. After setting downsample=12, i.e. 12x downsampling:

在matplotlib中绘制图像在3D平面上的更高效方法,比使用网格更好的方式。

PIL downsampling:

  1. from PIL import Image
  2. #Load image, or make a test image
  3. np.random.seed(0)
  4. img = Image.fromarray( np.random.randint(0, 255, size=(100, 100, 3), dtype=np.ubyte))
  5. img = Image.open('../image.png')
  6. #Subsample 12x and apply interpolation
  7. downsample = 12
  8. img_small = img.resize((img.height // downsample, img.width // downsample),
  9. resample=Image.BICUBIC)
  10. h, w = img_small.height, img_small.width
  11. img_small_arr = np.asarray(img_small)
  12. #Plot
  13. ax = plt.figure(figsize=(3, 3)).add_subplot(projection='3d')
  14. xx, yy = np.meshgrid(np.linspace(0, 1, w), np.linspace(0, 1, h))
  15. zz = np.ones((h, w))
  16. ax.plot_surface(xx, yy, zz, facecolors=img_small_arr / 255, shade=False)
  17. #facecolor=[0,0,0,0], linewidth=1) #optionally add a 'grid' effect

One-liner method using slicing:

  1. #Downsample using slicing
  2. img_small_arr = np.asarray(img)[::10, ::10, :]
  3. #New dimensions
  4. h, w, _ = img_small_arr.shape
  5. #Rest of the plotting, as before
  6. ax = plt.figure(figsize=(3, 3)).add_subplot(projection='3d')
  7. xx, yy = np.meshgrid(np.linspace(0, 1, w), np.linspace(0, 1, h))
  8. zz = np.ones((h, w))
  9. ax.plot_surface(xx, yy, zz, facecolors=img_small_arr / 255, shade=False)

huangapple
  • 本文由 发表于 2023年8月9日 18:29:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866876.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定