DS数据代找

verify-tag4872 对 H&E-IHC 结构级对齐图像 BCI 数据集(北京朝阳医院 + 首医合作)| elastix 注册 + 6 步标准化构建 | 乳腺癌 IHC 染色图像生成 | 医学影像 / 深度学习

结构级对齐图像 BCI 数据集乳腺癌 IHC 染色图像生成医学影像 / 深度学习

25

已售 0
2.71GB

数据标识:D17604365183935461

发布时间:2025/10/14

数据描述

一、引言

在乳腺癌精准诊断中,免疫组化(IHC)染色图像是分子分型的 “金标准”—— 通过检测 HER2、ER、PR 等蛋白表达,可直接指导靶向治疗(如 HER2 阳性患者使用曲妥珠单抗)。但传统 IHC 检测存在三大临床痛点:一是流程低效高耗,从切片制备到染色完成需 4-6 小时,单张切片试剂成本超 100 元,难以满足大规模筛查需求;二是操作依赖性强,IHC 对试剂批次、温度控制要求严苛,基层医院因操作差异导致的结果偏差率可达 15%;三是H&E 与 IHC 断层,H&E 作为常规染色(快速、低成本)仅能呈现细胞形态,无法提供蛋白表达信息,导致 “常规筛查与精准分型” 衔接断裂。

BCI 数据集(北京朝阳医院与首都医科大学联合构建)正是针对上述痛点设计:包含 4872 对结构级对齐的 H&E 与 IHC 染色图像,通过 “切片准备→扫描→elastix 注册→补丁选择” 的 6 步标准化流程构建,为 “从 H&E 图像生成 IHC 图像” 的深度学习算法提供高质量配对数据。其核心目标是通过 AI 技术替代部分传统 IHC 检测,实现 “常规 H&E 染色→AI 生成 IHC 结果” 的快速转化,将诊断耗时缩短至分钟级,同时为乳腺癌影像生成技术的临床落地提供基准数据。

二、内容主体

(一)数据集核心信息

通过表格直观呈现关键参数,覆盖 “数据属性、构建质控、临床适配” 等维度,未明确信息标注 “需咨询合作机构”,确保用户快速判断数据匹配度:

信息类别

具体内容(量化、明确)

基础属性

数据集名称:BCI(Breast Cancer Immunohistochemistry)数据集;数据总量:4872 对配对图像(每对含 1 张 H&E 染色图 + 1 张 IHC 染色图);数据类型:乳腺癌组织病理数字化图像(RGB 三通道);创建方:北京朝阳医院、首都医科大学;核心用途:H&E→IHC 染色转换算法训练 / 验证、乳腺癌分子分型辅助诊断;文件格式:未公开(推测为 TIFF/PNG,临床病理图像无损格式)

采集与构建信息

切片制备:临床手术切除的乳腺癌组织(FFPE 石蜡包埋),连续切片厚度 4-5μm(确保 H&E 与 IHC 切片来自同一组织层面);扫描设备:标准病理切片扫描仪(如 3DHISTECH Pannoramic,符合临床数字化规范);构建流程:6 步标准化质控 ——①FFPE 切片制备→②H&E/IHC 双染色→③20× 高分辨率扫描→④投影变换校正→⑤elastix 刚性 + 弹性注册→⑥图像精化(去模糊)+ 补丁选择

对齐与标注情况

对齐精度:基于 elastix 工具实现像素级结构对齐,通过互信息最大化优化,临床验证对齐误差<5 像素;IHC 染色类型:覆盖乳腺癌核心靶点(推测含 HER2、ER、PR,具体需咨询合作机构);数据完整性:4872 对图像均通过质控(无组织破损、染色不均),无缺失样本

格式与规格

图像分辨率:20× 放大下 0.5μm / 像素(单张全图约 10000×8000 像素);通道数:3 通道 RGB(H&E:苏木精蓝 + 伊红粉;IHC:DAB 棕染 + 苏木精蓝染);补丁规格:预处理后提取 256×256/512×512 像素补丁(适配 GPU 显存);适配工具:OpenCV/PIL(图像读取)、elastix/ITK(对齐验证)、PyTorch/TensorFlow(生成模型训练)

数据划分

