【读点论文】Fourier Contour Embedding for Arbitrary-Shaped Text Detection通过预测傅里叶自由度,系数来拟合任意形状轮廓线

Fourier Contour Embedding for Arbitrary-Shaped Text Detection

Abstract

  • 任意形状文本检测的主要挑战之一是设计一个好的文本实例表示,使网络能够学习不同的文本几何变化。大多数现有方法通过笛卡尔或极坐标系中的掩模或轮廓点序列在图像空间域中对文本实例进行建模。 然而,掩模表示可能会导致昂贵的后处理,而点序列表示对具有高度弯曲形状的文本的建模能力有限。为了解决这些问题,我们在傅里叶域中对文本实例进行建模,并提出一种新颖的傅里叶轮廓嵌入 (FCE) 方法将任意形状的文本轮廓表示为紧凑签名。我们进一步构建了具有主干、特征金字塔网络 (FPN) 和简单后处理的 FCENet,其中包括逆傅里叶变换 (IFT) 和非最大值抑制 (NMS)。与以前的方法不同,FCENet 首先预测文本实例的紧凑傅里叶签名,然后在测试期间通过 IFT 和 NMS 重建文本轮廓。大量实验表明,即使形状弯曲度很大,FCE 也能准确且稳健地拟合场景文本的轮廓,同时也验证了 FCENet 对任意形状文本检测的有效性和良好的泛化能力。此外,实验结果表明,我们的 FCENet 优于 CTW1500 和 Total-Text 上最先进的 (SOTA) 方法,尤其是在具有挑战性的高度弯曲文本子集上。mmocr/configs/textdet/fcenet/README.md at main · open-mmlab/mmocr · GitHub
  • 论文地址:[2104.10442] Fourier Contour Embedding for Arbitrary-Shaped Text Detection
  • FCENet是一种基于分割的场景文本检测算法。在场景文本检测中,基于分割这类算法可以更加准确的描述各种形状的场景文本(比如弯曲形状的文本),而变得越来越流行。 FCENet的一大亮点就是在任意不规则形状的文本场景上表现优异,这得益于它采用了可变形卷积 和傅里叶变换技术。 除此之外,FCENet还具有后处理简单和高泛化性的优点,在少量训练数据上训练就可以达到很好的效果。傅里叶轮廓线是基于傅里叶变换的一种曲线拟合方法,随着傅里叶级数的项数k越大,就引入更多的高频信号,对轮廓刻画就越准确
  • 傅里叶轮廓线编码是《Fourier Contour Embedding for Arbitrary-Shaped Text Detection》论文提出的一种将文本的轮廓的封闭曲线转化为一个向量(vector)的方法,也是FCENet算法需要用到的一种编码轮廓线的基础能力。傅里叶轮廓线编码方法通过在轮廓线上等间距的采样一些点,然后将采样的点的序列转化为傅里叶特征向量。值得注意的是,即使对于同一轮廓线,采样的点不同,对应生成的傅里叶特征向量也不相同。所以在采样的时候,需要限制起始点、间距和方向,保证对同一轮廓线生成的傅里叶特征向量的唯一性。
  • 论文提出了针对场景文本中的任意形状的文本框利用傅里叶变换进行建模的方法,骨干网络采用了ResNet+FPN的架构。针对Head部分,FCENet具有两个分支,其中分类分支预测文本区域和文本中心区域的概率图,相乘得到属于文本中心分类的得分图;回归分支则负责预测傅里叶特征向量。算法对文本中心置信度大于阈值的像素点所对应的傅里叶特征向量进行反变换,经过NMS得到最终的检测结果。

