问题描述
我正在尝试编写一个简单的可视化脚本,其中包含一些 mri 切片及其相应的掩码。将两者叠加并让我使用 j 和 k 键滚动时间序列。
这是我到目前为止所得到的并且它有效(从某种意义上说,它为我提供了上述功能)。
import matplotlib.pyplot as plt
import numpy as np
import nibabel as nib
import argparse
import os
import re
import matplotlib
def multiSliceViewer(volume):
# get rid of matplotlibs prevIoUs use for j,k keys
remove_keymap_conflicts({'j','k'})
# create figure
fig,ax = plt.subplots()
# set volume and index as attributes of ax
ax.volume = volume
ax.index = len(volume)//2
img,mask = ax.volume[ax.index]
# set 0 values to None so mask can be drawn on top of mri slice image
mask[mask==0]=None
# draw image and then over lay mask on top
ax.imshow(img,cmap = 'gray')
ax.imshow(mask,cmap = 'autumn')
fig.canvas.mpl_connect('key_press_event',process_key)
def process_key(event):
"""Set actions for keys j and k"""
fig = event.canvas.figure
ax = fig.axes[0]
if event.key == 'j':
prevIoUs_slice(ax)
elif event.key == 'k':
next_slice(ax)
fig.canvas.draw()
def prevIoUs_slice(ax):
"""Go to the prevIoUs slice."""
volume = ax.volume
# wrap around using % to enable continuous scrolling
ax.index = (ax.index - 1) % len(volume)
img,mask = volume[ax.index]
mask[mask==0]=None
ax.imshow(img,cmap = 'autumn')
def next_slice(ax):
"""Go to the next slice."""
volume = ax.volume
# wrap around using % to enable continuous scrolling
ax.index = (ax.index + 1) % len(volume)
img,cmap = 'autumn')
def remove_keymap_conflicts(new_keys_set):
"""takes in a set of keys and removes the action paired with them"""
for prop in plt.rcParams:
if prop.startswith('keymap.'):
keys = plt.rcParams[prop]
remove_list = set(keys) & new_keys_set
for key in remove_list:
keys.remove(key)
if __name__=="__main__":
parser = argparse.ArgumentParser()
parser.add_argument("img_path",help="path to imgs",type=str)
parser.add_argument("mask_path",help="path to masks",type=str)
args = parser.parse_args()
img_path = args.img_path
mask_path = args.mask_path
# image and mask file arrays
img_files = [f for f in os.listdir(img_path) if f.endswith('.nii.gz')]
mask_files = [f for f in os.listdir(mask_path) if f.endswith('.nii.gz')]
# sort imgs and masks by numbering (WARNING: Only works if theres 1 numerical expression in filename)
# eg - frame-312.nii.gz or frame312.nii.gz OK
# BUT - frame312-2.nii.gz will break code
sorted_img_files = sorted(img_files,key = lambda x :int(re.findall(r'\d+',x)[0]))
sorted_mask_files = sorted(mask_files,x)[0]))
# load imgs and masks
imgs_array = [nib.load(os.path.join(img_path,f)).get_fdata() for f in sorted_img_files]
masks_array = [nib.load(os.path.join(mask_path,f)).get_fdata() for f in sorted_mask_files]
# create image volume to be passed to multi slice viewer,time axis set to 0
volume=[]
for idx in range(len(imgs_array)):
volume.append((imgs_array[idx],masks_array[idx]))
multiSliceViewer(volume)
我可以通过按 j 和 k 来翻转帧,主要问题是这太慢了。加载下一张图片需要几秒钟的时间。
在查看了有关此主题的堆栈溢出之后,很多人都提到了 blitting 可以加快重新绘制过程,但是调用 figureCanvasBase.supports_blit
给了我 False
。有没有其他方法可以加快这个重新绘制过程?无论如何,除了掩码周围的区域之外,是否可以将有关绘图的所有内容存储在内存中,以便它只重新绘制掩码周围的区域(这是帧之间唯一变化的位)。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)