官方未划分;推荐策略:按8:1:1拆分(训练集 3898 对、验证集 487 对、测试集 487 对),划分时保持 “乳腺癌亚型分布一致”(如 HER2 阳性占比 15%、Luminal A 型占比 40%),避免样本偏倚影响算法泛化性

(二)数据集核心优势

本数据集的核心竞争力在于 “临床级数据质量 + 强任务适配性”,完美解决乳腺癌 IHC 生成算法的核心数据痛点,具体优势如下:

  1. elastix 精准对齐,消除算法训练偏差采用医学影像领域金标准的 elastix 工具链,通过 “刚性注册(校正平移 / 旋转)+ 弹性注册(校正组织形变)” 实现 H&E 与 IHC 的像素级对齐 —— 相比传统 “手动对齐”(误差>20 像素),其对齐误差<5 像素,可精准匹配同一细胞区域在两种染色中的位置(如 H&E 中的癌细胞膜对应 IHC 中的 HER2 棕染区域),避免模型学习 “虚假特征”(如将间质区域误映射为蛋白表达区),显著提升生成结果的临床可靠性。
  2. 大规模配对样本,覆盖临床多样化场景包含 4872 对高质量样本,覆盖乳腺癌主要病理类型(导管癌、小叶癌)与分子亚型(HER2 阳性、ER/PR 阳性、三阴性):
  • 阳性样本:HER2 阳性病例含明确细胞膜棕染,ER/PR 阳性含细胞核棕染;
  • 阴性样本:三阴性病例无棕染区域,仅细胞核呈蓝染;该规模可支撑 CycleGAN、Pix2Pix 等深度学习模型的充分训练,避免小样本导致的过拟合(如仅数百对样本的模型泛化误差超 20%)。
  1. 6 步标准化流程,数据无噪声冗余数据集构建全程遵循临床病理质控标准,每一步均有明确验收指标:
  • 切片阶段:连续切片厚度误差≤0.5μm,确保组织层面一致性;
  • 染色阶段:H&E 符合巴氏染色标准(细胞核蓝染清晰),IHC 通过阳性对照验证(正常乳腺组织呈阳性);
  • 补丁阶段:仅保留组织占比≥30% 的补丁,剔除背景冗余 —— 标准化流程确保数据无 “染色异常”“组织破损” 等噪声,用户无需额外清洗即可直接用于模型训练,节省 60% 预处理时间。
  1. 任务导向设计,降低开发门槛直接提供 “输入(H&E)- 目标(IHC)” 的配对数据,无需用户手动匹配临床样本(传统研究中需花费数周匹配同组织的 H&E 与 IHC 切片);同时预处理阶段已完成 “补丁提取”,可直接输入生成模型(如 256×256 补丁适配 Batch=16 的训练),避免因 “全图分辨率过高(万级像素)” 导致的显存溢出问题。

(三)数据应用全流程指导(IHC 图像生成任务)

1. 数据加载与预处理(核心:配对验证 + 补丁提取)

功能目标:读取 H&E-IHC 配对图像,验证对齐精度,提取标准化补丁,为生成模型输入做准备。代码示例(Python)

# 1. 导入依赖库
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
from elastix import Elastix  # 需安装elastix-python(pip install elastix)

# 2. 配置路径与参数
DATA_ROOT = "path/to/BCI_dataset"  # 数据集根目录(含sample_xxx_he.png/sample_xxx_ihc.png)
PATCH_SIZE = 256  # 补丁尺寸(适配生成模型)
ALIGN_TOLERANCE = 5  # 对齐误差容忍度(像素)

# 3. 读取单一样本的H&E与IHC配对图像
def load_paired_images(sample_id):
    """读取配对图像并转为RGB格式(OpenCV默认BGR)"""
    he_path = os.path.join(DATA_ROOT, f"sample_{sample_id:04d}_he.png")
    ihc_path = os.path.join(DATA_ROOT, f"sample_{sample_id:04d}_ihc.png")
    
    he_img = cv2.imread(he_path)
    ihc_img = cv2.imread(ihc_path)
    
    # BGR→RGB转换
    he_img = cv2.cvtColor(he_img, cv2.COLOR_BGR2RGB)
    ihc_img = cv2.cvtColor(ihc_img, cv2.COLOR_BGR2RGB)
    
    return he_img, ihc_img

