基于冷冻电镜图像的低通滤波(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_inchespad_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的图像,参考:

冷冻电镜图像的低通滤波,逻辑如下:

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)算法的主要内容,如果未能解决你的问题,请参考以下文章

CryoEM粒子(Particle)类型预测的数据集构建

CryoEM粒子(Particle)类型预测的数据集构建

MATLAB 中的低通/带通滤波器设计

冷冻电镜聚类中心(2D Class)粒子图像的解析

冷冻电镜聚类中心(2D Class)粒子图像的解析

冷冻电镜聚类中心(2D Class)粒子图像的解析