iT邦幫忙

2021 iThome 鐵人賽

DAY 27
0
AI & Data

手寫中文字之影像辨識系列 第 27

【第27天】探討與改善-增加訓練樣本(二)

摘要

  1. 作業流程
  2. OpenCV合成新訓練集
    2.1 讀取中文路徑圖檔
    2.2 顯示圖檔
    2.3 侵蝕圖檔白色區域
    2.4 圖檔前處理
    2.5 手寫中文字旋轉
    2.6 前後景影像疊加,並儲存圖檔
  3. 影像合成示意圖
  4. 成果

內容

  1. 作業流程(今日進度為1.4)

  2. OpenCV合成新訓練集

    2.1 讀取中文路徑圖檔(圖片讀取為BGR)

    import cv2
    import numpy as np
    import random
    
    def cv_imread(filePath):
        cv_img = cv2.imdecode(np.fromfile(filePath, dtype=np.uint8), -1)
        return cv_img
    

    2.2 顯示圖檔:用於觀察影像處理的過程。

    def show_img(name, img):
        cv2.namedWindow(name, cv2.WINDOW_NORMAL)
        cv2.resizeWindow(name, 160, 160)
        cv2.imshow(name, img)
        cv2.waitKey()
    

    2.3 侵蝕圖檔白色區域:用於加粗手寫中文字。

    def my_erode(img):
        kernel = np.ones((3, 3), np.uint8)
        new_img = cv2.erode(img, kernel, iterations=1)
        return new_img
    

    2.4 圖檔前處理

    • 空白圖片(背景)
    def back(filePath, target_size):
        img = cv_imread(filePath)
       img = cv2.resize(img, target_size)
        return img
    
    • 手寫中文字圖片(前景):
      • 以my_erode加粗中文字體,
      • 以高斯平滑,減少文字邊緣出現鋸齒狀。
    def font(filePath, target_size):
        img = cv_imread(filePath)
        img = cv2.resize(img, target_size)
        # 字體加粗
        img = my_erode(img)
        # 取高斯平滑
        img = cv2.GaussianBlur(img, (3, 3), 0)
        show_img('img2', img)
        return img
    

    2.5 手寫中文字旋轉:前景旋轉正負10度。

    def rotation(img, target_size, clockwise, scale):
        # 旋轉中心
        center = (target_size[0] // 2, target_size[1] // 2)
        # 旋轉角度
        angle = random.randint(clockwise[0], clockwise[1])
        # 圖檔旋轉
        M = cv2.getRotationMatrix2D(center, angle, scale)
        img = cv2.warpAffine(img, M, target_size, borderValue=(255, 255, 255))
        show_img('img2_rotaion', img)
        return img
    

    2.6 前後景影像疊加,並儲存圖檔

    def font_and_back(img1, img2):
        # 在空白背景上定義初始ROI位置
        rows, cols, channels = img2.shape
        roi = img1[0:rows, 0:cols]
    
        # 手寫中文字轉換成灰階圖
        img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
        show_img('img2gray', img2gray)
    
        # 將灰度值二值化,得到ROI區域掩模
        ret, mask = cv2.threshold(img2gray, 200, 255, cv2.THRESH_BINARY)
        show_img('mask', mask)
    
        # ROI掩模區域黑白反轉
        mask_inv = cv2.bitwise_not(mask)
        show_img('mask_inv', mask_inv)
    
        # ROI掩模顯示空白背景
        img1_bg = cv2.bitwise_and(roi, roi, mask=mask)
        show_img('img1_bg', img1_bg)
    
        # ROI掩模顯示手寫中文字
        img2_fg = cv2.bitwise_and(img2, img2, mask=mask_inv)
        show_img('img2_fg', img2_fg)
    
        # 空白背景與手寫中文字影像疊加
        dst = cv2.add(img1_bg, img2_fg)
        img1[0:rows, 0:cols] = dst
        show_img('res', img1)
        return img1
    
    if __name__ == '__main__':
        target_size = (80, 80)
        img1 = back('./8_辰.jpg', target_size)
        img2 = font('./丁_47.png', target_size)
        img2_rotaion = rotation(img2, target_size, (-10, 10), 1)
        result = font_and_back(img1, img2)
    
        # 儲存新樣本
        cv2.imencode('.jpg', result)[1].tofile('./丁_n_1.jpg')
        print("成功儲存圖片")
    
  3. 影像合成示意圖:影像處理順序由左至右,由上而下。

    3.1 前景代表手寫中文字;後景代表空白背景。

    3.2 前景、前景旋轉

    3.3 前景灰階、前景二值化

    3.4 前景黑白反轉、掩模顯示後景

    3.5 掩模顯示前景、前後景影像疊加

  4. 成果


小結

下一章,目標是:「分享如何處理資料類別不平衡的問題」。

讓我們繼續看下去...


參考資料

  1. 2021 年玉山銀行中文手寫影像辨識競賽作法分享,以及手寫文字圖片合成基本教學
  2. [Python+OpenCV] 影像侵蝕 erode 與影像膨脹 dilate

上一篇
【第26天】探討與改善-增加訓練樣本(一)
下一篇
【第28天】探討與改善-資料不平衡(一)
系列文
手寫中文字之影像辨識31

尚未有邦友留言

立即登入留言