UI2CODE智能生成代码——组件识别篇

1.背景

《UI2CODE——总体设计篇》中,咱们介绍了UI2CODE工程的总体流程:算法

在组件识别这个环节,须要有一种处理布局信息的方法,来解析和计算控件间的布局关系(好比识别业务组件(BI组件)和查找重复布局),以此来提升最终代码的可用性。数组

在这篇文章,咱们将介绍一种布局信息的结构化方法:“连线法”,以及一种布局间的计算和比较方法: “引导连线法”数据结构

首先来看咱们须要解决的问题:布局

2.问题一:识别业务组件

目的:代码复用

业务组件是指某些特定的卡片,好比一个商品详情卡片,这些卡片会在不一样页面出现,而这些卡片的代码通常是已经存在的。咱们在拿到一张图片的时候,须要先识别出这些组件,这样这一区块就能复用已有的组件代码,而不会形成不少冗余的一次性代码。学习

老解法:利用深度学习模型SSD作物体检测

若是把寻找业务组件这个问题当作从一张大图片上寻找小图片的话,那么最直接的作法就是用一个物体检测模型(好比SSD)来作,这样只要训练模型来识别每一个业务组件的图片就能够了。所以咱们尝试了用训练SSD模型来解决这个问题。测试

存在的问题:训练困难,训练结果不可控

通过训练和测试之后,咱们发现用物体检测模型来解这个问题的弊端:优化

  1. 须要造大量样本。因为图片信息丰富,为了不过拟合,须要造大量样原本训练。
  2. 训练困难,增长新的业务组件成本过高。每增长一个新的业务组件,就须要先造这个组件的样本,而后从新调整训练模型。
  3. 训练结果不可控。对于一些badcase,没有一些直接有效的方式来作调整和控制,只能不断调整样本。

思考:是否能够利用已有的控件信息?

既然前面已经解析出了各个控件的信息(包含类型以及位置等),那么咱们是否能够直接利用这些信息来作处理呢?所以咱们想要寻找一种新的方式,来处理和解析控件信息,利用这些信息来实现相似“物体检测”功能spa

3.问题二:重复布局

目的:提高代码可用性

如上图这个case,对于相似“GridView”的这种布局,咱们理想的布局方式应该是有8个Item,每一个Item包含一个TextView和ImageView(上图左边)。设计

存在的问题:没有识别出重复布局,最终代码不可用

然而实际状况是,咱们没有作重复布局的检测,所以布局的时候变成了4行(上图右边)。3d

思考:如何比较布局是否重复?

为了解决上面的问题,咱们就须要寻找一种方法,从多个控件信息中,找到一些规律,自动找到这些具备类似状况的布局。

4.问题分析

以上就是咱们须要解决的两个问题,咱们分析这两个问题,会发现他们有一些共同点:

  1. 都是由多个控件组成大的布局
  2. 布局间须要进行比较,寻找“类似布局”
  3. 都是非结构化数据:没法直接比较、计算

5.解决思路

首先咱们须要将非结构化数据转换为结构化数据(或者叫特征提取),这个思路能够参考图片分类任务的作法,不论是聚类算法仍是AI模型,都是先作特征提取,再进行进一步处理,实际上作的就是非结构化数据转换成结构化数据。

所以,咱们的问题解决思路也就分为两步:

  1. 布局信息结构化:将布局信息处理成结构化的数据
  2. 布局比较:对布局进行比较、计算,寻找类似布局

6.布局结构化:控件间的关系

为了分析控件间的关系,咱们能够先从简单的开始,看一下两个控件之间的关系都包含哪些信息。

两个控件间的关系,包含如下2个方面的信息:

  1. 控件属性(类型、文本内容、位置、大小)
  2. 方向、距离、对齐方式(用连线表达)

控件属性:

对于控件属性,能够直接用它自身表示,包含控件类型、内容、位置、大小等

方向和距离:

对于两个控件的方向和距离,咱们能够用一条虚拟的“连线”来表示,这条连线链接两个控件的中心点。这样,这条连线的长度和角度就能够表示两个控件的方向和距离。好比上图,咱们能够获得:一个TextView在一个ImageView正上方,距离xxx像素。

对齐方式:

可是除了角度和方向,实际上还存在着一个“对齐方式”信息。

