简体   繁体   English

如何在Python中使用步骤转换将图像正确显示为3D绘图?

[英]How to correctly display an image as a 3D plot with step transitions in Python?

I am trying to visualize differences between images in 3D, in order to more easily differentiate between positive and negative differences. 我试图想象三维图像之间的差异,以便更容易区分正面和负面的差异。

I have succeeded with a basic plot of an image, however, between the values matplotlib is interpolating values. 我已经成功完成了图像的基本绘图,但是,值matplotlib是插值之间的值。 I need these to be step changes between pixels. 我需要这些是像素之间的步骤变化。

I am often testing with very low-resolution images, for example, 16 by 16, so the interpolation has a large effect. 我经常使用非常低分辨率的图像进行测试,例如16乘16,因此插值效果很好。

Numpy file of 16 by 16 image: https://wetransfer.com/downloads/c916f76e0d86a61c00c2ed4cfe4ae97520190210192200/60d87c Numpy文件16 x 16图像: https//wetransfer.com/downloads/c916f76e0d86a61c00c2ed4cfe4ae97520190210192200/60d87c

One way to solve this would be to repeat the values however, this seems very inefficient and requires cleaning up the ticks after. 解决这个问题的一种方法是重复这些值,但这似乎非常低效,需要清理后的滴答声。

在此输入图像描述

Code to generate above image: 生成上图的代码:

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

SubIm = np.load("Subtract_Image.npy")

def ImPlot2D3D(img, cmap=plt.cm.jet):

    Z = img[::1, ::1]

    fig = plt.figure(figsize=(14, 7))

    # 2D Plot
    ax1 = fig.add_subplot(1, 2, 1)
    im = ax1.imshow(Z, cmap=cmap)
    ax1.set_title('2D')
    ax1.grid(False)

    # 3D Plot
    ax2 = fig.add_subplot(1, 2, 2, projection='3d')
    X, Y = np.mgrid[:Z.shape[0], :Z.shape[1]]
    ax2.plot_surface(X, Y, Z, cmap=cmap)
    ax2.set_title('3D')

    plt.show()


ImPlot2D3D(SubIm)

I've looked into 3D bar charts but they all use binning schemes and I can't make it work for an image. 我已经研究过3D条形图,但它们都使用分级方案,我无法使其适用于图像。

Eventually managed to answer my own question. 最终设法回答了我自己的问题。

A brute force method to solve this is to repeat the values in the array, hence making the interpolation between values that 'matplotlib' does, less impactful and better approximating a step change. 解决这个问题的强力方法是重复数组中的值,从而在'matplotlib'的值之间进行插值,减少影响并更好地逼近阶跃变化。 This can be achieved using numpy.repeat . 这可以使用numpy.repeat来实现。 As this is a 3D array we must iterate over one axis than the other. 由于这是一个3D数组,我们必须迭代一个轴而不是另一个轴。 Otherwise, the array will be flattened repeated and this flat array returned. 否则,阵列将被重复展平并返回此平面阵列。

Result: 结果: 结果:

def ImPlot2D3D(img, cmap=plt.cm.jet, step=False, ratio=10):

    if step:
        img = (img.repeat(ratio, axis=0)).repeat(ratio, axis=1)

    Z = img[::1, ::1]

    fig = plt.figure(figsize=(14, 7))

    # 2D Plot
    ax1 = fig.add_subplot(1, 2, 1)
    im = ax1.imshow(Z, cmap=cmap)
    ax1.set_title('2D')
    ax1.grid(False)

    # 3D Plot
    ax2 = fig.add_subplot(1, 2, 2, projection='3d')
    X, Y = np.mgrid[:Z.shape[0], :Z.shape[1]]
    ax2.plot_surface(X, Y, Z, cmap=cmap)
    ax2.set_title('3D')

    # Scale the ticks back down to original values
    if step:
        ticks_x = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x / ratio))
        ticks_y = ticker.FuncFormatter(lambda y, pos: '{0:g}'.format(y / ratio))
        ax1.xaxis.set_major_formatter(ticks_x)
        ax1.yaxis.set_major_formatter(ticks_y)
        ax2.xaxis.set_major_formatter(ticks_x)
        ax2.yaxis.set_major_formatter(ticks_y)

    plt.show()

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

SubIm = np.load("Subtract_Image.npy")
ImPlot2D3D(SubIm, step=True)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM