mmdetection的生物图像实例分割三:自定义数据集的测试与分析

news2024/11/26 3:46:16

mmdetection的生物图像实例分割全流程记录

第三章 自定义数据集的测试、重建与分析


文章目录

  • mmdetection的生物图像实例分割全流程记录
  • 前言
  • 一、测试集的推理
    • 1.模型测试
    • 2.测试数据解析
  • 二、测试结果的数据整合
  • 三、生物结构的重建效果


前言

mmdetection是一个比较容易入门且上手的深度学习检测框架,其官网为https://github.com/open-mmlab/mmdetection,相关文档https://mmdetection.readthedocs.io/zh-cn/latest/overview.html。

版本为mmdetection 3.3.0.这里可供借鉴。
在这里插入图片描述

一、测试集的推理

1.模型测试

找到文件位置:tools/test.py,复制为tools/test_ac3ac4.py,并进行如下更改:

# Copyright (c) OpenMMLab. All rights reserved.
import argparse
import os
import os.path as osp
import warnings
from copy import deepcopy

from mmengine import ConfigDict
from mmengine.config import Config, DictAction
from mmengine.runner import Runner

from mmdet.engine.hooks.utils import trigger_visualization_hook
from mmdet.evaluation import DumpDetResults
from mmdet.registry import RUNNERS
from mmdet.utils import setup_cache_size_limit_of_dynamo


# TODO: support fuse_conv_bn and format_only
def parse_args():
    parser = argparse.ArgumentParser(
        description='MMDet test (and eval) a model')
    # parser.add_argument('config', help='test config file path')
    # parser.add_argument('checkpoint', help='checkpoint file')
    parser.add_argument('--config', default='Path/to/your/mmdetection/mmdet/configs/mask_rcnn/mask_rcnn_r50_fpn_2x_ac3ac4.py', 
                        help='test config file path')
    parser.add_argument('--checkpoint', default='Path/to/your/DataLog/AC3AC4/MRCNN/epoch_best.pth', 
                        help='checkpoint file')
    parser.add_argument(
        '--work-dir', default='Path/to/your/DataLog/AC3AC4/MRCNNOUT/',
        help='the directory to save the file containing evaluation metrics')
    parser.add_argument(
        '--out',
        type=str, default='Path/to/your/DataLog/AC3AC4/MRCNNOUT/predictions.pkl',
        help='dump predictions to a pickle file for offline evaluation')
    # parser.add_argument(
    #     '--show', action='store_true', help='show prediction results')
    parser.add_argument(
        '--show', default=True, help='show prediction results')
    parser.add_argument(
        '--show-dir',
        default='Path/to/your/DataLog/AC3AC4/MRCNNOUT/show_dir/', 
        help='directory where painted images will be saved. '
        'If specified, it will be automatically saved '
        'to the work_dir/timestamp/show_dir')
    parser.add_argument(
        '--wait-time', type=float, default=2, help='the interval of show (s)')
    parser.add_argument(
        '--cfg-options',
        nargs='+',
        action=DictAction,
        help='override some settings in the used config, the key-value pair '
        'in xxx=yyy format will be merged into config file. If the value to '
        'be overwritten is a list, it should be like key="[a,b]" or key=a,b '
        'It also allows nested list/tuple values, e.g. key="[(a,b),(c,d)]" '
        'Note that the quotation marks are necessary and that no white space '
        'is allowed.')
    parser.add_argument(
        '--launcher',
        choices=['none', 'pytorch', 'slurm', 'mpi'],
        default='none',
        help='job launcher')
    parser.add_argument('--tta', action='store_true')
    # When using PyTorch version >= 2.0.0, the `torch.distributed.launch`
    # will pass the `--local-rank` parameter to `tools/train.py` instead
    # of `--local_rank`.
    parser.add_argument('--local_rank', '--local-rank', type=int, default=0)
    args = parser.parse_args()
    if 'LOCAL_RANK' not in os.environ:
        os.environ['LOCAL_RANK'] = str(args.local_rank)
    return args


