[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

admin 2023年12月5日20:00:49评论9 views字数 23591阅读78分38秒阅读模式

该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~

这篇文章将详细讲解利用数据增强方法实现图像数据集的扩充。通常,在某些情况下我们会缺失数据集或需要自主构建数据集,此时数据增强将发挥重要作用,本文以水书图像为例,通过五大类方法扩充数据集。本文以代码和方法为主,原理知识整个系列的众多文章已经介绍过。

希望对您有所帮助!让我们开始吧,且看且珍惜。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

  • 一.什么是水书

  • 二.数据集构造

  • 三.数据增强

    • 1.什么是数据增强

    • 2.几何变换增强数据

    • 3.亮度变换增强数据

    • 4.颜色通道变换增强数据

    • 5.高斯噪声和椒盐噪声

    • 6.模拟怀旧和噪声添加

  • 五.完整代码

  • 六.如何用GAN生成图像?

  • 七.总结


该系列在github所有源代码:

  • https://github.com/eastmountyxz/
    ImageProcessing-Python

前文回顾(下面的超链接可以点击喔):

学Python近十年,认识了很多大佬和朋友,感恩。深知自己很菜,得拼命努力前行,编程也没有什么捷径,干就对了。希望未来能更透彻学习和撰写文章,同时非常感谢参考文献中的大佬们的文章和分享,共勉。

- https://blog.csdn.net/eastmount


一.什么是水书

水书是水族古文字及其著编典籍的汉译统称,是除纳西族东巴文以外世界上最后“活着”的象形文字,收集整理、研究解读水族文字对了解水族历史文化、研究少数民族原始宗教和文化信仰、从中窥探中国古文字奥秘有着重要意义。

由于水书是靠数量稀少的水书先生代代手抄传承,且记录水书的载体除纸张外还有大量刺绣、碑刻、木刻等其他原生载 体、金石载体,随着时代的发展,大量水书古籍文献和文字图像正在损毁和流失。另一方面,水书传承者的数量随着时间推移正在急剧减少,据统计,全国有近千名水书先生,但绝大部分已在60岁以上,大量散落民间的水书古籍无法被收集进行专业修复和妥善保存。传统水书收集整理和水族文字研究在人力、物力和技术上有一定的局限性,对大量散落民间的水书进行系统采集整理和文字提取识别难度巨大,无法满足信息化时代对濒危水族文字抢救提出的新要求。

当前,国内外学者开始高度重视对濒危水书的抢救工作,发掘、收集和整理了大批水书文献资料。这一时期,除了传统的对水书自身的研究和挖掘,学者们也开始思考水族文字抢救工作中存在的问题和困难,并不断探索解决方案,如罗春寒的《水书的抢救及存在问题浅议》、潘朝霖的《水文急剧消亡的原因探 析》、康蔼德和潘兴文的《水 语 调 查 研 究》等。随着计算机技术的发展和普及,水书研究进入信息化时代,运用计算机辅助水书输入、整理研究开始走入学术视野,如韦宗林的《水族古文字计算机输入法》、董芳的《水书文字规范标准建设与信息化的研究》、罗刚的《计 算 机 水 书 语 料库建设的探讨》、戴丹的《水书水字可视化输入中的模式 匹配》。经过各级部门和专家学者不遗余力的努力,目前国内水书的整理和研究已颇具成效。但传统的水族文字采集、整理和保护方式还存在以下几个方面的不足:

  • 由于记载水族文字的主要载体为口传、纸张手抄、刺绣、碑刻、木刻、陶瓷和古籍等,文字清晰度不足,数字化读取困难,对字体的采集和整理主要依赖于大量的人力和物力,信息化环境下的数据库建设不足,大大制约了整理和研究效率;

  • 历来对水书和水族古文字的研究主要采用人文社科的思想,侧重于对字源、字音、字义和文化内涵的破译和解读,现代化信息技术在水书研究领域的运用体现不明显,作用没有得到充分发挥;

  • 对水族文字提取和识别研究,破译成果的整理和运用不足,至今没有完成水书本体和水族古文字识别及数据库的建设。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

随着计算机视觉和图像处理技术的迅速发展,图像分割与图像识别方法已广泛应用于各行各业,比如车牌识别、人脸识别、身份证识等。图像分割是将图像分成若干具有独特性质的区域并提取感兴趣目标的技术,它是图像处理和图像分析的关键步骤。图像识别是通过算法和函数提取像素中的某些特征,并对图像进行识别和分类的过程。

为了更好地运用现代计算机图像处理和图像分割等技术来辅助濒危水族文字的抢救工作,保护水族文化,修复水书文物图像,本文提出了一种基于图像增强及区域检测的水族文字提取与分割算法。该研究具有重要的理论研究意义和良好的实际应用价值,可以广泛应用于水族文字提取、水族文字识别和水族文化传承领域。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


二.数据集构造

作者构造了如下图的初始数据集,共计12个水族文字,您可以猜猜它们的含义。

PS:我写的水书看着还不错,丑萌丑萌的 O(∩_∩)O

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

初始数据集如下图所示,大家猜中了吗?

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

很显然,紧靠人工撰写无法完成水族文字识别任务。那怎么解决呢?

  • 方法1:通过图像提取采集水族古籍中的古文字,并构造数据集
  • 方法2:通过数据增强的方法生成更多的数据集
  • 方法3:利用GAN算法生成类似的数据集,但前提仍需要学习

此外,在真实场景中,我们会遇到很多缺乏图像数据的情况,数据增强的方法非常适用且有效。因此,本文主要介绍数据增强扩充水书图像数据集的案例。


三.数据增强

1.什么是数据增强

数据增强也叫数据扩增,意思是在不实质性的增加数据的情况下,让有限的数据产生等价于更多数据的价值。

常见方法如下:

  • 空间几何变换

    – 镜像、翻转、旋转、缩放、平移、裁剪

  • .亮度变换

    – 亮度、对比度、饱和度

  • 颜色通道变换

  • 噪声变换

    – 椒盐噪声、高斯噪声、白点噪声

  • 模拟雾或图像怀旧特效

    – 模拟传统水书碑刻、木刻等场景,针对特定场景进行模拟

  • GAN

    – 深度学习生成类似图像

  • 其它方法

    – SMOTE、 mixup(线性插值)、AutoAugment


2.几何变换增强数据

图像几何变换不改变图像的像素值,在图像平面上进行像素变换。适当的几何变换可以最大程度地消除由于成像角度、透视关系乃至镜头自身原因所造成的几何失真所产生的负面影响。几何变换常常作为图像处理应用的预处理步骤,是图像归一化的核心工作之一。比如图像旋转原理如下:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

原理参考作者前文:

  • [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)

  • [Python从零到壹] 三十九.图像处理基础篇之图像几何变换(镜像仿射透视)

该部分关键代码如下:

# -*- coding: utf-8 -*-"""2022-12-24By: Eastmount CSDN xiuzhang"""import osimport cv2import numpy as npimport matplotlib.pyplot as plt
#-----------------------------------------------------------------------#几何变换-镜像、翻转、旋转、缩放def JH_Transformation(img,img_path): rows, cols, channel = img.shape #print(rows,cols,channel) #镜像处理 jx = cv2.flip(img, 1)
#旋转30度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1) rotated30 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转45度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1) rotated45 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转90度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 90, 1) rotated90 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转330度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 330, 1) rotated330 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转180度 M = cv2.getRotationMatrix2D((cols/2, rows/2), 180, 1) rotated180 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#缩小 sx = cv2.resize(img, (int(cols*0.8), int(rows*0.8))) #放大 fd = cv2.resize(img, (int(cols*1.2), int(rows*1.2))) #显示图像 titles = ['Source', 'JX', 'XZ30', 'XZ45', 'XZ90', 'XZ330', 'XZ180', 'SX', 'FD'] images = [img, jx, rotated30, rotated45, rotated90, rotated330, rotated180, sx, fd] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
#保存图像 cv2.imwrite(img_path[0:-4] + '_jx.png', jx) cv2.imwrite(img_path[0:-4] + '_rotated30.png', rotated30) cv2.imwrite(img_path[0:-4] + '_rotated45.png', rotated45) cv2.imwrite(img_path[0:-4] + '_rotated90.png', rotated90) cv2.imwrite(img_path[0:-4] + '_rotated330.png', rotated330) cv2.imwrite(img_path[0:-4] + '_rotated180.png', rotated180) cv2.imwrite(img_path[0:-4] + '_sx.png', sx) cv2.imwrite(img_path[0:-4] + '_fd.png', fd) #-----------------------------------------------------------------------#读取指定文件夹下的所有图像def main(): file_path = "data" for img_name in os.listdir(file_path): img_path = file_path + "\" + img_name res_path = "data_add" + "\" + img_name img = cv2.imread(img_path) #1.几何变换-镜像、翻转、旋转、缩放 JH_Transformation(img,res_path)
if __name__ == "__main__": main()

输出结果如下图所示:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


3.亮度变换增强数据

图像亮度变换类似于图像加法或减法运算。第一种是调用Numpy库实现,目标图像像素为两张图像的像素之和;第二种是通过OpenCV调用add()函数实现。第二种方法的函数原型如下:

  • dst = add(src1, src2[, dst[, mask[, dtype]]])

    – src1表示第一张图像的像素矩阵
    – src2表示第二张图像的像素矩阵
    – dst表示输出的图像,必须和输入图像具有相同的大小和通道数
    – mask表示可选操作掩码(8位单通道数组),用于指定要更改的输出数组的元素。
    – dtype表示输出数组的可选深度

注意,当两幅图像的像素值相加结果小于等于255时,则输出图像直接赋值该结果,如120+48赋值为168;如果相加值大于255,则输出图像的像素结果设置为255,如(255+64) 赋值为255。原理参考作者前文:

  • [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解

该部分关键代码如下:

#-----------------------------------------------------------------------#亮度变换-增强、减弱def Brighter_Transformation(img, percetage):    img_copy = img.copy()    w = img.shape[1]    h = img.shape[0]    for xi in range(0, w):        for xj in range(0, h):            img_copy[xj, xi, 0] = np.clip(int(img[xj, xi, 0] * percetage), a_max=255, a_min=0)            img_copy[xj, xi, 1] = np.clip(int(img[xj, xi, 1] * percetage), a_max=255, a_min=0)            img_copy[xj, xi, 2] = np.clip(int(img[xj, xi, 2] * percetage), a_max=255, a_min=0)    return img_copy
def Darker_Transformation(img, percetage): img_copy = img.copy() w = img.shape[1] h = img.shape[0] for xi in range(0, w): for xj in range(0, h): img_copy[xj, xi, 0] = int(img[xj, xi, 0] * percetage) img_copy[xj, xi, 1] = int(img[xj, xi, 1] * percetage) img_copy[xj, xi, 2] = int(img[xj, xi, 2] * percetage) return img_copy
def LD_Transformation(img,img_path): rows, cols, channel = img.shape #增强1.1、1.5、2.0、2.5、3.0 zq_11 = Brighter_Transformation(img,1.1) zq_15 = Brighter_Transformation(img,1.5) zq_20 = Brighter_Transformation(img,2.0) zq_25 = Brighter_Transformation(img,2.5) zq_30 = Brighter_Transformation(img,3.0)
#减弱0.9、0.8、0.5 jr_09 = Darker_Transformation(img,0.9) jr_08 = Darker_Transformation(img,0.8) jr_07 = Darker_Transformation(img,0.7)
#显示图像 titles = ['Source', 'ZQ1.1', 'ZQ1.5', 'ZQ2.0', 'ZQ2.5', 'ZQ3.0', 'JR0.9', 'JR0.8', 'JR0.7'] images = [img, zq_11, zq_15, zq_20, zq_25, zq_30, jr_09, jr_08, jr_07] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
#保存图像 cv2.imwrite(img_path[0:-4] + '_zq_11.png', zq_11) cv2.imwrite(img_path[0:-4] + '_zq_15.png', zq_15) cv2.imwrite(img_path[0:-4] + '_zq_20.png', zq_20) cv2.imwrite(img_path[0:-4] + '_zq_25.png', zq_25) cv2.imwrite(img_path[0:-4] + '_zq_30.png', zq_30) cv2.imwrite(img_path[0:-4] + '_jr_09.png', jr_09) cv2.imwrite(img_path[0:-4] + '_jr_08.png', jr_08) cv2.imwrite(img_path[0:-4] + '_jr_07.png', jr_07)

输出结果如下图所示:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


4.颜色通道变换增强数据

该部分关键代码如下:

#-----------------------------------------------------------------------#颜色通道变换def Channel_Transformation(img,img_path):    rows, cols, channel = img.shape    img = Brighter_Transformation(img,1.5)  #边缘增强    color_map = [        cv2.COLORMAP_AUTUMN,        cv2.COLORMAP_BONE,        cv2.COLORMAP_JET,        cv2.COLORMAP_WINTER,        cv2.COLORMAP_PARULA,        cv2.COLORMAP_OCEAN,        cv2.COLORMAP_SUMMER,        cv2.COLORMAP_SPRING,        cv2.COLORMAP_COOL,        cv2.COLORMAP_PINK,        cv2.COLORMAP_HOT,        cv2.COLORMAP_PARULA,        cv2.COLORMAP_MAGMA,        cv2.COLORMAP_INFERNO,        cv2.COLORMAP_PLASMA,        cv2.COLORMAP_TWILIGHT,        cv2.COLORMAP_TWILIGHT_SHIFTED    ]
rgb_img_01 = cv2.applyColorMap(img, color_map[0]) rgb_img_02 = cv2.applyColorMap(img, color_map[1]) rgb_img_03 = cv2.applyColorMap(img, color_map[9]) rgb_img_04 = cv2.applyColorMap(img, color_map[3]) rgb_img_05 = cv2.applyColorMap(img, color_map[13]) rgb_img_06 = cv2.applyColorMap(img, color_map[5]) rgb_img_07 = cv2.applyColorMap(img, color_map[12]) rgb_img_08 = cv2.applyColorMap(img, color_map[10])
# 通道分离 b = cv2.split(img)[0] g = np.zeros((rows,cols), dtype=img.dtype) r = np.zeros((rows,cols), dtype=img.dtype) mb = cv2.merge([b, g, r])
g = cv2.split(img)[1] b = np.zeros((rows,cols), dtype=img.dtype) r = np.zeros((rows,cols), dtype=img.dtype) mg = cv2.merge([b, g, r])
r = cv2.split(img)[2] b = np.zeros((rows,cols), dtype=img.dtype) g = np.zeros((rows,cols), dtype=img.dtype) mr = cv2.merge([b, g, r]) #显示图像 titles = ['Source', 'RGB-1', 'RGB-2', 'RGB-3', 'RGB-4', 'RGB-5', 'RGB-6', 'RGB-7', 'RGB-8', 'B', 'G', 'R'] images = [img, rgb_img_01, rgb_img_02, rgb_img_03, rgb_img_04, rgb_img_05, rgb_img_06, rgb_img_07, rgb_img_08, mb, mg, mr] for i in range(12): plt.subplot(4,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
#保存图像 cv2.imwrite(img_path[0:-4] + '_rgb_img_01.png', rgb_img_01) cv2.imwrite(img_path[0:-4] + '_rgb_img_02.png', rgb_img_02) cv2.imwrite(img_path[0:-4] + '_rgb_img_03.png', rgb_img_03) cv2.imwrite(img_path[0:-4] + '_rgb_img_04.png', rgb_img_04) cv2.imwrite(img_path[0:-4] + '_rgb_img_05.png', rgb_img_05) cv2.imwrite(img_path[0:-4] + '_rgb_img_06.png', rgb_img_06) cv2.imwrite(img_path[0:-4] + '_rgb_img_07.png', rgb_img_07) cv2.imwrite(img_path[0:-4] + '_rgb_img_08.png', rgb_img_08) cv2.imwrite(img_path[0:-4] + '_mb.png', mb) cv2.imwrite(img_path[0:-4] + '_mg.png', mg) cv2.imwrite(img_path[0:-4] + '_mr.png', mr)

输出结果如下图所示:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


5.高斯噪声和椒盐噪声

该部分关键代码如下:

#-----------------------------------------------------------------------#添加高斯噪声和椒盐噪声def GaussianNoise(img, percetage):    gn = img.copy()    w = img.shape[1]    h = img.shape[0]    G_NoiseNum = int(percetage * img.shape[0] * img.shape[1])    for i in range(G_NoiseNum):        lx = np.random.randint(0, h)        ly = np.random.randint(0, w)        gn[lx][ly][np.random.randint(3)] = np.random.randn(1)[0]    return gn
def SaltNoise(img, percetage): sn = img.copy() SP_NoiseNum = int(percetage * img.shape[0] * img.shape[1]) for i in range(SP_NoiseNum): randR = np.random.randint(0, img.shape[0] - 1) randG = np.random.randint(0, img.shape[1] - 1) randB = np.random.randint(0, 3) if np.random.randint(0, 1) == 0: sn[randR, randG, randB] = 0 else: sn[randR, randG, randB] = 255 return sn
def Gaussian_Salt_Noise(img,res_path): rows, cols, channel = img.shape img = Brighter_Transformation(img,1.5) #边缘增强
#高斯噪声 gn_005 = GaussianNoise(img, 0.05) gn_010 = GaussianNoise(img, 0.10) gn_015 = GaussianNoise(img, 0.15) gn_020 = GaussianNoise(img, 0.20)
#椒盐噪声 sn_005 = SaltNoise(img, 0.05) sn_010 = SaltNoise(img, 0.10) sn_015 = SaltNoise(img, 0.15) sn_020 = SaltNoise(img, 0.20) #显示图像 titles = ['Source', 'Gaussian-0.05', 'Gaussian-0.10', 'Gaussian-0.15', 'Gaussian-0.20', 'Salt-0.05', 'Salt-0.10', 'Salt-0.15', 'Salt-0.20'] images = [img, gn_005, gn_010, gn_015, gn_020, sn_005, sn_010, sn_015, sn_020] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() #保存图像 cv2.imwrite(img_path[0:-4] + '_gn_005.png', gn_005) cv2.imwrite(img_path[0:-4] + '_gn_010.png', gn_010) cv2.imwrite(img_path[0:-4] + '_gn_015.png', gn_015) cv2.imwrite(img_path[0:-4] + '_gn_020.png', gn_020) cv2.imwrite(img_path[0:-4] + '_sn_005.png', sn_005) cv2.imwrite(img_path[0:-4] + '_sn_010.png', sn_010) cv2.imwrite(img_path[0:-4] + '_sn_015.png', sn_015) cv2.imwrite(img_path[0:-4] + '_sn_020.png', sn_020)

输出结果如下图所示:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


6.模拟怀旧和噪声添加

该部分关键代码如下:

#-----------------------------------------------------------------------#模拟怀旧和噪声添加def Salt(img, num):    wn = img.copy()    rows, cols, chn = wn.shape    for i in range(num):        x = np.random.randint(0, rows)        y = np.random.randint(0, cols)            wn[x,y,:] = 210    return wn
def Fog_Noise(img, percetage): mask_img = img.copy() mask_img[:, :] = (166, 178, 180) #雾的颜色 (146,182,213) #调整雾的浓度 round(random.uniform(0.03, 0.28), 2) res = cv2.addWeighted(img, percetage, mask_img, 1-percetage, 0) return res
def Fog_Salt_Noise(img,img_path): rows, cols, channel = img.shape img = Brighter_Transformation(img,1.5) #边缘增强
#白点噪声 wn_100 = Salt(img, 100) wn_150 = Salt(img, 150) wn_200 = Salt(img, 200) wn_250 = Salt(img, 250)
#模拟怀旧 fog_06 = Fog_Noise(img, 0.6) fog_07 = Fog_Noise(img, 0.7) fog_08 = Fog_Noise(img, 0.8) fog_09 = Fog_Noise(img, 0.9)
#显示图像 titles = ['Source', 'wn-100', 'wn-150', 'wn-200', 'wn-250', 'fog_06', 'fog_07', 'fog_08', 'fog_09'] images = [img, wn_100, wn_150, wn_200, wn_250, fog_06, fog_07, fog_08, fog_09] for i in range(9): plt.subplot(3,3 ,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()
#保存图像 cv2.imwrite(img_path[0:-4] + '_wn_100.png', wn_100) cv2.imwrite(img_path[0:-4] + '_wn_150.png', wn_150) cv2.imwrite(img_path[0:-4] + '_wn_200.png', wn_200) cv2.imwrite(img_path[0:-4] + '_wn_250.png', wn_250) cv2.imwrite(img_path[0:-4] + '_fog_06.png', fog_06) cv2.imwrite(img_path[0:-4] + '_fog_07.png', fog_07) cv2.imwrite(img_path[0:-4] + '_fog_08.png', fog_08) cv2.imwrite(img_path[0:-4] + '_fog_09.png', fog_09)

输出结果如下图所示:

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


五.完整代码

本文的最终代码如下所示,通过定义函数实现了五大类别的数据增强。希望对您有所帮助。

# -*- coding: utf-8 -*-"""2022-12-24By: Eastmount CSDN xiuzhang"""import osimport cv2import numpy as npimport matplotlib.pyplot as pltimport random
#-----------------------------------------------------------------------#几何变换-镜像、翻转、旋转、缩放def JH_Transformation(img,img_path): rows, cols, channel = img.shape #print(rows,cols,channel) #镜像处理 jx = cv2.flip(img, 1)
#旋转30度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1) rotated30 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转45度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1) rotated45 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转90度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 90, 1) rotated90 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转330度 (旋转中心,旋转度数,scale) M = cv2.getRotationMatrix2D((cols/2, rows/2), 330, 1) rotated330 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#旋转180度 M = cv2.getRotationMatrix2D((cols/2, rows/2), 180, 1) rotated180 = cv2.warpAffine(img, M, (cols, rows), borderValue=(255,255,255))
#缩小 sx = cv2.resize(img, (int(cols*0.8), int(rows*0.8))) #放大 fd = cv2.resize(img, (int(cols*1.2), int(rows*1.2)))
""" #显示图像 titles = ['Source', 'JX', 'XZ30', 'XZ45', 'XZ90', 'XZ330', 'XZ180', 'SX', 'FD'] images = [img, jx, rotated30, rotated45, rotated90, rotated330, rotated180, sx, fd] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() """
#保存图像 cv2.imwrite(img_path[0:-4] + '_jx.png', jx) cv2.imwrite(img_path[0:-4] + '_rotated30.png', rotated30) cv2.imwrite(img_path[0:-4] + '_rotated45.png', rotated45) cv2.imwrite(img_path[0:-4] + '_rotated90.png', rotated90) cv2.imwrite(img_path[0:-4] + '_rotated330.png', rotated330) cv2.imwrite(img_path[0:-4] + '_rotated180.png', rotated180) cv2.imwrite(img_path[0:-4] + '_sx.png', sx) cv2.imwrite(img_path[0:-4] + '_fd.png', fd)
#-----------------------------------------------------------------------#亮度变换-增强、减弱def Brighter_Transformation(img, percetage): img_copy = img.copy() w = img.shape[1] h = img.shape[0] for xi in range(0, w): for xj in range(0, h): img_copy[xj, xi, 0] = np.clip(int(img[xj, xi, 0] * percetage), a_max=255, a_min=0) img_copy[xj, xi, 1] = np.clip(int(img[xj, xi, 1] * percetage), a_max=255, a_min=0) img_copy[xj, xi, 2] = np.clip(int(img[xj, xi, 2] * percetage), a_max=255, a_min=0) return img_copy
def Darker_Transformation(img, percetage): img_copy = img.copy() w = img.shape[1] h = img.shape[0] for xi in range(0, w): for xj in range(0, h): img_copy[xj, xi, 0] = int(img[xj, xi, 0] * percetage) img_copy[xj, xi, 1] = int(img[xj, xi, 1] * percetage) img_copy[xj, xi, 2] = int(img[xj, xi, 2] * percetage) return img_copy
def LD_Transformation(img,img_path): rows, cols, channel = img.shape #增强1.1、1.5、2.0、2.5、3.0 zq_11 = Brighter_Transformation(img,1.1) zq_15 = Brighter_Transformation(img,1.5) zq_18 = Brighter_Transformation(img,1.8) zq_20 = Brighter_Transformation(img,2.0) zq_25 = Brighter_Transformation(img,2.5)
#减弱0.9、0.8、0.5 jr_09 = Darker_Transformation(img,0.9) jr_08 = Darker_Transformation(img,0.8) jr_07 = Darker_Transformation(img,0.7)
""" #显示图像 titles = ['Source', 'ZQ1.1', 'ZQ1.5', 'ZQ1.8', 'ZQ2.0', 'ZQ2.5', 'JR0.9', 'JR0.8', 'JR0.7'] images = [img, zq_11, zq_15, zq_18, zq_20, zq_25, jr_09, jr_08, jr_07] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() """ #保存图像 cv2.imwrite(img_path[0:-4] + '_zq_11.png', zq_11) cv2.imwrite(img_path[0:-4] + '_zq_15.png', zq_15) cv2.imwrite(img_path[0:-4] + '_zq_18.png', zq_18) cv2.imwrite(img_path[0:-4] + '_zq_20.png', zq_20) cv2.imwrite(img_path[0:-4] + '_zq_25.png', zq_25) cv2.imwrite(img_path[0:-4] + '_jr_09.png', jr_09) cv2.imwrite(img_path[0:-4] + '_jr_08.png', jr_08) cv2.imwrite(img_path[0:-4] + '_jr_07.png', jr_07) #-----------------------------------------------------------------------#颜色通道变换def Channel_Transformation(img,img_path): rows, cols, channel = img.shape img = Brighter_Transformation(img,1.5) #边缘增强 color_map = [ cv2.COLORMAP_AUTUMN, cv2.COLORMAP_BONE, cv2.COLORMAP_JET, cv2.COLORMAP_WINTER, cv2.COLORMAP_PARULA, cv2.COLORMAP_OCEAN, cv2.COLORMAP_SUMMER, cv2.COLORMAP_SPRING, cv2.COLORMAP_COOL, cv2.COLORMAP_PINK, cv2.COLORMAP_HOT, cv2.COLORMAP_PARULA, cv2.COLORMAP_MAGMA, cv2.COLORMAP_INFERNO, cv2.COLORMAP_PLASMA, cv2.COLORMAP_TWILIGHT, cv2.COLORMAP_TWILIGHT_SHIFTED ]
rgb_img_01 = cv2.applyColorMap(img, color_map[0]) rgb_img_02 = cv2.applyColorMap(img, color_map[1]) rgb_img_03 = cv2.applyColorMap(img, color_map[9]) rgb_img_04 = cv2.applyColorMap(img, color_map[3]) rgb_img_05 = cv2.applyColorMap(img, color_map[13]) rgb_img_06 = cv2.applyColorMap(img, color_map[5]) rgb_img_07 = cv2.applyColorMap(img, color_map[12]) rgb_img_08 = cv2.applyColorMap(img, color_map[10])
# 通道分离 b = cv2.split(img)[0] g = np.zeros((rows,cols), dtype=img.dtype) r = np.zeros((rows,cols), dtype=img.dtype) mb = cv2.merge([b, g, r])
g = cv2.split(img)[1] b = np.zeros((rows,cols), dtype=img.dtype) r = np.zeros((rows,cols), dtype=img.dtype) mg = cv2.merge([b, g, r])
r = cv2.split(img)[2] b = np.zeros((rows,cols), dtype=img.dtype) g = np.zeros((rows,cols), dtype=img.dtype) mr = cv2.merge([b, g, r]) """ #显示图像 titles = ['Source', 'RGB-1', 'RGB-2', 'RGB-3', 'RGB-4', 'RGB-5', 'RGB-6', 'RGB-7', 'RGB-8', 'B', 'G', 'R'] images = [img, rgb_img_01, rgb_img_02, rgb_img_03, rgb_img_04, rgb_img_05, rgb_img_06, rgb_img_07, rgb_img_08, mb, mg, mr] for i in range(12): plt.subplot(4,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() """
#保存图像 cv2.imwrite(img_path[0:-4] + '_rgb_img_01.png', rgb_img_01) cv2.imwrite(img_path[0:-4] + '_rgb_img_02.png', rgb_img_02) cv2.imwrite(img_path[0:-4] + '_rgb_img_03.png', rgb_img_03) cv2.imwrite(img_path[0:-4] + '_rgb_img_04.png', rgb_img_04) cv2.imwrite(img_path[0:-4] + '_rgb_img_05.png', rgb_img_05) cv2.imwrite(img_path[0:-4] + '_rgb_img_06.png', rgb_img_06) cv2.imwrite(img_path[0:-4] + '_rgb_img_07.png', rgb_img_07) cv2.imwrite(img_path[0:-4] + '_rgb_img_08.png', rgb_img_08) cv2.imwrite(img_path[0:-4] + '_mb.png', mb) cv2.imwrite(img_path[0:-4] + '_mg.png', mg) cv2.imwrite(img_path[0:-4] + '_mr.png', mr)
#-----------------------------------------------------------------------#添加高斯噪声和椒盐噪声def GaussianNoise(img, percetage): gn = img.copy() w = img.shape[1] h = img.shape[0] G_NoiseNum = int(percetage * img.shape[0] * img.shape[1]) for i in range(G_NoiseNum): lx = np.random.randint(0, h) ly = np.random.randint(0, w) gn[lx][ly][np.random.randint(3)] = np.random.randn(1)[0] return gn
def SaltNoise(img, percetage): sn = img.copy() SP_NoiseNum = int(percetage * img.shape[0] * img.shape[1]) for i in range(SP_NoiseNum): randR = np.random.randint(0, img.shape[0] - 1) randG = np.random.randint(0, img.shape[1] - 1) randB = np.random.randint(0, 3) if np.random.randint(0, 1) == 0: sn[randR, randG, randB] = 0 else: sn[randR, randG, randB] = 255 return sn
def Gaussian_Salt_Noise(img,img_path): rows, cols, channel = img.shape img = Brighter_Transformation(img,1.5) #边缘增强
#高斯噪声 gn_005 = GaussianNoise(img, 0.05) gn_010 = GaussianNoise(img, 0.10) gn_015 = GaussianNoise(img, 0.15) gn_020 = GaussianNoise(img, 0.20)
#椒盐噪声 sn_005 = SaltNoise(img, 0.05) sn_010 = SaltNoise(img, 0.10) sn_015 = SaltNoise(img, 0.15) sn_020 = SaltNoise(img, 0.20)
""" #显示图像 titles = ['Source', 'Gaussian-0.05', 'Gaussian-0.10', 'Gaussian-0.15', 'Gaussian-0.20', 'Salt-0.05', 'Salt-0.10', 'Salt-0.15', 'Salt-0.20'] images = [img, gn_005, gn_010, gn_015, gn_020, sn_005, sn_010, sn_015, sn_020] for i in range(9): plt.subplot(3,3,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() """ #保存图像 cv2.imwrite(img_path[0:-4] + '_gn_005.png', gn_005) cv2.imwrite(img_path[0:-4] + '_gn_010.png', gn_010) cv2.imwrite(img_path[0:-4] + '_gn_015.png', gn_015) cv2.imwrite(img_path[0:-4] + '_gn_020.png', gn_020) cv2.imwrite(img_path[0:-4] + '_sn_005.png', sn_005) cv2.imwrite(img_path[0:-4] + '_sn_010.png', sn_010) cv2.imwrite(img_path[0:-4] + '_sn_015.png', sn_015) cv2.imwrite(img_path[0:-4] + '_sn_020.png', sn_020)
#-----------------------------------------------------------------------#模拟怀旧和噪声添加def Salt(img, num): wn = img.copy() rows, cols, chn = wn.shape for i in range(num): x = np.random.randint(0, rows) y = np.random.randint(0, cols) wn[x,y,:] = 210 return wn
def Fog_Noise(img, percetage): mask_img = img.copy() mask_img[:, :] = (166, 178, 180) #雾的颜色 (146,182,213) #调整雾的浓度 round(random.uniform(0.03, 0.28), 2) res = cv2.addWeighted(img, percetage, mask_img, 1-percetage, 0) return res
def Fog_Salt_Noise(img,img_path): rows, cols, channel = img.shape img = Brighter_Transformation(img,1.5) #边缘增强
#白点噪声 wn_100 = Salt(img, 100) wn_150 = Salt(img, 150) wn_200 = Salt(img, 200) wn_250 = Salt(img, 250)
#模拟怀旧 fog_06 = Fog_Noise(img, 0.6) fog_07 = Fog_Noise(img, 0.7) fog_08 = Fog_Noise(img, 0.8) fog_09 = Fog_Noise(img, 0.9)
""" #显示图像 titles = ['Source', 'wn-100', 'wn-150', 'wn-200', 'wn-250', 'fog_06', 'fog_07', 'fog_08', 'fog_09'] images = [img, wn_100, wn_150, wn_200, wn_250, fog_06, fog_07, fog_08, fog_09] for i in range(9): plt.subplot(3,3 ,i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show() """
#保存图像 cv2.imwrite(img_path[0:-4] + '_wn_100.png', wn_100) cv2.imwrite(img_path[0:-4] + '_wn_150.png', wn_150) cv2.imwrite(img_path[0:-4] + '_wn_200.png', wn_200) cv2.imwrite(img_path[0:-4] + '_wn_250.png', wn_250) cv2.imwrite(img_path[0:-4] + '_fog_06.png', fog_06) cv2.imwrite(img_path[0:-4] + '_fog_07.png', fog_07) cv2.imwrite(img_path[0:-4] + '_fog_08.png', fog_08) cv2.imwrite(img_path[0:-4] + '_fog_09.png', fog_09)
#-----------------------------------------------------------------------#读取指定文件夹下的所有图像def main(): file_path = "data" for img_name in os.listdir(file_path): img_path = file_path + "\" + img_name res_path = "data_add" + "\" + img_name img = cv2.imread(img_path)
#1.几何变换-镜像、翻转、旋转、缩放 JH_Transformation(img,res_path)
#2.亮度变换-增强、减弱 LD_Transformation(img,res_path)
#3.颜色通道变换 Channel_Transformation(img,res_path)
#4.添加高斯噪声和椒盐噪声 Gaussian_Salt_Noise(img,res_path)
#5.模拟怀旧和噪声添加 Fog_Salt_Noise(img,res_path) if __name__ == "__main__": main()

最终结果如下图所示,加原图共5280张图像。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

后续可以按照同水族文字进行划分,并生成对应的训练集、测试集和验证集。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集


六.如何用GAN生成图像?

建议读者先自行尝试,结合作者前文GAN的博客,后面有时间我也会详细撰写一篇文章。

  • [Python图像识别] 四十九.图像生成之什么是生成对抗网络GAN?基础原理和代码普及


七.总结

写到这里,这篇文章就介绍结束了,希望对您有所帮助,也希望大家多多关注非物质文化遗产,包括水族文字,作者多年致力于利用AI技术保护和抢救濒危少数民族文字和语音,典型的是水书、侗族大歌、清水江文献古籍等。后续也会陆续开源相关代码和文章,靠一两个人真心挺难的,但贵在喜欢,贵在有趣,尽管每年只能前进一点点,但趴着也要前行,希望能为家乡贡献一丝丝力量,加油!感恩同行,感兴趣的也希望能一起交流。

[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

博四,只能挤时间分享一些原创博客,希望您喜欢这篇文章,还挺花时间的,再次感谢参考文献的老师们。真心希望这篇文章对您有所帮助,加油!今年闭关搞论文,非诚勿扰,如果有时间就会在CSDN和公众号分享更多高质量的文章和专栏,继续加油,感恩前行!

(By:Eastmount 2022-12-05 夜于贵阳)


参考文献:

  • [1] 作者. 基于自适应图像增强技术的水族文字提取与识别研究[J]. 计算机科学, 2021.

  • [2] 岑家梧. 水书与水家来源[J]. 西南民族文化论丛, 1949.

  • [3] 张为纲. 水家来源试探[J]. 社会研究, 1942(36).

  • [4] 潘朝霖. 水族探源[J]. 贵州民族学院学报(社会科学版), 1987.

  • [5] 王品魁. 水书·正七卷壬辰卷[M]. 贵阳:贵州民族出版社, 1994.

  • [6] 吴端端, 蒋国生. 中国水族文字档案的形成与特点[J]. 档案学研究, 1999.

  • [7] 马费成,陈潇俊,刘向. 基于科学知识图谱分析的知识演化研究—以生物医学为例[J]. 情报科学, 2012, 30(1): 1-7.

  • [8] 苏新宁. 知识组织的科学理论阐释[J]. 图书与情报, 2013(6): 1-7.

  • [9] 刘峤,李杨,等.知识图谱构建技术综述[J].计算机研究与发展, 2016,53(3): 582-600.

  • [10] [英]康蔼德, 潘兴文. 水语调查研究[M]. 贵阳:贵州人民出版社, 2014.

  • [11] 王炳江, 潘进头. 水书名物考论[J]. 贵州大学学报(社会科学版), 2018.

  • [12] 汤敏丽, 等. 基于Faster-RCNN的水书古籍手写文字的检测与识别[J]. 厦门大学学报(自然科学版), 2022.

  • [13] 高慧宜. 水族水文和傈僳族竹书的异体字比较研究[J]. 民族论坛, 2008.

  • [14] 我不爱机器学习. Python实现11种图像扩增方法. https://zhuanlan.zhihu.com/p/521651728

  • [15] orangezs. [图像处理]-使用python及PIL库对图像分类数据图片进行数据增强扩充. https://blog.csdn.net/ai_faker/article/details/115218601

原文始发于微信公众号(娜璋AI安全之家):[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年12月5日20:00:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   [Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集https://cn-sec.com/archives/2269443.html

发表评论

匿名网友 填写信息