[需求分析] 淺談圖片進行個資遮蔽

承續先前說的 [設計模式] 淺談長文本個資遮蔽設計

長文本PII完成後, 可再加上地端Azure AI智慧文件來進行圖片遮蔽
先列出SA規格:

  1. 如果未選擇偵測項目, 自動偵測台灣常用個資項目
  2. 上行傳入圖片, 下行回傳已遮蔽JPEG格式圖片
  3. 可選擇遮蔽顏色、回傳圖片壓縮率、是否二次遮蔽

依以上需求再進一步分析拆解出SD規格
首先要送到AI 智慧文件來進行OCR, 由於地端只有v3.1, 實測效果沒有雲端這麼好, 
尤其是手寫字, 容易直接被當圖畫忽略掉, 但是個資無法上雲的限制下, 也只能接受了!
研究了一下v3.1回傳的結果, 有

  1. content: 全篇OCR的字串
  2. pages: 每頁資訊, 本文會用到的是words: 從左上到右下列出每字位置及長度及座標, 另外還有每行資訊, 因為個資可能跨行, 每行丟PII會不準確
  3. paragraphs: 每段資訊, OCR會自動幫你分段, 但判斷分段不是很準確

經過考量之後, 採用content和words來進行PII及圖片遮蔽
前文提到, 實作長文本丟到PII後, 也能回傳完整Enitity, 內容包含偵測到的字和在字串的index及length, 
理論上PII回傳的Enitity是依index順序排列, 但經過長文本切割時有重疊,
難保不會第二個字串的Enitity在第一個字串的Entity前面, 所以, 必須作排序及加工Entity:

  1. 取得所有document下的enitity
  2. 將所有enitity的offset重新計算加上id (前文有提到, 我在id放本字串在全文的index), 換成真正的index
  3. 如果有enitity的offset是相同的, 可能是重疊字串有偵測到個資, 只取用length長的那個entity
  4. 依offset排序

取得OCR的結果後, 直接將content丟PII, 再取得PII的結果, 這時就要來找出要遮蔽的圖上座標:

  1. 由於OCR結果的word和PII結果的entity已依上文說的都排序好了, 所以只要一層迴圈, 就能對雙方陣列進行比對
  2. 這時就要研究一下word會有什麼內容, word內, 只會有一個中文字、一個英文單字或一串代碼/電話/Email, 
    並且, 在實際畫出來時有遇到一個問題, 就是全形字的座標, 只占了半個字母寬度, 也就是說全形字都會遮不滿, 
    因此, 全形字的座標要另外處理
  3. word是全文資料, 所以對word跑迴圈, 一一比對是否符合entity, 要考量到的是, 
    word頭到尾的位置, 是否和entity頭到尾位置重疊, 就算只有部份重疊, 也要取得座標
  4. 判斷重疊的邏輯是entity頭≤word尾&entity尾≥word頭, 如果word頭>entity尾, 
    表示查看entity在全文的位置已經過了, 要改比對下一個entity
  5. 座標要依全半形字分別用List收集, 只要判斷word內只有一字就當全形字

二次遮蔽:

  1. 長文本內有提到二次遮蔽後, 要還原字串, 也有提到要重算entity的offset和index, 而重算的entity就能用來繪圖
  2. 作法同找出要遮蔽的圖上座標

接下來就是在原圖畫上填滿區塊:

  1. 先把半形字依取得座標畫上填滿區塊
  2. 全形字不直接改座標, 這裡的作法就看人了. 圖片可能斜個n度, 不易重算加寬的範圍, 
    所以我直接在填滿區塊外再加個框, 框的粗細要多少呢? 隨便抽幾個出來, 假設全文的全形字大小都一樣,  
    因為寧可多遮一點也不要沒遮到, 我是直接選長/寬擇大者來平均再* 加權數值 (0.5~1之間, 實務上要自己測試選哪個值) 當作框粗細
  3. 另一種作法, 針對每個字算其框的粗細, 如果使用SkiaSharp來畫, 可以在迴圈內畫範圍的同時計算框粗,就不用另外跑迴圈
  4. 依全形字座標畫帶粗框的填滿區塊
  5. 最後就看你要轉回什麼格式的圖片, 一般是用JPEG格式, 高品質的壓縮率為85以上

 

這張圖的遮蔽效果:

原圖
 遮蔽後

Taiwan is a country. 臺灣是我的國家