Introduction

  • 受益于对象检测 和实例分割 的发展,文本检测取得了重大进展 。文本检测方法大致可分为基于分割的方法 和基于回归的方法 。最近的研究重点已经从水平或多方向文本检测 转向更具挑战性的任意形状文本检测 。与多方向文本检测相比,文本实例表示在任意形状文本检测中起着不可或缺的作用。好的表示应该简单、紧凑且具有良好的泛化能力以避免过度拟合。然而,设计一个紧凑的文本实例表示并不简单,因为拟合文本实例的不同几何变化具有挑战性。现有的任意形状文本检测方法在图像的空间域中表示文本实例。它们通过每像素掩码 、笛卡尔系统 或极坐标系统中的轮廓点序列 对文本进行建模。基于空间域的方法有明显的缺点。掩码表示可能导致计算成本高昂的后处理,并且通常需要大量训练数据。而轮廓点序列对高度弯曲的文本的建模能力可能有限

  • 在本文中,我们通过傅里叶变换在傅里叶域而不是空间域中对文本实例轮廓进行建模,该变换可以以稳健而简单的方式对任何封闭轮廓进行渐进近似。 图 1a 说明,傅里叶变换可以准确地拟合具有非常紧凑签名(例如,K = 125)的极其复杂的形状(例如,肖像素描),并且表明随着傅里叶阶数 k 的增加,重建的形状更接近 GT。与极坐标系中的 SOTA 文本轮廓点序列 TextRay 相比,我们提出的傅里叶轮廓表示可以更好地模拟高弯曲文本,如图 1b-c 所示。

    • 在这里插入图片描述

    • 图 1:与 Fourier 轮廓和 TextRay 轮廓 表示的比较。(a) 显示 Fourier 轮廓可以拟合极其复杂的物体形状,并且随着 Fourier 阶数 k 的增加,获得更好的近似值。(b) 和 © 比较 TextRay 轮廓和我们提出的 Fourier 轮廓,其中真实轮廓为绿色,重建轮廓为红色。TextRay 无法模拟高度弯曲的文本(最好以彩色显示)。

  • 为此,我们提出了傅里叶轮廓嵌入(FCE)方法,将文本实例轮廓从点序列转换为傅里叶签名向量。首先,我们提出一种重采样方案,以获得每个文本轮廓上固定数量的密集点。为保持所得傅里叶签名向量的唯一性,我们将文本轮廓与通过文本中心点的水平线之间的最右交点设置为采样起点,固定采样方向为顺时针方向,并保持沿文本轮廓的采样间隔不变。其次,通过傅里叶变换(FT)将空域中轮廓的采样点序列嵌入到傅里叶域中。FCE 对于文本实例表示的优点有三点:

    • 灵活:任何封闭轮廓,包括极其复杂的形状,都能精确拟合;

    • 紧凑性:我们的方法得到的傅里叶签名向量是紧凑的。在我们的实验中,傅里叶阶数 K = 5 可以实现非常准确的文本近似

    • 简单性:采样点序列与文本轮廓的傅里叶特征向量之间的转换公式为傅里叶变换和逆傅里叶变换。因此,FCE 方法易于实现,无需引入复杂的后处理。

  • 借助 FCE,我们进一步构建了用于任意形状文本检测的 FCENet。具体来说,它由带有可变形卷积网络 (DCN) 的 ResNet50 主干、特征金字塔网络 (FPN) 和傅里叶预测头组成。头有两个独立的分支,即分类分支和回归分支。前者预测文本区域掩码和文本中心区域掩码。后者预测傅里叶域中的文本傅里叶特征向量,这些向量被输入到逆傅里叶变换 (IFT) 中以重建文本轮廓点序列。 GT 文本轮廓点序列用作监督信号。得益于 FCE 的重采样方案,我们在回归分支中的损失在不同数据集之间兼容,尽管 CTW1500 和 Total-Text 等数据集对于每个文本实例的轮廓点数量不同。

  • 实验验证了 FCENet 对任意形状文本检测的有效性和良好的泛化能力。 此外,我们的 FCENet 优于 CTW1500 和 Total-Text 上的最先进 (SOTA) 方法,尤其是在其高度弯曲的文本子集上。我们总结这项工作的贡献如下:

    • 我们提出了傅里叶轮廓嵌入(FCE)方法,它可以准确地将任何封闭形状(包括任意形状的文本轮廓)近似为紧凑的傅里叶签名向量
    • 我们提出了 FCENet,它首先在傅里叶域中预测文本实例的傅里叶特征向量,然后通过逆傅里叶变换 (IFT) 在图像空间域中重建文本轮廓点序列。它可以端到端学习,并且无需任何复杂的后处理即可进行推断。
    • 我们对所提出的 FCE 和 FCENet 进行了广泛的评估。实验结果验证了 FCE 的良好表示能力(尤其是在高度弯曲的文本上)以及 FCENet 在小型数据集上训练时的泛化能力。此外,已经证明 FCENet 在 CTW1500 和 Total-Text 上实现了最先进的性能。
  • FCENet (Fourier Contour Embedding for Arbitrary-Shaped Text Detection) 通过预测一种基于傅里叶变换的任意形状文本包围框表示,从而实现了自然场景文本检测中对于高度弯曲文本实例的检测精度的提升。

  • 目前场景文本检测的关注点已从原来的水平方向文本和多方向文本转到更具挑战性且更普遍的任意形状文本上,如果在任意形状文本检测中仍然采用矩形框表示文本实例,会引入过多的背景信息从而影响检测精度。因此,如何对任意形状的文本实例进行建模,是解决任意形状文本检测的一个关键。

  • 目前现有的任意形状文本实例建模大致上可以分为基于分割的自底向上的方法和从数学上对文本包围框进行建模的自顶向下的方法。自底向上的方法借鉴了实例分割的思想,对输入的图像的每个像素进行分类从而生成掩模,再经过聚合操作得到输出结果。但是通常这类方法的聚合后处理比较复杂,使得网络的处理流程变得冗长,而且对于重叠在一起的目标,因为不同的文本共享同样的像素,这类方法难以将它们进行区分。而目前在自顶向下的方法中,轮廓表征模型的表达能力还是有限的、当遇到一些形状比较复杂的轮廓时会建模失败,并且需要较多的参数。由于傅里叶系数表示在理论上可以拟合任意的封闭曲线,并且文本轮廓信息更多集中在低频分量上,所以通过在傅立叶域对不规则场景文字实例进行表征能够很好地解决上述问题,并且具有简单、紧凑、对复杂轮廓表达能力优异的特点

Related Work

Segmentation-Based Methods

  • 这些方法主要从语义分割中汲取灵感,语义分割使用逐像素掩码对文本实例进行隐式编码 。这些方法大多遵循组件分组范式,即首先检测场景文本实例的组件,然后聚合这些组件以获得最终的掩码输出

  • 对于基于像素的方法,首先使用实例/语义分割框架获取像素级得分图,然后对文本像素进行分组以获取输出文本掩码 。为了进一步提高性能,一些方法会在变换空间上进行预测,然后重建最终的图。例如,Tian 等人 将每个文本实例视为一个聚类,并通过像素聚类预测嵌入图;TextField 通过将邻近像素与深度方向场链接来生成候选文本部分

  • 对于基于 segment 的方法,首先检测包含单词或文本行的一部分(片段) 或字符 的片段,然后将片段分组到整个单词/文本行中。PSENet 使用相应的核检测每个文本实例,并采用渐进式缩放算法逐渐扩展预定义核以获得最终检测。 SegLink++ 使用具有最小生成树的实例感知组件分组实现密集和任意形状的场景文本检测。CRAFT 获得字符级检测并估计字符之间的亲和力以实现最终检测。

  • 一些方法在变换空间中训练预测器,并通过预测特征重建输出掩码。 例如,Tian 等人 [Learning shape-aware embedding for scene text detection] 通过将像素嵌入到一个空间中来构建判别性表示,其中相同文本的像素倾向于位于相同的聚类中,反之亦然;提出了 TextField 来学习一个方向场来分离相邻的文本实例。