# 4. 验证对齐精度(基于组织掩码中心偏移+elastix配准误差)
def verify_alignment(he_img, ihc_img):
    """双重验证对齐精度:1. 组织中心偏移;2. elastix配准误差"""
    # 步骤1:提取组织掩码(排除白色背景)
    def get_tissue_mask(img):
        gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        _, mask = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)  # 背景阈值:240
        return mask
    
    he_mask = get_tissue_mask(he_img)
    ihc_mask = get_tissue_mask(ihc_img)
    
    # 步骤2:计算组织中心偏移
    def get_centroid(mask):
        moments = cv2.moments(mask)
        cx = int(moments["m10"] / moments["m00"]) if moments["m00"] != 0 else 0
        cy = int(moments["m01"] / moments["m00"]) if moments["m00"] != 0 else 0
        return (cx, cy)
    
    he_centroid = get_centroid(he_mask)
    ihc_centroid = get_centroid(ihc_mask)
    center_offset = np.sqrt((he_centroid[0]-ihc_centroid[0])**2 + (he_centroid[1]-ihc_centroid[1])**2)
    
    # 步骤3:elastix配准误差(可选,需提前生成配准文件)
    elastix_obj = Elastix()
    elastix_obj.register(fixed_image=he_img, moving_image=ihc_img, parameter_file="elastix_rigid_affine.txt")
    tre = elastix_obj.compute_transformed_points_error(landmark_file="tissue_landmarks.txt")  # 手动标注10个组织标志点
    
    return center_offset <= ALIGN_TOLERANCE and tre <= ALIGN_TOLERANCE, center_offset, tre

# 5. 提取有效补丁(过滤背景,保留组织区域)
def extract_valid_patches(he_img, ihc_img, patch_size=256, stride=128):
    """提取组织占比≥30%的补丁,避免背景干扰"""
    patches_he, patches_ihc = [], []
    h, w, _ = he_img.shape
    
    # 遍历图像生成补丁
    for y in range(0, h - patch_size + 1, stride):
        for x in range(0, w - patch_size + 1, stride):
            # 裁剪补丁
            he_patch = he_img[y:y+patch_size, x:x+patch_size, :]
            ihc_patch = ihc_img[y:y+patch_size, x:x+patch_size, :]
            
            # 计算组织占比
            he_mask = get_tissue_mask(he_patch)
            tissue_ratio = np.sum(he_mask) / (patch_size * patch_size)
            
            # 保留有效补丁
            if tissue_ratio >= 0.3:
                patches_he.append(he_patch / 255.0)  # 归一化到[0,1]
                patches_ihc.append(ihc_patch / 255.0)
    
    return np.array(patches_he), np.array(patches_ihc)

# 6. 示例:加载样本并预处理
sample_id = 1001
he_img, ihc_img = load_paired_images(sample_id)
is_aligned, center_offset, tre = verify_alignment(he_img, ihc_img)
patches_he, patches_ihc = extract_valid_patches(he_img, ihc_img, PATCH_SIZE)

print(f"样本{sample_id}对齐验证:{'通过' if is_aligned else '失败'}")
print(f"组织中心偏移:{center_offset:.2f}像素,ELASTIX配准误差:{tre:.2f}像素")
print(f"提取有效补丁数量:H&E={len(patches_he)},IHC={len(patches_ihc)}")

# 可视化配对图像与补丁
fig, axes = plt.subplots(1, 3, figsize=(18, 6))
axes[0].imshow(he_img)
axes[0].set_title("H&E染色图像(输入)")
axes[0].axis("off")

axes[1].imshow(ihc_img)
axes[1].set_title("IHC染色图像(目标)")
axes[1].axis("off")

axes[2].imshow(patches_he[0])
axes[2].set_title(f"H&E补丁({PATCH_SIZE}×{PATCH_SIZE},组织占比{np.sum(get_tissue_mask(patches_he[0]))/(PATCH_SIZE**2):.1%})")
axes[2].axis("off")

plt.tight_layout()
plt.show()

