使用数据转换器将 3D 体积显示为图像
Using a Data Converter to Display 3D Volume as Images
我想写一个数据转换工具。我需要分析文件中的比特流以显示 3D 体积的 2D cross-sections。
我想查看的数据集可以在这里找到:https://figshare.com/articles/SSOCT_test_dataset_for_OCTproZ/12356705。
文件标题为:burned_wood_with_tape_1664x512x256_12bit.raw (832 MB)
非常感谢一些指导。如果我能得到一些软件使用数据转换将数据集显示为图像,我愿意悬赏。
由于我对这个概念完全陌生,所以我没有代码来解决这个问题。然而,这里有一些我尝试使用来自其他问题的灵感的东西:
import rawpy
import imageio
path = "Datasets/burned_wood_with_tape_1664x512x256_12bit.raw"
for item in path:
item_path = path + item
raw = rawpy.imread(item_path)
rgb = raw.postprocess()
rawpy.imshow(rgb)
我认为它根本不是有效的 RAW 文件。
如果您尝试此代码:
import rawpy
import imageio
path = 'Datasets/burned_wood_with_tape_1664x512x256_12bit.raw'
raw = rawpy.imread(path)
rgb = raw.postprocess()
您将收到以下错误:
----> 5 raw = rawpy.imread(path)
6 rgb = raw.postprocess()
~\Anaconda3\envs\py37tf2gpu\lib\site-packages\rawpy\__init__.py in imread(pathOrFile)
18 d.open_buffer(pathOrFile)
19 else:
---> 20 d.open_file(pathOrFile)
21 return d
rawpy\_rawpy.pyx in rawpy._rawpy.RawPy.open_file()
rawpy\_rawpy.pyx in rawpy._rawpy.RawPy.handle_error()
LibRawFileUnsupportedError: b'Unsupported file format or not RAW file'
下面我实现了下一个可视化。
示例 RAW 文件 burned_wood_with_tape_1664x512x256_12bit.raw
由每个 A 扫描 1664 个样本、每个 B 扫描 512 个 A 扫描、每个缓冲区 16 个 B 扫描、每个卷 16 个缓冲区以及此文件中的 2 个卷组成,每个样本都被编码为小端顺序的 2 字节无符号整数,仅使用高 12 位,低 4 位包含零。样本大约集中在 2^15 左右,准确地说数据具有这些统计信息 min 0 max 47648 mean 32757 standard deviation 454.5
.
我画了1664 x 512的灰度图,一个文件中总共有16 * 16 * 2 = 512张这样的图(帧)。我使用 matplotlib
库在屏幕上绘制动画帧,还将这些动画渲染到 GIF 文件中。一个以降低质量呈现的 GIF 示例位于代码之后。
对于render/draw不同分辨率的图像,您需要使用plt.rcParams['figure.figsize']
更改代码行,此图大小包含(widht_in_inches,height_in_inches),默认DPI (每英寸点数)等于 100,这意味着如果您想要生成分辨率为 720x265 的 GIF,则需要将此图形大小设置为 (7.2, 2.65)。生成的 GIF 还包含分辨率稍小的动画,因为轴和填充包含在生成的图形大小中。
我的下一个代码需要通过命令安装一次 pip 模块 python -m pip install numpy matplotlib
。
# Needs: python -m pip install numpy matplotlib
def oct_show(file, *, begin = 0, end = None):
import os, numpy as np, matplotlib, matplotlib.pyplot as plt, matplotlib.animation
plt.rcParams['figure.figsize'] = (7.2, 2.65) # (4.8, 1.75) (7.2, 2.65) (9.6, 3.5)
sizeX, sizeY, cnt, bits = 1664, 512, 16 * 16 * 2, 12
stepX, stepY = 16, 8
fps = 5
try:
fsize, opened_here = None, False
if type(file) is str:
fsize = os.path.getsize(file)
file, opened_here = open(file, 'rb'), True
by = (bits + 7) // 8
if end is None and fsize is not None:
end = fsize // (sizeX * sizeY * by)
imgs = []
file.seek(begin * sizeY * sizeX * by)
a = file.read((end - begin) * sizeY * sizeX * by)
a = np.frombuffer(a, dtype = np.uint16)
a = a.reshape(end - begin, sizeY, sizeX)
amin, amax, amean, stdd = np.amin(a), np.amax(a), np.mean(a), np.std(a)
print('min', amin, 'max', amax, 'mean', round(amean, 1), 'std_dev', round(stdd, 3))
a = (a.astype(np.float32) - amean) / stdd
a = np.maximum(0.1, np.minimum(a * 128 + 128.5, 255.1)).astype(np.uint8)
a = a[:, :, :, None].repeat(3, axis = -1)
fig, ax = plt.subplots()
plt.subplots_adjust(left = 0.08, right = 0.99, bottom = 0.06, top = 0.97)
for i in range(a.shape[0]):
title = ax.text(
0.5, 1.02, f'Frame {i}',
size = plt.rcParams['axes.titlesize'],
ha = 'center', transform = ax.transAxes,
)
imgs.append([ax.imshow(a[i], interpolation = 'antialiased'), title])
ani = matplotlib.animation.ArtistAnimation(plt.gcf(), imgs, interval = 1000 // fps)
print('Saving animated frames to GIF...', flush = True)
ani.save(file.name + '.gif', writer = 'imagemagick', fps = fps)
print('Showing animated frames on screen...', flush = True)
plt.show()
finally:
if opened_here:
file.close()
oct_show('burned_wood_with_tape_1664x512x256_12bit.raw')
示例输出 GIF:
我想写一个数据转换工具。我需要分析文件中的比特流以显示 3D 体积的 2D cross-sections。
我想查看的数据集可以在这里找到:https://figshare.com/articles/SSOCT_test_dataset_for_OCTproZ/12356705。
文件标题为:burned_wood_with_tape_1664x512x256_12bit.raw (832 MB)
非常感谢一些指导。如果我能得到一些软件使用数据转换将数据集显示为图像,我愿意悬赏。
由于我对这个概念完全陌生,所以我没有代码来解决这个问题。然而,这里有一些我尝试使用来自其他问题的灵感的东西:
import rawpy
import imageio
path = "Datasets/burned_wood_with_tape_1664x512x256_12bit.raw"
for item in path:
item_path = path + item
raw = rawpy.imread(item_path)
rgb = raw.postprocess()
rawpy.imshow(rgb)
我认为它根本不是有效的 RAW 文件。
如果您尝试此代码:
import rawpy
import imageio
path = 'Datasets/burned_wood_with_tape_1664x512x256_12bit.raw'
raw = rawpy.imread(path)
rgb = raw.postprocess()
您将收到以下错误:
----> 5 raw = rawpy.imread(path)
6 rgb = raw.postprocess()
~\Anaconda3\envs\py37tf2gpu\lib\site-packages\rawpy\__init__.py in imread(pathOrFile)
18 d.open_buffer(pathOrFile)
19 else:
---> 20 d.open_file(pathOrFile)
21 return d
rawpy\_rawpy.pyx in rawpy._rawpy.RawPy.open_file()
rawpy\_rawpy.pyx in rawpy._rawpy.RawPy.handle_error()
LibRawFileUnsupportedError: b'Unsupported file format or not RAW file'
下面我实现了下一个可视化。
示例 RAW 文件 burned_wood_with_tape_1664x512x256_12bit.raw
由每个 A 扫描 1664 个样本、每个 B 扫描 512 个 A 扫描、每个缓冲区 16 个 B 扫描、每个卷 16 个缓冲区以及此文件中的 2 个卷组成,每个样本都被编码为小端顺序的 2 字节无符号整数,仅使用高 12 位,低 4 位包含零。样本大约集中在 2^15 左右,准确地说数据具有这些统计信息 min 0 max 47648 mean 32757 standard deviation 454.5
.
我画了1664 x 512的灰度图,一个文件中总共有16 * 16 * 2 = 512张这样的图(帧)。我使用 matplotlib
库在屏幕上绘制动画帧,还将这些动画渲染到 GIF 文件中。一个以降低质量呈现的 GIF 示例位于代码之后。
对于render/draw不同分辨率的图像,您需要使用plt.rcParams['figure.figsize']
更改代码行,此图大小包含(widht_in_inches,height_in_inches),默认DPI (每英寸点数)等于 100,这意味着如果您想要生成分辨率为 720x265 的 GIF,则需要将此图形大小设置为 (7.2, 2.65)。生成的 GIF 还包含分辨率稍小的动画,因为轴和填充包含在生成的图形大小中。
我的下一个代码需要通过命令安装一次 pip 模块 python -m pip install numpy matplotlib
。
# Needs: python -m pip install numpy matplotlib
def oct_show(file, *, begin = 0, end = None):
import os, numpy as np, matplotlib, matplotlib.pyplot as plt, matplotlib.animation
plt.rcParams['figure.figsize'] = (7.2, 2.65) # (4.8, 1.75) (7.2, 2.65) (9.6, 3.5)
sizeX, sizeY, cnt, bits = 1664, 512, 16 * 16 * 2, 12
stepX, stepY = 16, 8
fps = 5
try:
fsize, opened_here = None, False
if type(file) is str:
fsize = os.path.getsize(file)
file, opened_here = open(file, 'rb'), True
by = (bits + 7) // 8
if end is None and fsize is not None:
end = fsize // (sizeX * sizeY * by)
imgs = []
file.seek(begin * sizeY * sizeX * by)
a = file.read((end - begin) * sizeY * sizeX * by)
a = np.frombuffer(a, dtype = np.uint16)
a = a.reshape(end - begin, sizeY, sizeX)
amin, amax, amean, stdd = np.amin(a), np.amax(a), np.mean(a), np.std(a)
print('min', amin, 'max', amax, 'mean', round(amean, 1), 'std_dev', round(stdd, 3))
a = (a.astype(np.float32) - amean) / stdd
a = np.maximum(0.1, np.minimum(a * 128 + 128.5, 255.1)).astype(np.uint8)
a = a[:, :, :, None].repeat(3, axis = -1)
fig, ax = plt.subplots()
plt.subplots_adjust(left = 0.08, right = 0.99, bottom = 0.06, top = 0.97)
for i in range(a.shape[0]):
title = ax.text(
0.5, 1.02, f'Frame {i}',
size = plt.rcParams['axes.titlesize'],
ha = 'center', transform = ax.transAxes,
)
imgs.append([ax.imshow(a[i], interpolation = 'antialiased'), title])
ani = matplotlib.animation.ArtistAnimation(plt.gcf(), imgs, interval = 1000 // fps)
print('Saving animated frames to GIF...', flush = True)
ani.save(file.name + '.gif', writer = 'imagemagick', fps = fps)
print('Showing animated frames on screen...', flush = True)
plt.show()
finally:
if opened_here:
file.close()
oct_show('burned_wood_with_tape_1664x512x256_12bit.raw')
示例输出 GIF: