CT-Palette: 用扩散模型恢复截断CT图像的身体成分分析
本文最后更新于190 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

发布日期: 2025年11月
文章分类: 深度学习 / 医学影像 / 生成模型
阅读时间: 15分钟


摘要

本文介绍CT-Palette论文的核心内容。该论文通过扩散模型小掩码统计选择三个创新,解决了胸部CT图像视场截断导致的身体成分分析问题。关键成果是只用87%的少数据,效果反而改进56%


一、问题背景:为什么需要恢复截断的CT图像

医学背景

胸部CT扫描是评估肺部疾病的重要工具。然而,临床中常见一个问题:CT图像被截断

为什么会截断?原因很简单——为了优先保证肺部(中心区域)的图像质量,医生会故意减小扫描的视场(Field of View, FOV)。结果是:

  • ✓ 肺部清晰(诊断肺病有利)
  • ✗ 周围肌肉和脂肪被切掉(无法做身体成分分析)

临床意义

身体成分分析(Body Composition Analysis)是什么?就是测量患者在某个CT层面上的:

  • 肌肉面积(骨骼肌横截面积)
  • 脂肪面积(皮下脂肪,Subcutaneous Adipose Tissue, SAT)

这看起来是个简单的测量,但对患者预后评估至关重要:

患者类型关键指标医学意义
肺癌患者肌肉面积↓肌肉浪费是负面预后因素
胰腺癌患者脂肪/肌肉比影响治疗效果和生存期
重症患者肌肉质量决定康复能力

如果图像被截断,我们就无法准确测量这些指标,从而影响医生的诊断和治疗决策。

标准测量位置

医学上规定了三个标准的测量脊椎水平:

  • T5(第5胸椎)
  • T8(第8胸椎)
  • T10(第10胸椎)

这三个位置的身体成分是评估患者整体健康状况的标准指标。


二、问题的数学本质:Ill-posed问题

什么是Ill-posed问题

在数学中,一个问题称为well-posed需要满足三个条件:

  1. 存在性(Existence):解必须存在
  2. 唯一性(Uniqueness):解必须唯一
  3. 稳定性(Stability):解连续依赖于输入

如果违反任何一个条件,就是ill-posed问题。

FOV恢复问题为什么是Ill-posed

设:

  • $x$ = 完整的原始CT图像
  • $y$ = 观测到的截断图像
  • $T$ = 截断操作

我们的关系式是:
$$y = T(x)$$

问题:给定 $y$,求 $x$

困难:操作 $T$ 不是单射(injective)

这意味着:多个不同的 $x$ 都可能产生相同的 $y$

具体例子

想象医生看到一个截断的胸部CT图像,肺部看起来完全一样。但我们无法看到背部。背部可能是:

情景1: 肌肉发达的人  ✓ 可能产生这个截断图像
情景2: 普通人        ✓ 可能产生这个截断图像  
情景3: 病人          ✓ 可能产生这个截断图像
情景4: 其他...       ✓ 都有可能

结论:无法唯一确定正确答案!

集合论表示

解的可能集合为:
$$S = {x : T(x) = y}$$

这个集合 $S$ 可能包含无穷多个元素

传统方法的局限

传统方法通过加约束条件(regularization)来解决this问题:

$$\arg\min_x |T(x) – y|^2 + \lambda R(x)$$

其中 $R(x)$ 是正则化项。常见的约束:

  • 平滑性:$R(x) = |\nabla x|^2$(假设最光滑的解最好)
  • 稀疏性:$R(x) = |x|_1$(假设最稀疏的解最好)

问题:这些假设可能不成立!真实的身体有肌肉纹理、脂肪堆积等结构,根本不光滑。所以数学上最优的解医学上可能是错的


三、扩散模型:从概率角度解决Ill-posed问题

新思路:学习分布而不是加假设

与传统的约束优化不同,我们采用生成模型的思路:

传统方法:      数学优化 → 单一确定解
生成模型方法:  学习分布 → 多个可能解 → 统计选择

关键洞察:既然有多个可能的解,我们为什么要选单一的?不如生成多个解,然后统计选最合理的

扩散模型的基本原理

扩散模型是一种生成模型,通过学习数据的分布来生成新的样本。

前向过程:逐步加噪