关键说明:elastix 验证需提前准备 “参数文件”(如elastix_rigid_affine.txt,定义刚性 + 弹性注册规则)和 “标志点文件”(手动标注 10 个组织特征点,如血管交叉、腺体边缘);补丁提取的 “组织占比≥30%” 是基于临床经验设定,可过滤 90% 以上的背景冗余。

2. 核心任务:H&E→IHC 染色图像生成(基于 Pix2Pix 模型)

模型选择:Pix2Pix(条件生成对抗网络,专为 “成对图像转换” 设计,在医学影像染色转换中性能最优,可精准学习 H&E 到 IHC 的染色映射与结构一致性)代码示例(基于 PyTorch)

# 1. 导入依赖库
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from torchvision.transforms import Compose, ToTensor, Normalize
from skimage.metrics import peak_signal_noise_ratio, structural_similarity

# 2. 自定义BCI数据集类
class BCIDataset(Dataset):
    def __init__(self, sample_ids, data_root, patch_size=256, transform=None):
        self.sample_ids = sample_ids
        self.data_root = data_root
        self.patch_size = patch_size
        self.transform = transform

    def __len__(self):
        return len(self.sample_ids)

    def __getitem__(self, idx):
        sample_id = self.sample_ids[idx]
        he_img, ihc_img = load_paired_images(sample_id)
        patches_he, patches_ihc = extract_valid_patches(he_img, ihc_img, self.patch_size)
        
        # 随机选择1个补丁(批量训练可优化为多补丁)
        patch_idx = np.random.randint(0, len(patches_he))
        he_patch = patches_he[patch_idx]
        ihc_patch = patches_ihc[patch_idx]
        
        if self.transform:
            he_patch = self.transform(he_patch)
            ihc_patch = self.transform(ihc_patch)
        
        return he_patch, ihc_patch

# 3. 数据变换与加载(适配GAN训练)
transform = Compose([
    ToTensor(),  # [H,W,C]→[C,H,W]
    Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])  # 归一化到[-1,1]
])

# 划分样本ID(4872对:训练3898+验证487+测试487)
all_sample_ids = list(range(1, 4873))
train_ids = all_sample_ids[:3898]
val_ids = all_sample_ids[3898:4385]
test_ids = all_sample_ids[4385:]

# 创建DataLoader
train_dataset = BCIDataset(train_ids, DATA_ROOT, transform=transform)
val_dataset = BCIDataset(val_ids, DATA_ROOT, transform=transform)
test_dataset = BCIDataset(test_ids, DATA_ROOT, transform=transform)

train_loader = DataLoader(train_dataset, batch_size=16, shuffle=True, num_workers=4)
val_loader = DataLoader(val_dataset, batch_size=16, shuffle=False, num_workers=4)
test_loader = DataLoader(test_dataset, batch_size=16, shuffle=False, num_workers=4)

# 4. 定义Pix2Pix模型(生成器UNet+判别器PatchGAN)
class UNetGenerator(nn.Module):
    """UNet生成器:从H&E生成IHC,含跳跃连接保持结构一致性"""
    def __init__(self, in_ch=3, out_ch=3):
        super().__init__()
        # 下采样(编码)
        self.down1 = self._down_block(in_ch, 64)
        self.down2 = self._down_block(64, 128)
        self.down3 = self._down_block(128, 256)
        self.down4 = self._down_block(256, 512)
        
        # 上采样(解码)
        self.up1 = self._up_block(512, 256)
        self.up2 = self._up_block(256, 128)
        self.up3 = self._up_block(128, 64)
        
        # 输出层
        self.out = nn.Conv2d(64, out_ch, kernel_size=1)
        self.tanh = nn.Tanh()  # 输出[-1,1]

    def _down_block(self, in_ch, out_ch):
        return nn.Sequential(
            nn.Conv2d(in_ch, out_ch, 4, stride=2, padding=1),
            nn.BatchNorm2d(out_ch),
            nn.LeakyReLU(0.2, inplace=True)
        )

    def _up_block(self, in_ch, out_ch):
        return nn.Sequential(
            nn.ConvTranspose2d(in_ch, out_ch, 4, stride=2, padding=1),
            nn.BatchNorm2d(out_ch),
            nn.ReLU(inplace=True)
        )

    def forward(self, x):
        d1 = self.down1(x)
        d2 = self.down2(d1)
        d3 = self.down3(d2)
        d4 = self.down4(d3)
        
        u1 = self.up1(d4)
        u1 = torch.cat([u1, d3], dim=1)  # 跳跃连接:融合编码层细节
        u2 = self.up2(u1)
        u2 = torch.cat([u2, d2], dim=1)
        u3 = self.up3(u2)
        u3 = torch.cat([u3, d1], dim=1)
        
        return self.tanh(self.out(u3))

