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」組合起來的時候組合條件的判斷、重複佈局其它額外信息的提取等。可是整體上都是圍繞着「佈局信息結構化」和「引導連線法展開」,咱們也在不斷的繼續探尋和持續優化各個環節。


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索