[英]How to create a uint16 numpy array from a uint8 raw image data array
[英]How to create uint16 gaussian noise image?
我想創建一個具有定義的均值和標准差的uint16高斯噪聲圖像。
我試過使用numpy的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噪點圖像的方法?
編輯:如評論中所述,給定sd>平均值, np.random.normal
將不可避免地對負值進行采樣,這對於轉換為uint16是一個問題。
因此,我認為我需要一種可以直接創建無符號高斯圖像的不同方法。
所以我認為這與您要尋找的很接近。
導入庫並欺騙一些偏斜的數據。 在這里,由於輸入來源不明,因此我使用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()
直方圖非常接近。 如果看起來足夠好,請將新數據重塑為所需的形狀。
# 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 dev中(請參閱每個熱圖中的標題,但同樣,如對原始問題的評論一樣……Mean&std不能真正表征分布,因為它們是不正常的。 ,但它們只是作為相對比較)。
但這只是我創建的非常具體的偏斜樣本所面臨的問題。 希望這里有足夠的東西可以解決和調整,直到它適合您的需求和您的特定數據集。 祝好運!
使用該均值和sigma,您一定會采樣一些負值。 因此,我猜選項可能是您在采樣后找到了最大的負值,並將其絕對值添加到所有樣本中。 之后,按照注釋中的建議轉換為uint
。 但是,當然,您可以通過這種方式降低均值。
如果您有一系列uint16數字可供選擇,那么您應該查看這篇文章 。
這樣,您可以使用scipy.stats.truncnorm生成無符號整數的高斯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.