def main():
    args = parse_args()

    # Reduce the number of repeated compilations and improve
    # testing speed.
    setup_cache_size_limit_of_dynamo()

    # load config
    cfg = Config.fromfile(args.config)
    cfg.launcher = args.launcher
    if args.cfg_options is not None:
        cfg.merge_from_dict(args.cfg_options)

    # work_dir is determined in this priority: CLI > segment in file > filename
    if args.work_dir is not None:
        # update configs according to CLI args if args.work_dir is not None
        cfg.work_dir = args.work_dir
    elif cfg.get('work_dir', None) is None:
        # use config filename as default work_dir if cfg.work_dir is None
        cfg.work_dir = osp.join('./work_dirs',
                                osp.splitext(osp.basename(args.config))[0])

    cfg.load_from = args.checkpoint

    if args.show or args.show_dir:
        cfg = trigger_visualization_hook(cfg, args)

    if args.tta:

        if 'tta_model' not in cfg:
            warnings.warn('Cannot find ``tta_model`` in config, '
                          'we will set it as default.')
            cfg.tta_model = dict(
                type='DetTTAModel',
                tta_cfg=dict(
                    nms=dict(type='nms', iou_threshold=0.5), max_per_img=100))
        if 'tta_pipeline' not in cfg:
            warnings.warn('Cannot find ``tta_pipeline`` in config, '
                          'we will set it as default.')
            test_data_cfg = cfg.test_dataloader.dataset
            while 'dataset' in test_data_cfg:
                test_data_cfg = test_data_cfg['dataset']
            cfg.tta_pipeline = deepcopy(test_data_cfg.pipeline)
            flip_tta = dict(
                type='TestTimeAug',
                transforms=[
                    [
                        dict(type='RandomFlip', prob=1.),
                        dict(type='RandomFlip', prob=0.)
                    ],
                    [
                        dict(
                            type='PackDetInputs',
                            meta_keys=('img_id', 'img_path', 'ori_shape',
                                       'img_shape', 'scale_factor', 'flip',
                                       'flip_direction'))
                    ],
                ])
            cfg.tta_pipeline[-1] = flip_tta
        cfg.model = ConfigDict(**cfg.tta_model, module=cfg.model)
        cfg.test_dataloader.dataset.pipeline = cfg.tta_pipeline

    # build the runner from config
    if 'runner_type' not in cfg:
        # build the default runner
        runner = Runner.from_cfg(cfg)
    else:
        # build customized runner from the registry
        # if 'runner_type' is set in the cfg
        runner = RUNNERS.build(cfg)

    # add `DumpResults` dummy metric
    if args.out is not None:
        assert args.out.endswith(('.pkl', '.pickle')), \
            'The dump file must be a pkl file.'
        runner.test_evaluator.metrics.append(
            DumpDetResults(out_file_path=args.out))

    # start testing
    runner.test()


if __name__ == '__main__':
    main()

若使用指定GPU,可以在命令行执行:

CUDA_VISIBLE_DEVICES=0 Path/to/your/envs/mmlab3/bin/python Path/to/your/mmdetection/tools/train_cremi.py

在这里插入图片描述

可以看到,在DataLog/AC3AC4/MRCNNOUT/show_dir/路径下已经出现测试的结果,左边是真值,右边是测试结果:
在这里插入图片描述

2.测试数据解析

对于已经推理出来的数据,我们可能不仅仅是作为可视化,还想将其还原为体积数据,进行后续的处理分析。打开我们存放的pkl文件,可以看到:

在这里插入图片描述
其中保存的data为list格式,长度是我们所的测试的图像数量,对于从标注到真实的mask还原的函数,官方给的数据在mmdet/visualization/local_visualizer.py这里。我们根据我们数据的命名方式,将pkl数据重新还原为体积数据:

其实在mmdet/evaluation/metrics/coco_metric.py路径下,我们可以看到官网中已经给出了Mask信息,并将其编码为RLE格式:

            # encode mask to RLE
            if 'masks' in pred:
                result['masks'] = encode_mask_results(
                    pred['masks'].detach().cpu().numpy()) if isinstance(
                        pred['masks'], torch.Tensor) else pred['masks']

我们同样调用pycocotools.mask进行解码,代码如下:


import os
from os.path import join
import pickle
from tqdm import tqdm
from skimage import io
import numpy as np
import pycocotools.mask as mask_util

def pkl2stack(pkl_path, save_path, 
              y_range = [[0, 1024]],
              x_range = [[0, 1024]],
              score_thre = 0.6):
    os.makedirs(save_path, exist_ok=True)
    with open(pkl_path, 'rb') as file:
        data = pickle.load(file)
        for single_item in tqdm(data):
            img_path = single_item['img_path']
            img_name = img_path.split('/')[-1].split('.')[0]
            stack_name, z_name, y_name, x_name = img_name.split('_')
            save_img_name = z_name + '.tif'
            save_sub_path = join(save_path, stack_name)
            os.makedirs(save_sub_path, exist_ok=True)
            if os.path.isfile(join(save_sub_path, save_img_name)):
                save_array = io.imread(join(save_sub_path, save_img_name))
            else:
                save_array = np.zeros(shape=(y_range[-1][-1], x_range[-1][-1]), dtype=np.uint8)
            pred_scores = single_item['pred_instances']['scores'].numpy()
            pred_masks = mask_util.decode(single_item['pred_instances']['masks'])
            for scores_index in range(pred_scores.shape[0]):
                item_score = pred_scores[scores_index]
                if item_score > score_thre:
                    save_array[y_range[int(y_name)][0]:y_range[int(y_name)][1], 
                               x_range[int(x_name)][0]:x_range[int(x_name)][1]] += pred_masks[:, :, scores_index]
            save_array[save_array>0] = 1
            io.imsave(join(save_sub_path, save_img_name), save_array)