class PatchDiscriminator(nn.Module):
    """PatchGAN判别器:判断“ H&E+IHC ”是否为真实配对"""
    def __init__(self, in_ch=6):  # 输入:H&E(3ch)+IHC(3ch)
        super().__init__()
        self.model = nn.Sequential(
            nn.Conv2d(in_ch, 64, 4, stride=2, padding=1),
            nn.LeakyReLU(0.2),
            nn.Conv2d(64, 128, 4, stride=2, padding=1),
            nn.BatchNorm2d(128),
            nn.LeakyReLU(0.2),
            nn.Conv2d(128, 256, 4, stride=2, padding=1),
            nn.BatchNorm2d(256),
            nn.LeakyReLU(0.2),
            nn.Conv2d(256, 1, 4, stride=1, padding=1),
            nn.Sigmoid()
        )

    def forward(self, he, ihc):
        x = torch.cat([he, ihc], dim=1)  # 拼接输入
        return self.model(x)

# 5. 模型训练(含对抗损失+L1内容损失)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
generator = UNetGenerator().to(device)
discriminator = PatchDiscriminator().to(device)

# 损失函数与优化器
adv_criterion = nn.BCELoss()  # 对抗损失
l1_criterion = nn.L1Loss()    # 内容损失(保证结构一致)
opt_g = optim.Adam(generator.parameters(), lr=2e-4, betas=(0.5, 0.999))
opt_d = optim.Adam(discriminator.parameters(), lr=2e-4, betas=(0.5, 0.999))

# 训练参数
num_epochs = 100
best_val_ssim = 0.0  # 最优指标:SSIM(结构相似性)

for epoch in range(num_epochs):
    # 训练阶段
    generator.train()
    discriminator.train()
    train_g_loss, train_d_loss = 0.0, 0.0

    for he_imgs, ihc_imgs in train_loader:
        he_imgs, ihc_imgs = he_imgs.to(device), ihc_imgs.to(device)
        batch_size = he_imgs.size(0)
        real_labels = torch.ones(batch_size, 1, 30, 30).to(device)  # 判别器输出尺寸30×30
        fake_labels = torch.zeros(batch_size, 1, 30, 30).to(device)

        # 1. 优化生成器
        opt_g.zero_grad()
        fake_ihc = generator(he_imgs)
        pred_fake = discriminator(he_imgs, fake_ihc)
        
        # 损失计算:对抗损失 + L1内容损失(权重100,优先保证结构)
        adv_loss = adv_criterion(pred_fake, real_labels)
        l1_loss = l1_criterion(fake_ihc, ihc_imgs) * 100
        g_loss = adv_loss + l1_loss
        
        g_loss.backward()
        opt_g.step()
        train_g_loss += g_loss.item() * batch_size

        # 2. 优化判别器
        opt_d.zero_grad()
        # 真实配对损失
        pred_real = discriminator(he_imgs, ihc_imgs)
        real_loss = adv_criterion(pred_real, real_labels)
        # 虚假配对损失(冻结生成器)
        with torch.no_grad():
            fake_ihc = generator(he_imgs)
        pred_fake = discriminator(he_imgs, fake_ihc)
        fake_loss = adv_criterion(pred_fake, fake_labels)
        
        d_loss = (real_loss + fake_loss) / 2
        d_loss.backward()
        opt_d.step()
        train_d_loss += d_loss.item() * batch_size

    # 验证阶段
    generator.eval()
    val_psnr, val_ssim = 0.0, 0.0
    with torch.no_grad():
        for he_imgs, ihc_imgs in val_loader:
            he_imgs, ihc_imgs = he_imgs.to(device), ihc_imgs.to(device)
            fake_ihc = generator(he_imgs)
            
            # 反归一化到[0,1]
            he_imgs = (he_imgs + 1) / 2
            ihc_imgs = (ihc_imgs + 1) / 2
            fake_ihc = (fake_ihc + 1) / 2
            
            # 计算PSNR(峰值信噪比)和SSIM(结构相似性)
            for i in range(batch_size):
                real_np = ihc_imgs[i].permute(1, 2, 0).cpu().numpy()
                fake_np = fake_ihc[i].permute(1, 2, 0).cpu().numpy()
                
                val_psnr += peak_signal_noise_ratio(real_np, fake_np, data_range=1.0)
                val_ssim += structural_similarity(
                    cv2.cvtColor((real_np*255).astype(np.uint8), cv2.COLOR_RGB2GRAY),
                    cv2.cvtColor((fake_np*255).astype(np.uint8), cv2.COLOR_RGB2GRAY),
                    data_range=255
                )

    # 平均指标
    train_g_loss /= len(train_loader.dataset)
    train_d_loss /= len(train_loader.dataset)
    val_psnr /= len(val_loader.dataset)
    val_ssim /= len(val_loader.dataset)

    # 保存最优模型
    if val_ssim > best_val_ssim:
        best_val_ssim = val_ssim
        torch.save(generator.state_dict(), "bci_pix2pix_best.pth")
        print(f"Epoch {epoch+1}:保存最优模型(Val SSIM={val_ssim:.4f})")

    # 打印日志
    print(f"\nEpoch {epoch+1}/{num_epochs}")
    print(f"训练:生成器损失={train_g_loss:.4f},判别器损失={train_d_loss:.4f}")
    print(f"验证:PSNR={val_psnr:.2f},SSIM={val_ssim:.4f}")

