Как правильно отобразить изображение в виде 3D графика с пошаговыми переходами в Python? - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь визуализировать различия между изображениями в 3D, чтобы легче было различать положительные и отрицательные различия.

Однако мне удалось составить базовый график изображения между значениями matplotlib интерполирует значения.Мне нужно, чтобы это были ступенчатые изменения между пикселями.

Я часто тестирую изображения с очень низким разрешением, например, 16 на 16, поэтому интерполяция имеет большой эффект.

Файл Numpy из 16 на 16 изображений: https://wetransfer.com/downloads/c916f76e0d86a61c00c2ed4cfe4ae97520190210192200/60d87c

Один из способов решить эту проблему - повторить значения, однако, это кажется очень неэффективным и требует очистки тиков после.

enter image description here

Код для создания изображения выше:

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)

Я просмотрел гистограммы 3D, но все они используют схемы биннинга, и яне может заставить его работать на изображение.

1 Ответ

0 голосов
/ 11 февраля 2019

В конце концов мне удалось ответить на мой собственный вопрос.

Метод грубой силы, чтобы решить эту проблему, состоит в том, чтобы повторить значения в массиве, что делает интерполяцию между значениями, что делает 'matplotlib', менее эффектной и лучше приближеннойшаг изменения.Это может быть достигнуто с помощью numpy.repeat .Поскольку это трехмерный массив, мы должны выполнять итерации по одной оси, а не по другой.В противном случае массив будет повторен и этот плоский массив будет возвращен.

Результат: Results:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...