从一张干净的图像开始,逐步加入高斯噪声,直到变成纯噪声:

$$x_t = \sqrt{\alpha_t} \cdot x_0 + \sqrt{1-\alpha_t} \cdot \epsilon$$

其中:

  • $x_0$ = 原始清晰图像
  • $x_t$ = 第 $t$ 步的噪声图像
  • $\alpha_t$ = 噪声比例系数(随 $t$ 增加而减小,从1到0)
  • $\epsilon \sim \mathcal{N}(0, I)$ = 标准高斯噪声
  • $t \in {0, 1, \ldots, 1000}$ = 时间步

理解:这是一个线性组合

  • 当 $t=0$ 时:$x_0 = 1 \cdot x_0 + 0 \cdot \epsilon$(100%原图,0%噪声)
  • 当 $t \to 1000$ 时:$x_t \approx 0 \cdot x_0 + 1 \cdot \epsilon$(接近纯噪声)

反向过程:逐步去噪

反向就是从噪声逐步恢复清晰图像。这需要神经网络学习去噪:

$$x_{t-1} = \frac{1}{\sqrt{\alpha_t}} \left( x_t – \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \hat{\epsilon}(x_t, t) \right) + \sigma_t z$$

其中:

  • $\hat{\epsilon}(x_t, t)$ = 神经网络预测的噪声(这是我们要学的
  • $\bar{\alpha}t = \prod{s=1}^{t} \alpha_s$ = 累积系数
  • $z \sim \mathcal{N}(0, I)$ = 新引入的高斯噪声
  • $\sigma_t$ = 噪声标准差

简单理解:每一步,神经网络看一个嘈杂的图像,然后预测”这一步应该去掉什么噪声”,然后我们真的去掉它。重复1000次,得到清晰图像。

训练过程

训练损失函数很简单:

$$\mathcal{L} = \mathbb{E}_{t, x_0, \epsilon} \left[ | \epsilon – \hat{\epsilon}(x_t, t) |^2 \right]$$

让网络学会准确预测噪声。期望是对所有:

  • 时间步 $t$
  • 训练样本 $x_0$
  • 噪声样本 $\epsilon$

进行求期望。

扩散模型的优势

为什么选扩散模型而不是CNN或GAN?

  1. 多样性:每次从不同随机噪声开始,所以能生成多个不同的结果 → 适合ill-posed问题
  2. 理论完整:有明确的概率论基础,训练目标清晰
  3. 稳定性:训练过程简单稳定,不需要复杂的损失函数调参
  4. 泛化性好:学习的是通用的去噪能力,对小数据也有效

四、CT-Palette的三个核心创新

创新1:小掩码方法

传统方法的掩码

传统方法的做法:

  1. 检测RFOV(重建视场,圆形)
  2. 检测DFOV(显示视场,矩形)
  3. 标记所有在这两者之外的像素为”需要修复”

结果是修复区域很大,而且大部分在身体外

  • 空气区域(单调,容易修复)
  • 扫描台(单调,容易修复)
  • 只有一小部分在身体边界(复杂,难修复)

这就像教一个学生识别猫,却给他看1000张照片,其中1000张猫、200张狗、100张背景。学生需要学很多不相关的东西。

CT-Palette的小掩码创新

改进做法:

  1. 检测身体的边界框 $\hat{B}$
  2. 只修复边界框内,身体外的部分

数学表示:
$$m_{\text{small}} = \left( (RFOV \cup DFOV)^c \right) \cap \hat{B} \setminus m_{\text{body}}$$

解读:

  • $(RFOV \cup DFOV)^c$ = 被切掉的部分
  • $\cap \hat{B}$ = 交上边界框内
  • $\setminus m_{\text{body}}$ = 去掉身体内部

效率对比

假设图像大小为 $256 \times 256 = 65536$ 像素:

方法修复像素数简化比例
传统掩码~36,000100%
小掩码~10,80030%
削减-25,20070%削减

为什么有效?

学习难度与待学习区域的复杂度成正比:

  • 修复空气 = 简单(单调)
  • 修复身体边界 = 复杂(纹理、脂肪堆积)
  • 总难度 = (简单+复杂) = 中等

小掩码做法:

  • 只修复复杂部分
  • 总难度 = 复杂 = 相对更容易用小数据学

这就是为什么用87%的少数据反而效果更好的关键原因。

创新2:条件扩散模型

条件是什么

在标准扩散模型的基础上,我们加入条件信息

  1. 截断图像 $y_{\text{truncated}}$:已知的部分
  2. 掩码 $m$:标记哪些像素是未知的

条件扩散模型学习的是条件分布:
$$p(x_{\text{unknown}} | x_t, t, y_{\text{known}}, m)$$

如何编码条件

方法1:通道拼接

网络输入 = [噪声图像, 已知区域像素, 掩码, 时间嵌入]
        (拼成多通道张量)

方法2:注意力融合

噪声图像 → 主处理流
已知区域 → 通过交叉注意力与主流交互
结合产生输出

CT-Palette可能使用通道拼接的方法。

推理中的强制约束

这是关键一步——确保已知部分始终不变:

对每一个去噪步骤:
$$x_{t-1}[\text{已知区域}] = y_{\text{truncated}}[\text{已知区域}]$$

意义

  • 模型只生成未知区域
  • 已知区域完全保持输入的截断图像
  • 生成多个结果时,已知部分始终一致,只有未知部分有多样性

创新3:多次推理与统计选择

多次推理

生成 $N$ 个(默认 $N=5$)不同的恢复结果:

for i in range(1, 6):
    x_i = diffusion_model(truncated_image, mask)
    # 每次得到的结果略微不同,因为:
    # 1. 扩散过程中引入的随机噪声 z 每次不同
    # 2. 网络预测的噪声有微小差异

特征提取

对每个生成的恢复结果 $x_i$,用预训练的分割网络提取身体成分特征:

$$f_i^{\text{muscle}} = \text{肌肉面积}_i \quad (\text{cm}^2)$$
$$f_i^{\text{fat}} = \text{脂肪面积}_i \quad (\text{cm}^2)$$

中位数计算

$$\bar{f}^{\text{muscle}} = \text{median}(f_1^{\text{muscle}}, f_2^{\text{muscle}}, \ldots, f_5^{\text{muscle}})$$
$$\bar{f}^{\text{fat}} = \text{median}(f_1^{\text{fat}}, f_2^{\text{fat}}, \ldots, f_5^{\text{fat}})$$

为什么用中位数而不是平均数?

中位数对异常值更鲁棒。统计学术语是”breakdown point”:

  • 平均数:任何极端值都会拉偏
  • 中位数:需要 $\geq 50\%$ 的数据才能被拉偏

例子

5个肌肉面积:[100, 105, 102, 110, 98]
平均数 = (100+105+102+110+98)/5 = 103
中位数 = 102

5个肌肉面积(有离群值):[100, 105, 102, 110, 5000]
平均数 = (100+105+102+110+5000)/5 = 1083 ✗ 被5000拉偏了!
中位数 = 102 ✓ 不受影响

L1距离选择

对每个结果计算到中位数的L1距离

$$L_1(x_i) = |f_i^{\text{muscle}} – \bar{f}^{\text{muscle}}| + |f_i^{\text{fat}} – \bar{f}^{\text{fat}}|$$

选择距离最小的结果作为最终输出:

$$x^* = \arg\min_i L_1(x_i)$$

为什么L1而不是L2?

L1范数对大偏差不敏感(线性),L2范数会平方放大(二次):

$$\begin{align}
\text{L1}: \quad |x| &= x \quad \text{(线性)} \
\text{L2}: \quad |x|^2 &= x^2 \quad \text{(二次,大数被拉大)}
\end{align}$$

如果有一个极端结果(如肌肉面积预测特别离谱),L2会被严重拉偏,但L1不会。

具体例子

假设生成了5个恢复结果:

结果肌肉面积 (cm²)脂肪面积 (cm²)
1100200
2105210
3102205
4110220
598190

计算过程

第1步:中位数
$$\bar{f}^{\text{muscle}} = \text{median}(100, 105, 102, 110, 98) = 102$$
$$\bar{f}^{\text{fat}} = \text{median}(200, 210, 205, 220, 190) = 205$$

第2步:L1距离
$$\begin{align}
L_1(x_1) &= |100-102| + |200-205| = 2 + 5 = 7 \
L_1(x_2) &= |105-102| + |210-205| = 3 + 5 = 8 \
L_1(x_3) &= |102-102| + |205-205| = 0 + 0 = 0 \quad \leftarrow \text{最小} \
L_1(x_4) &= |110-102| + |220-205| = 8 + 15 = 23 \
L_1(x_5) &= |98-102| + |190-205| = 4 + 15 = 19
\end{align}$$

选择:结果3,因为距离最小

医学意义:选择的是最”正常”的身体成分组合——既不肌肉特别多,也不特别少,脂肪也是适度的。


五、实验设置与数据

数据源

  • 研究:Framingham心脏研究(长期队列研究)
  • 时间:2002-2011年
  • 总患者:3,152人

患者统计

  • 女性比例:54%
  • 种族:91%白人
  • 平均年龄:56.1 ± 10.4岁
  • 平均BMI:29.9 ± 5.4 kg/m²

使用的CT层面

只使用三个标准身体成分分析的脊椎水平:

  • T5(第5胸椎)
  • T8(第8胸椎)
  • T10(第10胸椎)

数据集划分

数据集切片数患者数占比
训练集9,0613,15270%
验证集89917710%
测试集99821010%

重要:按患者ID划分(防止同一患者的多个切片跨越不同数据集,造成数据泄露)

图像预处理

原始512×512 CT图像
  ↓
[步骤1] 应用HU窗口 [-160, 240]
        目的:只关注软组织(肌肉、脂肪)
  ↓
[步骤2] 线性缩放到 [-1, 1]
        目的:标准化像素值范围供神经网络使用
  ↓
[步骤3] 移除身体外的物体
        目的:去除扫描台、床等无关物体
  ↓
[步骤4] 降采样到 256×256
        目的:减少计算量,加快训练
  ↓
准备完毕!

HU窗口的意义

HU(Hounsfield Units)是CT图像的强度单位:

  • 脂肪:-100 到 -50 HU
  • 肌肉:+10 到 +40 HU
  • 水:0 HU

窗口 [-160, 240] 覆盖了脂肪和肌肉的全部范围,同时压低了骨头(+400~1000 HU)和其他组织的信号,达到突出感兴趣组织的目的。

合成截断模式

RFOV(重建视场)

  • 形状:圆形
  • 大小:半径比例 $r_{\text{RFOV}} \sim \text{Uniform}[0.5, 0.7]$
  • 中心:图像中心
  • 含义:扫描仪物理能记录的范围

DFOV(显示视场)

  • 形状:矩形
  • 大小:边长比例 $r_{\text{DFOV}} \sim \text{Uniform}[0.65, 0.9]$
  • 位置:中心加随机偏移 $(x_{\text{DFOV}}, y_{\text{DFOV}})$
  • 含义:显示给医生的最终范围

实际截断区域

$$\text{截断区域} = RFOV \cap DFOV$$

即:只显示既在RFOV范围内,又在DFOV范围内的部分。

为什么两种FOV? 为了模拟真实CT机器的复杂截断模式,增加训练数据的多样性。


六、评估指标

1. 肌肉和脂肪面积RMSE(最核心)

定义

$$\text{RMSE}{\text{muscle}} = \sqrt{\frac{1}{n} \sum{i=1}^{n} (A_{\text{muscle},i}^{\text{pred}} – A_{\text{muscle},i}^{\text{true}})^2}$$

$$\text{RMSE}{\text{fat}} = \sqrt{\frac{1}{n} \sum{i=1}^{n} (A_{\text{fat},i}^{\text{pred}} – A_{\text{fat},i}^{\text{true}})^2}$$

含义:预测的肌肉/脂肪面积与真实值的平方误差平均值,再开方。

单位:cm²

医学意义:直接关系到身体成分分析的准确度,最终影响患者诊断。

2. Dice相似系数(分割准确度)

定义

$$\text{Dice} = \frac{2|X \cap Y|}{|X| + |Y|}$$

其中:

  • $X$ = 预测的分割区域(肌肉或脂肪)
  • $Y$ = 真实的分割区域
  • $|\cdot|$ = 区域的像素数

范围:0到1,1表示完全相同

医学意义:衡量分割的精度,直接影响测量的准确性。

3. FID(Fréchet初始距离)

定义

$$\text{FID} = \left| \mu_r – \mu_g \right|_2^2 + \text{Tr}\left(\Sigma_r + \Sigma_g – 2\left(\Sigma_r^{1/2} \Sigma_g \Sigma_r^{1/2}\right)^{1/2}\right)$$

其中:

  • $\mu$ = 特征分布的均值
  • $\Sigma$ = 特征分布的协方差矩阵
  • 下标 $r$ = 真实,$g$ = 生成

含义:生成图像分布与真实图像分布的距离,数值越小越好。

意义:衡量生成的图像在统计上有多”像”真实数据。

4. PSNR和SSIM(图像质量指标)

PSNR(峰值信噪比)

$$\text{PSNR} = 10 \log_{10} \left( \frac{\text{MAX}^2}{\text{MSE}} \right)$$

单位:dB,通常 >30dB 表示图像质量好

SSIM(结构相似性)

$$\text{SSIM} = \frac{(2\mu_1\mu_2 + c_1)(2\sigma_{12} + c_2)}{(\mu_1^2 + \mu_2^2 + c_1)(\sigma_1^2 + \sigma_2^2 + c_2)}$$

范围:-1到1,1表示完全相同


七、实验结果

核心数据

方法肌肉RMSE脂肪RMSE肌肉Dice脂肪Dice
RFR-Net9.02235.258
S-EFOV9.09120.480
S-EFOV(FT)8.20224.9740.9740.947
CT-Palette(SI)5.02716.307
CT-Palette(MI)3.96712.9730.9790.954

  • SI = Single Inference(单次推理)
  • MI = Multiple Inference(多次推理,本论文方法)
  • FT = Fine-tuned(微调)

关键改进

相对于S-EFOV(FT)(之前最好的方法)

$$\begin{align}
\text{肌肉误差改进} &= \frac{8.202 – 3.967}{8.202} = \frac{4.235}{8.202} \approx 51.6\% \text{ ↓} \
\text{脂肪误差改进} &= \frac{24.974 – 12.973}{24.974} = \frac{12.001}{24.974} \approx 48.0\% \text{ ↓}
\end{align}$$

数据效率对比

$$\begin{align}
\text{S-EFOV 数据量} &= 71,319 \text{ 张} \
\text{CT-Palette 数据量} &= 9,061 \text{ 张} \
\text{数据节省} &= \frac{71,319 – 9,061}{71,319} = \frac{62,258}{71,319} \approx 87.3\%
\end{align}$$

结论:用 87%更少的数据,效果反而改进 51.6%

单次vs多次推理

方法肌肉RMSE改进vs单次
单次推理(SI)5.027
多次推理(MI)3.96721.1%↓

多次推理的价值:通过5个样本的统计选择,避免了单次推理可能出现的极端情况。

医生定性评价

邀请两位放射科医生评价120个测试样本:

医生经验CT-Palette更好相当S-EFOV更好
A3年23.3%76.7%0%
B10年+58.3%41.7%0%

综合结论:医生认可CT-Palette的方法。


八、关键洞察与讨论

为什么小数据效果更好?

这是论文最有趣的发现。关键原因:

  1. 学习复杂度降低
  • 传统:需要学习如何填充简单(空气)+ 复杂(身体边界)区域
  • 小掩码:只学复杂部分,相当于集中学习困难部分
  1. 扩散模型的通用性
  • 扩散模型学习的是通用的去噪能力
  • 不依赖复杂的任务特定损失函数
  • 对小数据更友好
  1. 小掩码的数据效率
  • 将需要学习的区域从36,000像素减少到10,800像素
  • 学习密度提高(同样数据量,每个像素被”看到”的次数更多)

ill-posed问题的一般性解决方案

这个工作提供了一个通用框架来处理ill-posed问题:

Ill-posed问题(多个解都对)
  ↓
用生成模型生成多个可能解
  ↓
设计指标来评判解的质量
  ↓
自动统计选择最优解

这个框架可以应用于:

  • 其他医学图像截断问题
  • 图像修复(inpainting)
  • 超分辨率(本质也是ill-posed)
  • 其他逆问题

九、局限与未来方向

主要局限

  1. 推理速度慢
  • 需要1000步迭代去噪
  • 多次推理需要5次运行
  • 这是论文承认的主要限制
  1. 数据集单一
  • 只在Framingham数据上验证
  • 需要在其他数据集验证泛化性
  1. 只用三个脊椎水平
  • 可能需要扩展到全身CT
  1. 依赖分割网络
  • 评判标准依赖预训练的肌肉/脂肪分割网络
  • 这个网络的质量直接影响结果

潜在改进方向

  1. 推理加速
  • DDIM采样:1000步 → 50步
  • 知识蒸馏:训练快速学生网络
  • 硬件加速:使用专用芯片
  1. 应用扩展
  • 其他医学图像模态(MRI、超声)
  • 其他部位的CT(腹部、颈部)
  • 其他医学图像任务
  1. 方法改进
  • 更好的条件融合方式
  • 更智能的结果选择(不仅考虑面积)
  • 融合医学先验知识

十、总结与启示

核心贡献

CT-Palette论文的核心贡献是:

  1. 理论:用生成模型处理ill-posed医学图像问题的新思路
  2. 方法:三个实用的创新(小掩码、扩散模型、统计选择)
  3. 结果:用少得多的数据达到更好的效果

关键数字

指标数值
肌肉误差改进56%
脂肪误差改进37%
数据节省87%

更深的启示

这个工作展现了几个重要的ML/医学影像研究思路:

  1. 问题的本质很重要
  • 识别ill-posed vs well-posed
  • 选择合适的解决范式(优化 vs 生成)
  1. 小数据时的设计
  • 减少学习区域复杂度
  • 用通用而不是特定的学习目标
  • 充分利用数据的有效性
  1. 医学应用的验证
  • 定量指标(RMSE、Dice)
  • 定性评价(医生评价)
  • 两者结合才是完整验证

参考与延伸阅读

相关概念

  • Ill-posed问题理论:Hadamard在1902年提出的经典概念
  • 扩散模型:Ho et al. (2020) “Denoising Diffusion Probabilistic Models”
  • 条件生成:Dhariwal & Nichol (2021) 在扩散模型中的应用
  • 医学身体成分分析:临床常用指标

类似工作

  • 图像修复:inpainting任务,也常用扩散模型
  • 医学图像重建:各种逆问题,都涉及ill-posed问题
  • 其他生成应用:文本生成、视频生成等也遇到类似问题

关于作者

作者机构

  • Technical University of Munich
  • Massachusetts General Hospital / Harvard Medical School
  • Imperial College London

发表时间:2024年


讨论与反馈

如果你对这篇论文感兴趣,欢迎讨论:

  • 扩散模型在医学图像的应用
  • Ill-posed问题的其他解决方案
  • 小数据条件下的深度学习策略
  • 医学影像AI的伦理问题

文章完。


附录:关键公式一览表

所有重要公式在这里汇总:

扩散模型

前向过程(加噪)
$$x_t = \sqrt{\alpha_t} \cdot x_0 + \sqrt{1-\alpha_t} \cdot \epsilon$$

反向过程(去噪)
$$x_{t-1} = \frac{1}{\sqrt{\alpha_t}} \left( x_t – \frac{1-\alpha_t}{\sqrt{1-\bar{\alpha}_t}} \hat{\epsilon}(x_t, t) \right) + \sigma_t z$$

训练损失
$$\mathcal{L} = \mathbb{E}_{t, x_0, \epsilon} \left[ | \epsilon – \hat{\epsilon}(x_t, t) |^2 \right]$$

小掩码

$$m_{\text{small}} = \left( (RFOV \cup DFOV)^c \right) \cap \hat{B} \setminus m_{\text{body}}$$

统计选择

中位数
$$\bar{f}^{\text{muscle}} = \text{median}(f_1^{\text{muscle}}, \ldots, f_5^{\text{muscle}})$$

L1距离
$$L_1(x_i) = |f_i^{\text{muscle}} – \bar{f}^{\text{muscle}}| + |f_i^{\text{fat}} – \bar{f}^{\text{fat}}|$$

最优选择
$$x^* = \arg\min_i L_1(x_i)$$

评估指标

RMSE
$$\text{RMSE} = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i – \hat{y}_i)^2}$$

Dice系数
$$\text{Dice} = \frac{2|X \cap Y|}{|X| + |Y|}$$

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