基于冷冻电镜图像的低通滤波(Lowpass Filter)算法
Posted SpikeKing
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于冷冻电镜图像的低通滤波(Lowpass Filter)算法相关的知识,希望对你有一定的参考价值。
目标:将冷冻电镜图像,通过低通滤波算法降噪,输入冷冻电镜图像,输出信息集中的降噪图像。
脚本位置:cryosparc/cryosparc_master/cryosparc_compute/jobs/imports/run.py
Particles:Lowpass Filtered Images:
Lowoass Filtered源码位置:
逻辑:
fig = plotutil.plot_images_simple(dispparts, rows=4, cols=8, radwn=6, figscale=1.5)
rc.log_plot(fig, 'Lowpass Filtered Images: ')
plotutil:cryosparc/cryosparc_master/cryosparc_compute/plotutil.py
解耦lowpass + fft逻辑:
img = images[imgi]
rD = img
N = rD.shape[0]
D = fourier.fft(rD)
Cval = -1.0
lowpass_mask = sigproc.lowpass_mask(N, 2, self.radwn, lowpassorder=self.lowpassorder)
dispim = fourier.ifft(lowpass_mask*D*Cval)
vmax = max(-dispim.min(), dispim.max())*vscale
vmin = -vmax
cmap='gray'
imshow(dispim , cmap, colorbar=False, vmin=vmin, vmax=vmax)
测试图像:
img_dir = "/nfs_baoding/chenlong/datasets/cryoEM/kongfang/cryo_dataset_4_imagenet_v1_1/train/1"
img_name = "018444013402718290241_stack_1348_cor2_DW_particles.mrc_7_1.png"
img_path = os.path.join(img_dir, img_name)
img_gray = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)
dispim = img_gray
vscale = 1.5
vmax = max(-dispim.min(), dispim.max())*vscale
vmin = -vmax
cmap='gray'
# 原始图像
imshow(dispim, cmap, colorbar=False, vmin=vmin, vmax=vmax)
原始图像:
增加Conda环境,核心包:pyfftw
python -m ipykernel install --user --name cryosparc-master --display-name "cryosparc-master"
查看Conda环境,参考:Anaconda 查看、创建、管理和使用python环境
conda info --env
# conda environments:
#
base * /home/chenlong/miniconda3
torch-def /home/chenlong/miniconda3/envs/torch-def
/nfs_baoding/chenlong/workspace/cryosparc/cryosparc_master/deps/anaconda
/nfs_baoding/chenlong/workspace/cryosparc/cryosparc_worker/deps/anaconda
Conda重命名,参考:How can I rename a conda environment?
tmux attach -t download
conda create -n cryosparc-master --clone /nfs_baoding/chenlong/workspace/cryosparc/cryosparc_master/deps/anaconda
Source: /nfs_baoding/chenlong/workspace/cryosparc/cryosparc_master/deps/anaconda
Destination: /home/chenlong/miniconda3/envs/cryosparc-master
The following packages cannot be cloned out of the root environment:
- https://repo.anaconda.com/pkgs/main/linux-64::conda-4.8.3-py37_0
Packages: 34
Files: 1
测试脚本:
cryosparc/cryosparc_master/cryosparc_compute/20220802-lowpass_filter.ipynb
cryosparc/cryosparc_master/cryosparc_compute/20220802-lowpass_filter.py
matplotlib存储image,通过savefig,设置bbox_inches
和pad_inches
,去除白边,但是,转换为numpy,无法去除左右的白边。
plt.savefig('match.png', bbox_inches='tight', transparent="True", pad_inches=0)
通过以下方案转换numpy,去除白边:
- 设置fig尺寸为输入图像尺寸:
fig.set_size_inches(plt.figaspect(dispim))
- 全部填充,没有pad:
fig.tight_layout(pad=0, h_pad=None, w_pad=None)
fig = plt.gcf()
fig.set_size_inches(plt.figaspect(dispim)) # 设置fig尺寸为输入图像尺寸,例如dispim
fig.tight_layout(pad=0, h_pad=None, w_pad=None) # 全部填充,没有pad
fig.canvas.draw()
img_plt = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
img_plt = img_plt.reshape(fig.canvas.get_width_height()[::-1] + (3,))
存储matplotlib的图像,参考:
- Removing the white border around an image when using matplotlib without saving the image,去除numpy格式的白边
- How do I change the size of figures drawn with Matplotlib?,设置figure的尺寸
- Matplotlib figure to image as a numpy array,figure转换为numpy
冷冻电镜图像的低通滤波,逻辑如下:
class LowpassFilter(object):
"""
冷冻电镜图像的低通滤波
"""
def __init__(self):
self.radwn = 6 # 低通滤波mask参数
self.lowpassorder = 1 # 低通滤波等级,mask参数
@staticmethod
def imshow(rD, cmap='turbo', colorbar=True, vmin=None, vmax=None):
"""
展示图像
"""
plt.imshow(rD, cmap=plt.get_cmap(cmap), vmin=vmin, vmax=vmax)
if colorbar:
plt.colorbar()
# plt.colorbar(orientation='horizontal', shrink=0.6, fraction=0.05, pad=0.05);
else:
fig = plt.gcf()
plt.axis('off')
for ax in fig.axes:
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
def lowpass_filter_for_cryoem(self, img_gray):
"""
冷冻电镜图像的低通滤波算法
"""
rD = img_gray
N = rD.shape[0]
# 计算低通滤波的mask
lowpass_mask = sigproc.lowpass_mask(N, 2, self.radwn, lowpassorder=self.lowpassorder)
D = fourier.fft(rD) # 傅里叶变换
Cval = -1.0
dispim = fourier.ifft(lowpass_mask * D * Cval) # 傅里叶变换
vscale = 1.5
vmax = max(-dispim.min(), dispim.max()) * vscale
vmin = -vmax
cmap = 'gray'
# 原始图像
LowpassFilter.imshow(dispim, cmap, colorbar=False, vmin=vmin, vmax=vmax)
# 获取matplotlib显示的image,转换为numpy格式
fig = plt.gcf()
fig.set_size_inches(plt.figaspect(dispim))
fig.tight_layout(pad=0, h_pad=None, w_pad=None)
fig.canvas.draw()
img_plt = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
img_plt = img_plt.reshape(fig.canvas.get_width_height()[::-1] + (3,))
img_lowpass = cv2.cvtColor(img_plt, cv2.COLOR_RGB2GRAY)
img_lowpass = cv2.resize(img_lowpass, img_gray.shape)
return img_lowpass
低通滤波图像:
v1.0的lowpass filter算法,如下:
class LowpassFilter(object):
"""
低通滤波类
"""
def __init__(self):
pass
@staticmethod
def gen_mask(image_size, radius=20):
x, y = np.ogrid[0:image_size, 0:image_size]
center_x = (image_size - 1) / 2
center_y = (image_size - 1) / 2
mask = (x - center_x) ** 2 + (y - center_y) ** 2 <= radius ** 2
return np.array(mask, dtype=np.int32)
@staticmethod
def lowpass(img):
"""
低通滤波
"""
image_size = img.shape[0]
img_dft = np.fft.fft2(img)
dft_shift = np.fft.fftshift(img_dft)
dft_mask = LowpassFilter.gen_mask(image_size, radius=20)
dft_filter = dft_mask * dft_shift
idft_shift = np.fft.ifftshift(dft_filter)
img_back = np.abs(np.fft.ifft2(idft_shift))
img_back = img_back.astype(np.uint8)
return img_back
效果对比:
像素分布:
以上是关于基于冷冻电镜图像的低通滤波(Lowpass Filter)算法的主要内容,如果未能解决你的问题,请参考以下文章