辨识手写中文字时,若图档内中文字迹有部分缺失,或是油墨泄漏造成字迹脏污,可能导致模型辨识错误,如下图。
训练影像辨识模型时,总不可避免地面临过拟合的情形,影响辨识效果。通常第一个想到的方法就是增加训练样本,以影像处理进行Data Augmentation,亦属於此列。
我们希望在资料前处理时,针对train资料集的图档加入椒盐杂讯,同时进行Data Augmentation,1张图档转变成4张,降低上述两点发生的可能性。
椒盐杂讯(Salt&Pepper Noise):分成盐噪音与胡椒噪音,盐噪音代表白色噪块(0)、胡椒噪音代表黑色躁块(255),当两者同时出现在图像上,会呈现黑白杂点,如下图。
图片来自於:https://blog.csdn.net/u011995719/article/details/83375196
Data Augmentation
2.1 读取中文路径图档
import os
import cv2
import numpy as np
import random
from itertools import product
# 读取图档
def cv_imread(filePath):
cv_img = cv2.imdecode(np.fromfile(filePath,dtype=np.uint8),-1)
return cv_img
2.2 生成椒盐杂讯
# 随机生成椒盐讯号
def random_mask(filename):
# 读取图档
img = cv_imread(filename)
img_high = img.shape[0]
img_width = img.shape[1]
# 将图档高度分成5等分
img_high1, img_high2, img_high3, img_high4 = round(img_high*0.2), round(img_high*0.4), round(img_high*0.6), round(img_high*0.8)
img_high_list = [0, img_high1, img_high2, img_high3, img_high4]
# 将图档长度分成5等分
img_width1, img_width2, img_width3, img_width4 = round(img_width*0.2), round(img_width*0.4), round(img_width*0.6), round(img_width*0.8)
img_width_list = [0, img_width1, img_width2, img_width3, img_width4]
# 切割成5*5个区块
combine = list(product(img_high_list, img_width_list))
# 随机抽取3个(取後不放回)
masks = random.sample(combine, 3)
print('masks:', masks)
print('shape', img.shape)
# mask
mask_high = round(img_high/5)
mask_widght = round(img_width/5)
for i in masks:
# y是宽,x是高
(x, y) = i
top_left = (y, x)
bottom_right_widght = y + mask_widght
bottom_right_high = x + mask_high
if y + img_width * 0.2 > img_width :
bottom_right_widght = img_width
if x + img_high * 0.2 > img_high:
bottom_right_high = img_high
bottom_right = (bottom_right_widght, bottom_right_high)
print('top_left', top_left)
print('bottom_right', bottom_right)
# 产生黑、白躁点(黑色躁点为0、白色躁点为255)
# cv2.rectangle(img, top_left, bottom_right, 255, -1)
cv2.rectangle(img, top_left, bottom_right, 0, -1)
print('-' * 20)
return img
2.3 显示mask成果
# 显示图档
def show_img(name, img):
cv2.namedWindow(name, cv2.WINDOW_NORMAL)
cv2.resizeWindow(name, 160, 120)
cv2.imshow(name, img)
cv2.waitKey()
2.4 将1张图档资料扩增成4张,并另存新档
if __name__ == '__main__':
# 图档路径
src_dir_name = './train/'
target_dir_name = './test/'
# 随机生成椒盐讯号,并另存新档
for i in os.listdir(src_dir_name):
sub_folder = src_dir_name + i + '/'
for i in os.listdir(sub_folder):
print(sub_folder+i)
# 生成3张有椒盐讯号的新图档
img1 = random_mask(sub_folder+i)
img1 = cv2.resize(img1, (160, 120), interpolation=cv2.INTER_CUBIC)
img2 = random_mask(sub_folder+i)
img2 = cv2.resize(img1, (160, 120), interpolation=cv2.INTER_CUBIC)
img3 = random_mask(sub_folder+i)
img3 = cv2.resize(img1, (160, 120), interpolation=cv2.INTER_CUBIC)
# 将新增随机椒盐杂讯後的图档另存新档
cv2.imencode('.jpg', img1)[1].tofile(sub_folder+'1_'+i)
cv2.imencode('.jpg', img2)[1].tofile(sub_folder+'2_'+i)
cv2.imencode('.jpg', img3)[1].tofile(sub_folder+'3_'+i)
print('=' * 50)
show_img('name', img1)
让我们继续看下去...
>>: 连续 30 天 玩玩看 ProtoPie - Day 6
不怎麽重要的前言 上一篇我们学会怎麽创建档案,也运行了我们的第一个程序,接下来会介绍上次的程序码,分...
2021.9.3更新: 调整了一些block scope的叙述。 Scope 的定义 scope ...
自己做行销的时候,很喜欢玩数据, 数据可以打破一些先入为主的想法、 也可以给我们更全面的视角、或是新...
本文介绍 Projucer 建立的 GUI Application 框架基本架构。框架(Framew...
我们在前面的时候有提过 interface 是用来定义物件的型别,对物件的形状进行描述。在物件导向程...