好比上图这个case,若是咱们仍是链接两个控件的中心点的话(图中蓝色虚线),那这左右两边的图就是指不一样的布局(由于两个控件的角度和距离都不同)。

可是由咱们人“肉眼”来看,咱们会认为这两个布局是同样的,都是左边一个头像,右边上面跟着一个文本。

所以,咱们须要链接TextView的“左边中点”(图上红色实线),这样,不一样的链接点位置,就能够表达不一样的对齐方式。左对齐的TextView链接左边中点,右对齐的TextView链接右边中点,居中的链接中心点。

定义数据结构

有了上面的分析,咱们就能够定义一个数据结构。咱们用一个Connection对象表达2个控件间的布局关系,它包含:

  1. 控件1属性(类型、位置大小等)
  2. 控件2属性(类型、位置大小等)
  3. 控件1和控件2间的多条连线(角度、距离)

这样,2个Connection之间就能够进行比较、判断是否“匹配”

Connection匹配计算

两个Connection之间是否“匹配”,必须知足:

  1. 控件信息匹配(类型一致、ImageView面积类似度知足要求等)
  2. 方向和距离匹配(连线的余弦类似度)
  3. 其它自定义的匹配要求

7.布局结构化:整个布局的表示

两个控件间的关系能够用一个Connection来表示,那么多个控件组成的大布局,就能够用一组Connection来表示。

咱们对每两个控件创建一个Connection,就能够获得一个Connection数组

这样,咱们的第一步“布局信息结构化”就完成了。

8.布局间比较:引导连线法

将布局信息转换成Connection数组之后,咱们就能够开始利用这些信息来查找类似布局。

首先,咱们能够理解这样一个概念,就是:

一个布局,能够当作由一组Connection对象串联起来,获得的一个“路径”


如上图,蓝色圈内的布局能够当作一组Connection串联起来(红色连线)。

那么,寻找类似布局,就是寻找两条类似“路径”的过程

引导连线法

为了寻找类似路径,咱们定义了一个“引导连线法”。

所谓“引导连线法”,就是一个 Leader,一个 Follower,Follower 尝试着跟随 Leader 走出一条同样的路径。

步骤以下:

  1. 计算出全部相互匹配的Connection(以下图全部绿色的连线)
  2. 定义一个“Leader”叫A,一个 “Follower” 叫B
  3. 随机选择一条绿色连线做为A的初始路径,与其相匹配的另外一条绿色连线做为B的初始路径
  4. A尝试着继续往前走,找到下一个路径(绿色连线),B尝试着跟随
  5. 若是B能跟的上(即找到了一条路径,恰好与A想走的路径匹配上),那么A继续往下走,若是B跟不上,那么A换条路径继续尝试。
  6. 直到A走的路径B怎么也跟不上时,A和B走过的路径所对应的那些控件,就是拥有类似布局的控件。

9.应用效果

有告终构化的方法和“引导连线法”,咱们就能够应用到上述两个问题。

业务组件

应用方式

  1. 对业务组件进行结构化处理(图左红色连线)
  2. 对待处理图片进行结构化处理
  3. 找到他们之间能够“匹配”的Connection(图右绿色部分)
  4. 用“引导连线法”找到类似的布局

效果

应用这套算法之后,扩展要识别的组件变得很是简单,只要把新组件的的结构化数据预先计算好存储起来,在查找的时候应用”引导连线法“便可。

重复布局

应用方式

查找重复布局步骤以下:

  1. 计算自身全部控件的Connection
  2. 寻找自身Connection中,互相匹配的 Connection

  1. “引导连线”法寻找匹配的布局“pair”

​​​​​​​

  1. 多个“pair”串联组成一个重复布局

  1. 继续尝试对重复布局的每一个Item作拆分,可获得“GridView”

这样,最终咱们就能够找到,图上有8个布局类似的Item。

效果

应用这套算法,能够查找出页面上任意的重复布局,不管是简单的仍是复杂的,极大得提高了代码的可用性。

10.结语

以上就是咱们针对布局信息的处理和计算的总体思路。固然其中还有不少复杂细节须要处理,好比类似布局类似度计算、重复布局多个“pair”组合起来的时候组合条件的判断、重复布局其它额外信息的提取等。可是整体上都是围绕着“布局信息结构化”和“引导连线法展开”,咱们也在不断的继续探寻和持续优化各个环节。


原文连接 本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索