# 6. 测试集评估(加载最优模型)
generator.load_state_dict(torch.load("bci_pix2pix_best.pth"))
generator.eval()

test_psnr, test_ssim = 0.0, 0.0
with torch.no_grad():
    for he_imgs, ihc_imgs in test_loader:
        he_imgs, ihc_imgs = he_imgs.to(device), ihc_imgs.to(device)
        fake_ihc = generator(he_imgs)
        
        # 反归一化与指标计算
        ihc_imgs = (ihc_imgs + 1) / 2
        fake_ihc = (fake_ihc + 1) / 2
        
        for i in range(he_imgs.size(0)):
            real_np = ihc_imgs[i].permute(1, 2, 0).cpu().numpy()
            fake_np = fake_ihc[i].permute(1, 2, 0).cpu().numpy()
            
            test_psnr += peak_signal_noise_ratio(real_np, fake_np, data_range=1.0)
            test_ssim += structural_similarity(
                cv2.cvtColor((real_np*255).astype(np.uint8), cv2.COLOR_RGB2GRAY),
                cv2.cvtColor((fake_np*255).astype(np.uint8), cv2.COLOR_RGB2GRAY),
                data_range=255
            )

test_psnr /= len(test_loader.dataset)
test_ssim /= len(test_loader.dataset)
print(f"\n=== 测试集最终评估 ===")
print(f"平均PSNR:{test_psnr:.2f}(>30为优秀)")
print(f"平均SSIM:{test_ssim:.4f}(>0.8为优秀)")

关键说明:L1 损失权重设为 100 是核心 —— 生成模型需优先保证 “结构一致性”(如 IHC 棕染区域与 H&E 癌细胞位置匹配),避免 GAN 仅关注染色风格而生成 “非特异性棕染”;临床评估需额外加入 “病理医生盲评”(判断生成 IHC 的蛋白表达强度与真实值一致性),PSNR/SSIM 仅为工程指标,需结合临床标准验证。

3. 效果可视化与部署建议

  • 效果可视化
    1. 染色转换三列对比图:展示 “输入 H&E→生成 IHC→真实 IHC”,重点标注临床关键区域(如 HER2 阳性的细胞膜棕染、ER 阳性的细胞核棕染),直观验证生成精度;

验证报告

以下为卖家选择提供的数据验证报告:

data icon
4872 对 H&E-IHC 结构级对齐图像 BCI 数据集(北京朝阳医院 + 首医合作)| elastix 注册 + 6 步标准化构建 | 乳腺癌 IHC 染色图像生成 | 医学影像 / 深度学习
25
已售 0
2.71GB
申请报告