if __name__ == '__main__':
    pkl2stack(pkl_path="Path/to/your/DataLog/AC3AC4/MRCNNOUT/predictions.pkl", 
              save_path='Path/to/your/DataPred/MRCNN/AC3AC4/')
    

可以看到相关的路径下已经为每一个体积数据创建了一个文件夹,并将每一个2D结果进行了保存。

在这里插入图片描述
这里可以发现它和真值的结果差异是十分大的。这是由于我们目前的demo仅仅训练了20个epoch,模型可能并未收敛,这里只展示基本流程。同时我们并没有对其中的3D信息,实例信息进行关联。下一节将会简要介绍简单的细胞器重建方法。

二、测试结果的数据整合

2D实例分割模型仅仅是得到了2D层面的结果,但是我们还需要将其整合为3D体积数据,最简单的方式是直接通过连通域进行实例化。然而这样的方法往往会出现大量的假阴和假阳结果。实例化的方法在众多的电镜数据集中都有涉及,包括突触、线粒体等。这里使用最简单的形态学后处理方法进行实现。

未完待续…

三、生物结构的重建效果

未完待续…

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1795599.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL Doublewrite Buffer 有了解过吗?

引言:在数据库管理中,确保数据的完整性和一致性是至关重要的。然而,在持久化数据到磁盘的过程中,可能会遇到各种意外情况,如断电或系统崩溃,从而导致部分数据写入,而另一部分数据未能成功写入&a…

eclipse怎么导入python项目

python项目导入eclipse的步骤: 1、首先,打开Eclipse集成开发程序,在菜单栏上点击“File(F)”,在弹出来的列表中点击“导入(I)...”。 2、在弹出来的“导入”窗口中,选择“常规”选项中的“现有…

QT学习过程中遇到的问题自记

文章目录 前言问题1问题2问题3 前言 学习QT嵌入式实战开发(从串口通信到JSON通信微课视频版)的过程中遇到的几个小问题 问题1 1.将书中的示例代码导入自己的电脑,然后点击工程进去,不能运行,报错 no kits are enabled for this project… 我…

[数据集][目标检测]数据集VOC格式岸边垂钓钓鱼fishing目标检测数据集-4330张

数据集格式:Pascal VOC格式(不包含分割路径的txt文件和yolo格式的txt文件,仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数):4330 标注数量(xml文件个数):4330 标注类别数:1 标注类别名称:["fishing"] 每…

小程序自定义marker弹出框教程

需求背景 微信小程序开发,需要使用腾讯地图显示自定义marker,并且点击marker后弹出自定义的customCallout,并且customCallout的内容为用户点击marker的时候再从后台接口获取数据。 百度了一圈后发现居然没有一篇文章可以一次性完成&#xf…

pESC-HIS是什么,怎么看?-实验操作系列-2

01 典型的pESC-HIS质粒遗传图谱 02 介绍 质粒类型:酿酒酵母蛋白表达载体 表达水平:高拷贝 诱导方法:半乳糖 启动子:GAL1和GAL10 克隆方法:多克隆位点,限制性内切酶 载体大小:6706bp 5 测…

uniapp封装picker选择器组件,支持关键字查询

CommonPicker.vue组件 路径在 components\CommonPicker.vue <template><view><uni-easyinput v-model"searchQuery" :placeholder"placeholder" /><picker :range"filteredOptions" :range-key"text" v-model&…

韩顺平0基础学java——第18天

p374-395 类变量和类方法 类变量&#xff08;静态变量&#xff09; 例&#xff1a; class Child{ public static Int count&#xff1b;//这个count可以被所有Child实例共享 /..../ } 内存中&#xff0c;static在堆中是独立存放的&#xff0c;并不在某个对象的空间中。 由于…

行业分析---造车新势力之理想汽车

1 前言 在之前的博客中&#xff0c;笔者撰写了多篇行业类分析的文章&#xff08;科技新能源&#xff09;&#xff1a; 《行业分析---我眼中的Apple Inc.》 《行业分析---马斯克的Tesla》 《行业分析---造车新势力之蔚来汽车》 《行业分析---造车新势力之小鹏汽车》 此类文章的受…

前端传参数后端变量类型能够接受到List却无法接收到值