Regression-Based Methods

  • 基于回归的方法是对基于分割的方法的补充,后者使用文本区域的轮廓(点序列)明确编码文本实例。它们旨在采用文本实例的直接形状建模来处理复杂的几何差异 ,并且通常更简单且更易于训练。然而,点序列对复杂文本实例的受限表示能力可能会限制网络的性能

  • 为了解决这个问题,人们精心设计了许多模块来进一步提高点序列表示的灵活性。LOMO 引入了迭代细化模块 (IRM) 和形状表达模块 (SEM) 来逐步细化直接回归的文本定位。张等人 使用 CNN 回归从文本实例中分割出的一系列小矩形组件的几何属性(例如高度、宽度和方向),并引入图卷积网络 (GCN) 来推断不同文本组件之间的联系。TextRay 在极坐标系统中制定文本轮廓,并提出了一个单次无锚框架来学习几何参数。刘等人 引入贝塞尔曲线来参数化曲线文本,并使用 BezierAlign 在场景文本识别中取得了 SOTA 性能。最近的研究表明,有效的轮廓建模对于不规则文本实例检测 和下游识别 至关重要。因此,设计一种灵活而简单的表示来检测任意形状的文本具有重要意义。

Explicit vs. Implicit Text Shape Representation

  • 从文本形状表示的角度来看,当前的模型大致可以分为两类。一类是通过每像素掩码 或通过变换特征重建的掩码 隐式地建模文本形状的方法,另一类是使用笛卡尔系统[Look more than once,Deep relational reasoning graph network for arbitrary shape text detection]或极坐标系统[Textray]中的轮廓点序列显式地建模文本形状的方法。然而,逐像素掩码可能导致网络本质上具有较高的计算复杂度(例如,复杂的后处理)并且需要大量的训练数据,而在轮廓上采样的点序列可能具有有限的表示能力,需要精心设计的细化或推理
  • 为了解决这个问题,刘等人引入了贝塞尔曲线来参数化弯曲的文本,但贝塞尔曲线的控制点设置可能会限制其在某些情况下的表示能力,如第 4.6 节所示。在本文中,文本实例在傅里叶域中公式化,这允许以稳健而简单的方式拟合任何闭合的连续轮廓。在下一节中,我们将探索 FCE 在任意形状文本检测中的潜力

Approach

  • 在本节中,我们首先介绍所提出的傅里叶轮廓嵌入 (FCE) 方法,该方法可以将任意形状的文本轮廓近似为紧凑的傅里叶签名向量。然后我们提出配备 FCE 的 FCENet 来检测任意形状的文本。

Fourier Contour Embedding

  • 我们使用一个实变量 t ∈ [ 0 ; 1 ] t \in [0; 1] t[0;1] 的复值函数 KaTeX parse error: Undefined control sequence: \C at position 16: \R \rightarrow \̲C̲ 来表示任何文本闭合轮廓,如下所示:

    • f ( t ) = x ( t ) + i y ( t ) ; ( 1 ) f(t) = x(t) + iy(t); (1) f(t)=x(t)+iy(t);(1)

    • 其中 i 表示虚数单位。(x(t); y(t)) 表示特定时间 t 时的空间坐标。由于 f 是闭合轮廓,因此 f(t) = f(t + 1)。f(t) 可以通过逆傅里叶变换 (IFT) 重新表述为:

    • f ( t ) = f ( t ; c ) = ∑ k = − ∞ + ∞ c k e 2 π i k t ; ( 2 ) f(t) = f(t; c) = \sum^{+\infty}_{k=-\infty} c_ke ^{2πikt} ; (2) f(t)=f(t;c)=k=+cke2πikt;(2)

    • 其中, k ∈ Z k \in \Z kZ 表示频率,ck 是复值傅里叶系数,用于表征频率 k 的初始状态。公式 2 中的每个分量 c k e 2 π i k t c_ke^{2πikt} cke2πikt 表示具有给定初始手部方向向量 ck 的固定频率 k 的圆周运动,因此,轮廓可以看作是不同频率圆周运动的组合,如图 2 所示的粉色圆圈。 从公式 2 中,我们观察到低频分量负责粗糙的文本轮廓,而高频分量负责轮廓的细节。我们通过经验发现,仅保留 K 个最低频率(在我们的实验中 K = 5)而丢弃其他频率可以获得令人满意的文本轮廓近似值,如图 5 所示。

    • 在这里插入图片描述

    • 图 2:FCE 示意图。它包含两个阶段,重采样根据真实点(红色)获得密集点序列(绿色);傅里叶变换用于使用重采样的点序列计算傅里叶系数 ck。可以通过将不同的固定频率圆周运动(用粉色圆圈表示)与手部方向 ck 相结合来重建轮廓。

    • 傅里叶轮廓嵌入算法(Fourier Contour Embedding)算法分两步,第一步是对轮廓进行采样离散化,譬如在轮廓上均匀采样400(N=400)个点,可以得到一个包含400个点的轮廓采样点序列 [ f ( 1 N ) , . . . , f ( 1 ) ] [f(\frac 1N),...,f(1)] [f(N1),...,f(1)],通过这一步采样,可以使得 FCE 算法支持更多的数据集合,因为不同数据集标注的文本区域轮廓点的数目并不一样。第二步就是进行傅里叶变换和反变换,求目标值和文本区域的检测框坐标。采样策略:采样起始点 f ( 0 ) f(0) f(0) 为,过轮廓中心点 ( u 0 , v 0 ) (u_0,v_0) (u0,v0) 的水平线与轮廓右侧的交点;采样方向,顺时针;匀速,每两个采样点的距离相同。

  • 由于实际应用中无法得到文本轮廓函数f的解析形式,可以将连续函数 f 离散为 N 个点,即 { f ( n N ) } \{f(\frac nN)\} {f(Nn)},其中 n ∈ [ 1 ; : : : ; N ] n\in [1;:::;N] n[1;:::;N]。此时,公式2中的ck可以通过傅里叶变换计算为:

    • c k = 1 N ∑ n = 1 N f ( n N ) e − 2 π i k n N ; ( 3 ) c_k =\frac 1 N\sum^N_{n=1} f(\frac n N )e ^{−2πik\frac n N} ; (3) ck=N1n=1Nf(Nn)e2πikNn;(3)

    • 其中 c k = u k + i v k c_k = u_k + iv_k ck=uk+ivk,uk 为实部,vk 为复数的图像部分。特别地,当 k = 0 时, c 0 = u 0 + i v 0 = 1 N ∑ n f ( n N ) c0 = u0 + iv0 =\frac 1 N \sum_n f(\frac n N) c0=u0+iv0=N1nf(Nn) 是轮廓的中心位置。对于任何文本轮廓 f,我们提出的傅里叶轮廓嵌入 (FCE) 方法可以在傅里叶域中将其表示为紧凑的 2(2K + 1) 维向量 [u−K; v−K; · · · ; u0; v0; · · · ; uK; vK],称为傅里叶签名向量。

  • 我们的 FCE 方法包含两个阶段,即重采样阶段和傅里叶变换阶段。具体而言,在重采样阶段,我们在文本轮廓上等距离采样固定数量 N(在我们的实验中 N = 400)个点,获得重采样点序列 { f ( 1 N ) ; ⋅ ⋅ ⋅ ; f ( 1 ) } \{f(\frac 1 N ); · · · ; f(1)\} {f(N1);⋅⋅⋅;f(1)}。请注意,这种重采样是必要的,因为不同的数据集对于文本实例具有不同数量的地面实况点,并且它们相对较小。 例如,CTW1500 中有 14 个,而 Total-Text 中有 4 ∼ 8 个。重采样策略使我们的 FCE 与具有相同设置的所有数据集兼容。在傅里叶变换阶段,重采样的点序列被变换为其对应的傅里叶信号向量

  • 傅里叶特征向量的唯一性。从上述FCE过程中不难看出,即使是相同的文本轮廓,不同的重采样点序列也会导致不同的傅里叶特征向量。为了使某一特定文本的特征向量唯一,使网络训练更加稳定,我们对f(t)的起点、采样方向和移动速度进行约束:

    • 起点:我们将起点 f(0)(或 f(1))设置为通过中心点 (u0; v0) 的水平线与文本轮廓的最右边的交点。
    • 采样方向:我们总是按照顺时针方向沿文本轮廓重新采样点。
    • 均匀速度:在文本轮廓上均匀地进行重采样点,并且每两个相邻点之间的距离保持不变,以保证均匀的速度。

