Как создать изображение гауссовского шума uint16? - PullRequest
0 голосов
/ 08 февраля 2019

Я хочу создать uint16 изображение гауссовского шума с определенным средним и стандартным отклонением.

Я пытался использовать для этого numpy's random.normal, но он возвращает массив float64:

mu = 10
sigma = 100
shape = (1024,1024)
gauss_img = np.random.normal(mu, sigma, shape)

print(gauss_img.dtype)

>>> dtype('float64')

Есть ли способ преобразовать gauss_img в массив uint16 при сохранении исходного среднего значения и стандартного отклонения ?Или есть другой подход, полностью основанный на создании изображения шума uint16?

РЕДАКТИРОВАТЬ: Как было упомянуто в комментариях, np.random.normal неизбежно будет отбирать отрицательные значения с учетом sd> среднего, что является проблемой для преобразования в uint16.

Так что я думаю, что мне нужен другой метод, который создаст гауссовское изображение без знака напрямую.

Ответы [ 3 ]

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

Если у вас есть диапазон номеров uint16 для выборки, вы должны проверить этот пост .

Таким образом, вы можете использовать scipy.stats.truncnorm чтобы создать гауссиан из целых чисел без знака.

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

Так что я думаю, что это близко к тому, что вы ищете.

Импорт библиотек и подделка некоторых искаженных данных.Здесь, поскольку входные данные неизвестного происхождения, я создал искаженные данные, используя np.expm1(np.random.normal()).Вы также можете использовать skewnorm().rvs(), но это обман, поскольку вы также будете использовать его для определения характеристик.

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

import numpy as np
from scipy.stats import skewnorm

# generate dummy raw starting data
# smaller shape just for simplicity
shape = (100, 100)
raw_skewed = np.maximum(0.0, np.expm1(np.random.normal(2, 0.75, shape))).astype('uint16')

# flatten to look at histograms and compare distributions
raw_skewed = raw_skewed.reshape((-1))

Теперь найдите параметры, которые характеризуют ваши искаженные данные, и используйте их, чтобы создать новый дистрибутив для выборки, который, как мы надеемся, хорошо соответствует вашим исходным данным.

Эти две строки кода действительно то, что выпосле того, как я думаю.

# find params
a, loc, scale = skewnorm.fit(raw_skewed)

# mimick orig distribution with skewnorm
new_samples = skewnorm(a, loc, scale).rvs(10000).astype('uint16')

Теперь нарисуйте распределения каждого из них для сравнения.

plt.hist(raw_skewed, bins=np.linspace(0, 60, 30), hatch='\\', label='raw skewed')
plt.hist(new_samples, bins=np.linspace(0, 60, 30), alpha=0.65, color='green', label='mimic skewed dist')
plt.legend()

enter image description here

Гистограммы довольно близки.Если это выглядит достаточно хорошо, измените ваши новые данные в нужную форму.

# final result
new_samples.reshape(shape)

Теперь ... вот где я думаю, что это, вероятно, не дотягивает.Посмотрите на тепловую карту каждого.Первоначальный дистрибутив имел более длинный хвост справа (больше выбросов, которые skewnorm() не характеризовали).

На этом графике показана тепловая карта каждого.

# plot heatmaps of each
fig = plt.figure(2, figsize=(18,9))
ax1 = fig.add_subplot(1, 2, 1)
ax2 = fig.add_subplot(1, 2, 2)

im1 = ax1.imshow(raw_skewed.reshape(shape), vmin=0, vmax=120)
ax1.set_title("raw data - mean: {:3.2f}, std dev: {:3.2f}".format(np.mean(raw_skewed), np.std(raw_skewed)), fontsize=20)

im2 = ax2.imshow(new_samples.reshape(shape), vmin=0, vmax=120)
ax2.set_title("mimicked data - mean: {:3.2f}, std dev: {:3.2f}".format(np.mean(new_samples), np.std(new_samples)), fontsize=20)

plt.tight_layout()

# add colorbar
fig.subplots_adjust(right=0.85)
cbar_ax = fig.add_axes([0.88, 0.1, 0.08, 0.8])  # [left, bottom, width, height]
fig.colorbar(im1, cax=cbar_ax)

Глядя на это ..... вы можете видеть случайные желтые пятна, указывающие на очень высокие значения в исходном распределении, которые не попали в вывод.Это также проявляется в более высоком стандартном отклонении входных данных (см. Заголовки в каждой тепловой карте, но, опять же, как в комментариях к исходному вопросу ... имеется ввиду, что & std на самом деле не характеризует распределения, поскольку они не являются нормальными).... но они в качестве относительного сравнения).

Но ... в этом-то и заключается проблема, связанная с очень специфическим искаженным образцом, который я создал для начала.Надеюсь, здесь достаточно, чтобы возиться и настраиваться, пока не будет соответствовать вашим потребностям и конкретному набору данных.Удачи!

enter image description here

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

С этим средним значением и сигмой вы обязаны отобрать некоторые отрицательные значения.Поэтому я думаю, что вариант может заключаться в том, что вы найдете наиболее отрицательное значение после выборки и добавите его абсолютное значение ко всем выборкам.После этого конвертируйте в uint, как предлагается в комментариях.Но, конечно же, вы теряете ссору таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...