问题描述 今天写了个接口&#xff0c;下图所示 ReqVO里是这样的&#xff1a; 然后前端去请求&#xff0c;从请求结果中看发现这里值是在的&#xff08;有经验的可能就看出来了otherInfo.id: 这样以参数后端是接收不到的&#xff0c;但是当时没发现&#xff09; 传进来后端…

zynq-7015启动分析及裸机BootLoader编写(未完待续)

使用lwip-tcp远程对QSPI进行更新、QSPI FLASH启动 W25Q128资料&#xff1a; W25Q128JV datasheet(1/78 Pages) WINBOND | 3V 128M-bit serial flash memory with dual/quad spi (alldatasheet.com) UG585资料&#xff1a; Zynq 7000 SoC Technical Reference Manual-UG585 翻译…

python3 -m http.server 检查打包前端的项目

python3 -m http.server这是 Python 提供的一个内置的简单 HTTP 服务器。当你在终端中运行 python3 -m http.server 命令时(在对应的打包目录比如dist目录)&#xff0c;Python 会启动一个 HTTP 服务器&#xff0c;它会将当前工作目录下的文件作为静态文件提供给浏览器。这个服务…

张大哥笔记:高考,万人过独木桥,你怕不怕摔倒?

今天刷到一个新闻&#xff1a;宁夏煤业计划招600名挖煤的井下操作工&#xff0c;要求大学学历&#xff01;结果却吸引了7900人来报名&#xff01;我都惊呆了&#xff0c;什么时候挖煤都要求这么高的学历了&#xff0c;那读书到底起啥作用&#xff01; 如果一个人读书读到大学后…

web刷题记录(4)

[GKCTF 2020]cve版签到 进来应该是给了个提示了&#xff0c;就是要以.ctfhub.com结尾 还有一个超链接&#xff0c;这题的ssrf还是挺明显的&#xff0c;抓包看看 发现回显里面有提示 说是和本地有关&#xff0c;那么也就是说&#xff0c;要访问127.0.0.1&#xff0c;大概意思就…

基于FPGA的任意点滑动平均(滑动窗长度和数据位宽参数化,例化时参数可设置)

目录 1.前言2.原理3.举例说明4.Matlab实现5.FPGA实现滑动平均 微信公众号获取更多FPGA相关源码&#xff1a; 1.前言 对于一维信号&#xff0c;我们可以使用类似移动平均滤波&#xff08;Moving Average Filtering&#xff09;实现denoising。Moving Average Filtering 是一种…

超速解读多模态InternVL-Chat1.5 ,如何做到开源SOTA——非官方首发核心技巧版(待修订)

解读InternVL-chat1.5系列 最近并行是事情太杂乱了&#xff0c;静下心来看一看优秀的开源项目,但是AI技术迭代这么快&#xff0c;现在基本是同时看五、六个方向的技术架构和代码&#xff0c;哪个我都不想放&#xff0c;都想知道原理和代码细节&#xff0c;还要自己训练起来&am…

性能飙升50%,react-virtualized-list如何优化大数据集滚动渲染

在处理大规模数据集渲染时&#xff0c;前端性能常常面临巨大的挑战。本文将探讨 react-virtualized-list 库如何通过虚拟化技术和 Intersection Observer API&#xff0c;实现前端渲染性能飙升 50% 的突破&#xff01;除此之外&#xff0c;我们一同探究下该库还支持哪些新的特性…

【嵌入式DIY实例】-OLED显示天气数据

OLED显示天气数据 文章目录 OLED显示天气数据1、硬件准备与接线2、天气数据获取准备3、代码实现在这个物联网项目中,本文将展示如何使用 ESP8266 NodeMCU (ESP-12E) Wi-Fi 开发板和 SSD1306 OLED 显示屏(12864 像素)制作一个简单的互联网气象站。 NodeMCU 从天气网站 openwe…

JavaWeb3 Ajax+Axios+Element+Nginx部署

Ajax 异步JS和XML 1.数据交换&#xff1a;给服务器发送请求&#xff0c;并获取服务器相应的数据 2.异步交互&#xff1a;在不重新加载整个页面的情况下&#xff0c;与服务器交换数据并更新部分网页 同步与异步 原生Ajax <!DOCTYPE html> <html> <body><…

kafka-消费者-消费异常处理(SpringBoot整合Kafka)

文章目录 1、消费异常处理1.1、application.yml配置1.2、注册异常处理器1.3、消费者使用异常处理器1.4、创建生产者发送消息1.5、创建SpringBoot启动类1.6、屏蔽 kafka debug 日志 logback.xml1.7、引入spring-kafka依赖1.8、消费者控制台&#xff1a;1.8.1、第一次启动SpringK…