FCENet

  • 利用FCE,我们进一步提出了用于任意形状文本检测的无锚网络FCENet。网络架构。我们提出的 FCENet 采用自上而下的方案。如图 3 所示,它包含 ResNet50 ,DCN 作为骨干,FPN 作为颈部以提取多尺度特征,以及傅里叶预测头。我们对 FPN 的特征图 P3、P4 和 P5 进行预测。头有两个分支,分别负责分类和回归。 每个分支由三个 3×3 卷积层和一个 1×1 卷积层组成,每个卷积层后跟一个 ReLU 非线性激活层。

    • 在这里插入图片描述

    • 图 3:所提出的 FCENet 的整体框架。给定一张图像,其由骨干和 FPN 提取的特征被输入到共享头中以检测文本。在头中,分类分支预测文本区域的热图和文本中心区域的热图,这些热图逐像素相乘,得到分类分数图。回归分支预测傅里叶特征向量,这些向量用于通过逆傅里叶变换 (IFT) 重建文本轮廓。给定具有相应分类分数的重建文本轮廓,使用非最大抑制 (NMS) 获得最终检测到的文本。

    • FCENet 的算法流程如图所示,输入图像会经过主干网络和 FPN 提取特征。FPN 上不同层负责不同尺度的文本目标,提取的特征会送入到共享的检测头中。共享的检测头具有两个分支,其中分类分支预测文本区域和文本中心区域的概率图,相乘得到属于文本中心分类的得分图;回归分支则负责预测傅里叶特征向量。算法对文本中心置信度大于阈值的像素点所对应的傅里叶特征向量进行傅里叶反变换,并经过非极大值抑制得到最终的检测结果。在模型训练阶段,由于不同频率分量对空间域上的包围框的影响是不均等的,FCENet 采用了在空间域计算损失的方法来实现回归分支上的损失均衡

    • 像大多数OCR算法一样,FCENet的网络结构大体可以分为backbone,neck,head三个部分。其中backbone采用可变形卷积版本的Resnet50用于提取特征;neck部分采用特征金字塔 ,特征金字塔是一组不同大小的卷积核,适用于提取原图中不同大小的特征,从而提高了目标检测的准确率,在一张图片中有不同大小的文本框的场景效果比较好;head部分有两条分支,一条是分类分支,用于预测文本区域和文本中心区域的热力图,通过比较该热力图与监督信号的交叉熵作为分类分支的损失值,另一条是回归分支,回归分支预测傅立叶特征向量,该向量用于通过傅立叶逆变换重构文本轮廓,通过计算重构文本轮廓线和监督信号的轮廓线在图像空间的smooth-l1 loss作为回归分支的损失值

    • 检测头由分类和回归两个分支组成,分类分支中,输出的结果通道数是4,前两个通道表示的是每个像素是否是文本区域(Text Region,TR)的概率,后两个通道表示的是每个像素是否是文本中心区域(Text Center Region)的概率,分类分支相当于是分割得到文本区域,然后求文本区域的轮廓中心

    • 回归分支的通道数 22,表示的是取傅里叶展开的自由度 k=5,取前5个高频和低频及 k=0 共 11 个复数傅里叶系数,复数使用 ( u k , v k ) (u_k,v_k) (uk,vk) 来表示,因此总共 22 个变量,通过使用傅里叶逆变换求得最后的检测结果

    • import numpy as np
      import matplotlib.pyplot as plt
      def generate_rectangle(width=100, height=50, noise_level=1):
          x = np.array([0, width, width, 0, 0])
          y = np.array([0, 0, height, height, 0])
          return add_noise(x, y, noise_level)
      def generate_curve(length=100, noise_level=1):
          t = np.linspace(0, 2 * np.pi, length)
          x = t * np.cos(t)
          y = t * np.sin(t)
          return add_noise(x, y, noise_level)
      def generate_circle(radius=50, noise_level=5):
          t = np.linspace(0, 2 * np.pi, 100)
          x = radius * np.cos(t)
          y = radius * np.sin(t)
          return add_noise(x, y, noise_level)
      def generate_heart(size=50, noise_level=10):
          t = np.linspace(0, 2 * np.pi, 100)
          x = size * 16 * np.sin(t)**3
          y = size * (13 * np.cos(t) - 5 * np.cos(2 * t) - 2 * np.cos(3 * t) - np.cos(4 * t))
          return add_noise(x, y, noise_level)
      def add_noise(x, y, noise_level):
          noise_x = np.random.normal(0, noise_level, x.shape)
          noise_y = np.random.normal(0, noise_level, y.shape)
          return x + noise_x, y + noise_y
      def fourier_transform(x, y):
          complex_pts = x + y * 1j
          ft_pts = np.fft.fft(complex_pts)
          return ft_pts
      def inverse_fourier_transform(ft_pts, num_freq):
          approx_ft_pts = np.zeros_like(ft_pts)
          approx_ft_pts[:num_freq] = ft_pts[:num_freq]
          approx_ft_pts[-num_freq:] = ft_pts[-num_freq:]
          appox_pts = np.fft.ifft(approx_ft_pts)
          return appox_pts.real, appox_pts.imag
      def plot_results(x, y, x_approx_list, y_approx_list, freq_list, title=""):
          plt.figure(num=1, figsize=(4,3), dpi=200)
          plt.plot(x, y, label='ground truth', linewidth=5 , alpha=0.5, color='black')
          for i, (x_approx, y_approx, num_freq) in enumerate(zip(x_approx_list, y_approx_list, freq_list)):
              plt.plot(x_approx, y_approx,
                       label=f'approx truth (degree: {num_freq})',
                       linewidth=i+1,
                       alpha=0.9-0.1*i,
                       color=colors[i%len(colors)],
              )
          plt.title(title, fontsize=10)
          plt.legend(fontsize=8)
          plt.show()
      def perform_ablation_study(x, y, freq_list):
          x_approx_list = []
          y_approx_list = []
          for num_freq in freq_list:
              ft_pts = fourier_transform(x, y)
              x_approx, y_approx = inverse_fourier_transform(ft_pts, num_freq)
              x_approx_list.append(x_approx)
              y_approx_list.append(y_approx)
          return x_approx_list, y_approx_list
      if __name__ == "__main__":
          colors = ['red', 'blue', 'purple', 'brown']
          # 生成不同形状的轮廓
          shapes = {
              "Rectangle": generate_rectangle,
              "Curve": generate_curve,
              "Circle": generate_circle,
              "Heart": generate_heart
          }
          freq_list = [1, 2, 4, 8]  # 减少消融实验的次数,只展示4个不同自由度的结果
          for shape_name, shape_func in shapes.items():
              x, y = shape_func()
              ft_pts = fourier_transform(x, y)
              x_approx_list, y_approx_list = perform_ablation_study(x, y, freq_list)
              plot_results(x, y, x_approx_list, y_approx_list, freq_list, f"Original {shape_name} with Different Fourier Degrees")
      
    • 在这个脚本中,傅里叶级数被用来拟合一组二维点集的轮廓线。具体来说,傅里叶变换将原始的点集数据从时域(或空间域)转换到频域,然后通过选择部分频域成分(高频和低频)来近似恢复原始轮廓。这种方法在信号处理和图像处理领域非常常见,可以用于压缩、去噪和特征提取等任务。傅里叶变换将时域(或空间域)信号转换为频域信号。对于二维点集,可以将点集的坐标转换为复数形式,然后进行傅里叶变换。傅里叶变换的公式为: [ F ( k ) = ∑ n = 0 N − 1 f ( n ) e − 2 π i k n / N ] [ F(k) = \sum_{n=0}^{N-1} f(n) e^{-2\pi i k n / N} ] [F(k)=n=0N1f(n)e2πikn/N];其中,( F(k) ) 是频域信号,( f(n) ) 是时域信号,( N ) 是信号的长度。逆傅里叶变换将频域信号转换回时域信号。通过选择部分频域成分(高频和低频)来近似恢复原始轮廓。逆傅里叶变换的公式为: [ f ( n ) = 1 N ∑ k = 0 N − 1 F ( k ) e 2 π i k n / N ] [ f(n) = \frac{1}{N} \sum_{k=0}^{N-1} F(k) e^{2\pi i k n / N} ] [f(n)=N1k=0N1F(k)e2πikn/N];其中,( f(n) ) 是时域信号,( F(k) ) 是频域信号,(N) 是信号的长度。

  • 在分类分支中,我们预测文本区域 (TR) 的逐像素掩码。我们发现文本中心区域 (TCR) 预测可以进一步提高性能。 我们认为这是因为它可以有效地过滤掉文本边界周围的低质量预测

  • 在回归分支中,对文本中的每个像素回归一个文本的傅里叶签名向量。为了处理不同规模的文本实例,P3、P4 和 P5 的特征分别负责小、中和大文本实例。检测结果将通过IFT和NMS从傅里叶域重建到空间域,如图4所示。

    • 在这里插入图片描述

    • 图 4:通过 IFT 和 NMS 对不同时间 t 的任意形状文本(红色表示真实值)进行傅里叶轮廓重建(蓝色)。

  • 真实值生成。对于分类任务,我们使用 [Textsnake: A flexible representation for detecting text of arbitrary shapes] 中的方法,通过收缩文本获得文本中心区域 (TCR) 掩码,收缩因子为 0.3(参见图 2 中的绿色掩码)。对于回归任务,我们通过提出的 FCE 方法计算真实值文本轮廓的傅里叶特征向量 c。请注意,对于一个文本实例的掩码中的所有像素,我们预测文本轮廓,因此需要一个傅里叶特征向量 c,其像素为复坐标系的 (0; 0) 点。同一文本实例中的不同像素除 c0 之外共享相同的傅里叶特征向量

  • 损失。FCE 基础网络的优化目标如下:

    • L = L c l s + λ L r e g L=L_{cls}+\lambda L_{reg} L=Lcls+λLreg

    • 其中 Lcls 和 Lreg 分别是分类分支的损失和回归分支的损失。λ 是平衡 Lcls 和 Lreg 的参数。我们在实验中固定 λ = 1。Lcls 由两部分组成:

    • L c l s = L t r + L t c r ; ( 5 ) L_{cls} = L_{tr} + L_{tcr}; (5) Lcls=Ltr+Ltcr;(5)

    • 其中 Ltr 和 Ltcr 分别是文本区域 (TR) 和文本中心区域 (TCR) 的交叉熵损失。为了解决样本不平衡问题,对 Ltr 采用 OHEM ,负样本与正样本的比例为 3:1。对于 Lreg,我们不会最小化预测的傅里叶特征向量与其对应的基本事实之间的距离。相反,我们最小化图像空间域中重建的文本轮廓,这与文本检测质量更相关。正式来说,

    • L r e g = 1 N ′ ∑ i ∈ T ∑ n = 1 N ′ w i l 1 ( F − 1 ( n N ′ ; c i ) ; F − 1 ( n N ′ ; c ^ i ) ) ; L_{reg} =\frac 1 {N'}\sum _{i\in T}\sum^{N'}_{n=1} w_i l_1(F ^{−1} (\frac n {N'} ; c_i); F ^{−1} (\frac n {N'} ; \hat c_i)); Lreg=N1iTn=1Nwil1(F1(Nn;ci);F1(Nn;c^i));

    • 其中 l1 是用于回归的 smooth-l1 损失 ,F −1 (·) 是等式 2 的 IFT。T 是文本区域像素索引集。ci 和 ^ci 分别是文本基本事实傅里叶特征向量和像素 i 的预测特征向量。如果像素 i 在其对应的文本中心区域,则 wi = 1,否则为 0.5。N’ 是文本轮廓上的采样数。如果 N’ 太小(通常 N’ < 30),可能会导致过度拟合。 因此,我们在实验中固定 N’ = 50。

  • 回归损失在我们的 FCENet 中非常重要。在第 4.4 节的消融研究中,结果表明它分别在 CTW 1500 和 Total-text 上带来了绝对 6.9% 和 9.3% 的 h 均值改进。

  • import numpy as np
    import cv2
    from numpy.fft import ifft
    class FCEPostprocessor(BaseTextDetPostProcessor):
        def __init__(self, **args):
            ...
    
        def _get_text_instances_single(self, pred_result: dict, scale: int):
            """
            从单个特征层级获取文本实例预测。
            参数: pred_result (dict): 包含 'cls_res' 和 'reg_res' 的字典,分别对应分类结果和回归结果, 它们的形状分别为  1, C_{cls,i}, H_i, W_i  和  1, C_{out,i}, H_i, W_i 。
                 scale (int): 当前特征图相对于原始图像的比例尺,等于 img_size / feat_size。
            返回: result_polys (list[ndarray]): 经过后处理的多边形列表。
                 result_scores (list[ndarray]): 经过后处理的得分列表。
            """
            # 解析分类预测结果并应用softmax函数,Softmax 函数用于将未归一化的分数转换为概率分布,确保所有类别的概率之和为1。
            cls_pred = pred_result['cls_res']
            # 对二分类结果应用softmax,得到TR(Text Region)概率图
            tr_pred = cls_pred[0:2].softmax(dim=0).data.cpu().numpy()
            # 对TCL(Text Center Line)结果应用softmax,得到TCL概率图
            tcl_pred = cls_pred[2:].softmax(dim=0).data.cpu().numpy()
    
            # 解析回归预测结果
            reg_pred = pred_result['reg_res'].permute(1, 2, 0).data.cpu().numpy() # 调整维度顺序以适应后续操作
            x_pred = reg_pred[:, :, :2 * self.fourier_degree + 1]   # 提取X方向的傅里叶系数
            y_pred = reg_pred[:, :, 2 * self.fourier_degree + 1:]   # 提取Y方向的傅里叶系数
    
            # 计算综合得分并生成掩码,通过乘幂运算结合两个不同来源的置信度,以增强或削弱某些区域的重要性;阈值化操作用来过滤低置信度区域。
            score_pred = (tr_pred[1] ** self.alpha) * (tcl_pred[1] ** self.beta)    # 结合TR和TCL的概率计算综合得分
            tr_pred_mask = (score_pred) > self.score_thr    # 根据阈值生成掩码
            tr_mask = fill_hole(tr_pred_mask)               # 填充孔洞以形成连通区域
    
            # 使用OpenCV找到轮廓,cv2.findContours 函数用于查找二值图像中的轮廓,这里用它来定位文本区域的边界。
            tr_contours, _ = cv2.findContours( tr_mask.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # opencv4
            mask = np.zeros_like(tr_mask)
            result_polys = []
            result_scores = []
            # 使用复数表示二维坐标是为了方便后续的傅里叶逆变换;更新中心频率项是为了让傅里叶系数代表正确的几何位置;NMS 是一种消除冗余检测框的技术。
            for cont in tr_contours:
                deal_map = mask.copy().astype(np.int8)
                # 在新掩码上绘制当前轮廓
                cv2.drawContours(deal_map, [cont], -1, 1, -1)
                # 应用掩码获取当前轮廓内的得分
                score_map = score_pred * deal_map
                # 获取得分非零位置的掩码
                score_mask = score_map > 0
                # 找到所有满足条件的位置坐标
                xy_text = np.argwhere(score_mask)
                # 将坐标转换为复数形式表示偏移量
                dxy = xy_text[:, 1] + xy_text[:, 0] * 1j
                # 获取当前轮廓内有效的傅里叶系数
                x, y = x_pred[score_mask], y_pred[score_mask]
                # 将傅里叶系数合并成复数形式
                c = x + y * 1j
                # 更新中心频率项以反映实际位置
                c[:, self.fourier_degree] = c[:, self.fourier_degree] + dxy
                # 按比例缩放以映射回原始图像尺寸
                c *= scale
                # 从傅里叶系数重建多边形
                polygons = self._fourier2poly(c, self.num_reconstr_points)
                # 获取与多边形对应的得分
                scores = score_map[score_mask].reshape(-1, 1).tolist()
                # 应用NMS去除重叠的多边形
                polygons, scores = self.poly_nms(polygons, scores, self.nms_thr)
                result_polys += polygons
                result_scores += scores
            result_polys, result_scores = self.poly_nms(result_polys, result_scores, self.nms_thr)
    
            if self.text_repr_type == 'quad':
                new_polys = []
                for poly in result_polys:
                    poly = np.array(poly).reshape(-1, 2).astype(np.float32)
                    points = cv2.boxPoints(cv2.minAreaRect(poly))   # 获取最小外接矩形的四个顶点
                    points = np.intp(points)
                    new_polys.append(points.reshape(-1))
                return new_polys, result_scores
            return result_polys, result_scores
    
        def _fourier2poly(self,
                          fourier_coeff: np.ndarray,
                          num_reconstr_points: int = 50):
            """
            逆傅里叶变换,
            参数: fourier_coeff (ndarray): 形状为 (n, 2k+1) 的傅里叶系数数组,其中 n 是候选数量,k 是傅里叶阶数。
                 num_reconstr_points (int): 重构后的多边形点的数量,默认为50。
            返回: List[ndarray]: 重构后的多边形列表。
            """
            # 初始化逆傅里叶变换输入矩阵,构造一个适合进行离散傅里叶逆变换的复数矩阵,通过填充正负频率成分来保证周期性。
            a = np.zeros((len(fourier_coeff), num_reconstr_points), dtype='complex')
            k = (len(fourier_coeff[0]) - 1) // 2
            a[:, 0:k + 1] = fourier_coeff[:, k:]
            a[:, -k:] = fourier_coeff[:, :k]
            # 执行逆傅里叶变换,ifft 函数执行离散傅里叶逆变换,将频域数据转换为空间域数据,并乘以 num_reconstr_points 来还原尺度。
            poly_complex = ifft(a) * num_reconstr_points
            # 分离实部和虚部作为多边形点坐标
            polygon = np.zeros((len(fourier_coeff), num_reconstr_points, 2))
            polygon[:, :, 0] = poly_complex.real
            polygon[:, :, 1] = poly_complex.imag
            return polygon.astype('int32').reshape(
                (len(fourier_coeff), -1)).tolist()
    
    • 核心在于利用傅里叶变换将复杂的曲线简化为少量的频率成分(即傅里叶系数),然后在需要时再通过逆傅里叶变换恢复出原始曲线。这种方法可以有效地压缩信息并且便于模型训练。同时,为了确保最终输出的是有意义的几何形状,还需要进行一系列的几何变换和筛选操作,比如 NMS 和最小外接矩形计算。这些技术共同作用,使得可以从神经网络的输出中准确地提取出文本区域的多边形表示。

Experiments

  • 在本节中,我们首先验证了 FCE 对文本实例建模的有效性,并与两种近期 SOTA 任意形状文本表示方法(即 TextRay 和 ABCNet )进行了比较。然后,我们评估了 FCENet 的文本检测能力。具体来说,我们对每个组件的有效性以及通过减少训练数据进行的泛化能力进行了消融研究;我们还在 CTW1500 和 Total-Text 基准上与近期 SOTA 方法进行了广泛的比较。由于这些基准数据集还包含大量非弯曲文本,我们构建了一个更具挑战性的子集,其中包含高度弯曲或高度不规则的文本以供进一步评估

Datasets

  • CTW1500 包含带有文本行级注释的英文和中文文本,其中 1000 张图像用于训练,500 张图像用于测试。
  • Total-Text 是从各种场景中收集的,包括类似文本的背景杂乱和低对比度文本,具有词级多边形注释,其中 1255 张图像用于训练,300 张图像用于测试。
  • ICDAR2015 是一个多方向街景数据集,包含 1000 张训练图像和 500 张测试图像。注释是单词级别的,有四个顶点。

Implementation Details

  • FCENet 的主干包含带有 DCN 和 FPN 的 ResNet50,如图 3 所示。回归和分类分支均由三个 3×3 卷积层和一个 1×1 卷积层组成,其核数设置为 [128; 64; 32; 32]。P3、P4 和 P5 的文本尺度范围分别设置为图像尺寸的 [0; 0.4]、[0.3; 0.7] 和 [0.6; 1],其中重叠范围是为了提高召回率。

  • 将图片缩放至 800 × 800,并在训练过程中采用数据增强策略,包括随机裁剪、随机旋转、随机水平翻转、颜色抖动和对比度抖动。使用两块 2080Ti GPU 训练模型,批量大小设置为 8。采用随机梯度下降 (SGD) 作为优化器,权重衰减为 0.001,动量为 0.9。初始化学习率为 0.001,每 200 个 epoches 减少 0.8 倍。

  • 测试时,图片大小调整如下:对于CTW1500,我们先将图片的短边调整为640,如果结果图像的长边大于1280,则将其调整为1280。对于Total-Text,我们先将图片的短边调整为960,如果结果图像的长边大于1280,则将其调整为1280。对于ICDAR2015,我们保持原方向,将长边调整为2020。之前比较的方法都是用开源代码实现的,并且一些方法在MindSpore平台上进行了测试。

Evaluation of FCE

  • 基本评估。理论上,任何封闭的连续轮廓都可以通过增加FCE的傅里叶阶数 K 得到更好的近似,从而得到傅里叶轮廓的拟合效果。图5的结果表明,对于大多数任意形状的文本,只需较小的K就可以得到满意的拟合,这证明了FCE强大的表示能力。

    • 在这里插入图片描述

    • 图 5:随着傅里叶阶数 K 的增加,对任意形状文本进行傅里叶轮廓拟合,其中绿色轮廓表示真实值;红色轮廓表示 FCE 拟合结果。

  • 比较。为了验证 FCE 对文本实例建模的有效性和稳健性,我们将其与最近的 SOTA 任意形状文本检测器 TextRay 进行了比较。图 6 的结果表明,对于高度弯曲的文本,TextRay 无法与 GT 紧密贴合,而我们的 FCE 获得了准确的近似值。请注意,我们的 FCE 仅使用 22 维参数,而 TextRay 使用了 44 维参数,是我们的 2 倍

    • 在这里插入图片描述

    • 图 6:不同文本表示在轮廓拟合能力方面的比较。绿色轮廓表示真实值,红色轮廓表示拟合结果。

Evaluation of FCENet

  • 消融研究。为了评估 FCENet 组件的有效性,我们对 CTW1500 和 Total-Text 数据集进行了消融研究,如表 2 所示。 结果表明,分类分支的文本中心区域 (TCR) 损失和回归分支的建议回归损失(等式 6)可以显著提高 FCENet 的性能。

    • 在这里插入图片描述

    • 表 2:消融研究。在等式 6 中,“TCR”表示文本中心区域损失,“RL”表示回归损失。

  • 泛化能力。得益于 FCE 表示,FCENet 只需要简单的 IFT 和 NMS 后处理即可重建复杂的文本轮廓。 此外,FCE 可以生成紧凑的文本表示,这使得我们的 FCENet 与 SOTA 方法相比具有更好的泛化能力。我们在 CTW1500 数据集上使用不同数量的训练数据与 DRRG 、TextRay 、ABCNet 和我们提出的 FCENet 进行了比较,如表 3 所示。

    • 在这里插入图片描述

    • 表 3:使用不同量训练数据在 CTW1500 上进行的泛化能力评估。

  • 结果表明,当训练数据减少到原来的 50% 和 25% 时,其他方法的性能会急剧下降。相比之下,我们的 FCENet 保持了良好的准确率,准确率、召回率、精确率和 F 值均超过 73%(精确率甚至保持在 80% 以上)。结果表明我们的 FCENet 具有良好的泛化能力,并展示了我们的方法的广泛应用潜力,特别是在训练样本有限的实际场景中。

Evaluation on Benchmark Datasets

  • 我们对不同数据集上的最新 SOTA 方法进行了广泛的比较,如表 1 所示。结果表明,我们的 FCENet 在任意形状文本的 CTW1500 和 Total-Text 数据集上获得了最佳的精度 § 和 F 度量 (F) 性能,并在召回率 ® 方面取得了具有竞争力的性能。请注意,除了 ContourNet 之外,大多数先前的方法都需要额外的训练数据才能获得最佳性能,但我们的 FCENet 无需额外设置即可进行训练。在多方向和街景文本的 ICDAR15 数据集上,FCENet 也无需额外设置即可获得具有竞争力的结果。

  • 此外,FCENet 的网络架构简单,后处理高效(即 IFT 和 NMS),因此易于实现且非常实用。请注意,即使 FCENet 使用 ResNet50 作为主干,而没有 DCN(其主干与 ABCNet 相同),它仍然在表 1 中的不同数据集上获得了有竞争力的结果。

    • 在这里插入图片描述

    • 表 1:与 CTW1500、Total-Text 和 ICDAR2015 上相关方法的比较,其中 ’Ext.’ 表示额外的训练数据,’FCENet†’ 表示使用 ResNet50 作为主干而不使用 DCN 的 FCENet。

Evaluation on Highly-curved Subset

  • 由于 CTW1500 仍包含大量非弯曲文本,我们从中选择了高度弯曲的文本来构建一个具有挑战性的子集。我们对最新的具有明确文本形状建模的方法(即 TextRay 和 ABCNet)进行了比较。

  • 为了构建具有挑战性的子集,我们丢弃了“简单”的非弯曲文本,但保留了高度弯曲的文本。我们利用一种算法来选择子集(总共 106 个样本),基于这样的观察:当我们删除除头部和尾部之外的一个地面真实注释点时,高度弯曲的文本的面积将发生很大变化。我们计算了在删除 GT 注释中的一个点之前和之后的注释多边形的面积,并根据 ∣ A b e f − A a f t ∣ = A b e f ≥ 0.07 |A_{bef} − A_{aft}|=A_{bef} ≥ 0.07 AbefAaft=Abef0.07 来选择样本。定性和定量比较分别如图 7 和表 4 所示。结果表明,FCE 在显式建模不规则文本实例方面与 TextRay 和 ABCNet 相辅相成,同时也证明了 FCENet 在高度弯曲文本检测方面的有效性。

    • 在这里插入图片描述

    • 图 7:在 CTW1500 中选定的具有挑战性的样本上与 TextRay 和 ABCNet 进行定性比较。

    • 在这里插入图片描述

    • 表 4:CTW1500 高度弯曲文本子集的定量比较。“Ext.”表示额外的训练数据。

Conclusion

  • 本文重点研究了任意形状文本检测的显式形状建模。我们提出了傅里叶轮廓嵌入方法,可以准确近似任何封闭形状。然后,我们提出了 FCENet,它首先在傅里叶域中预测文本实例的傅里叶特征向量,然后通过逆傅里叶变换在图像空间域中重建文本轮廓点序列。FCENet 可以以端到端的方式进行优化,并且无需任何复杂的后处理即可实现。对提出的 FCE 和 FCENet 进行了广泛的评估。实验结果验证了 FCE 的表示能力,尤其是在高度弯曲的文本上,以及 FCENet 在用小样本训练时的良好泛化能力。此外,它表明 FCENet 在 CTW1500、Total-Text 上实现了 SOTA 性能,并在 ICDAR2015 上取得了有竞争力的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羞儿

写作是兴趣,打赏看心情

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值