前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >[Python图像识别] 二十一.水书图像识别之利用数据增强扩充图像数据集

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

作者头像
Eastmount
发布于 2023-12-06 11:09:52
发布于 2023-12-06 11:09:52
24900
代码可运行
举报
运行总次数:0
代码可运行

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

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

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

  • 一.什么是水书
  • 二.数据集构造
  • 三.数据增强
    • 1.什么是数据增强
    • 2.几何变换增强数据
    • 3.亮度变换增强数据
    • 4.颜色通道变换增强数据
    • 5.高斯噪声和椒盐噪声
    • 6.模拟怀旧和噪声添加
  • 五.完整代码
  • 六.如何用GAN生成图像?
  • 七.总结

该系列在github所有源代码:

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

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


一.什么是水书

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

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

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

  • 由于记载水族文字的主要载体为口传、纸张手抄、刺绣、碑刻、木刻、陶瓷和古籍等,文字清晰度不足,数字化读取困难,对字体的采集和整理主要依赖于大量的人力和物力,信息化环境下的数据库建设不足,大大制约了整理和研究效率;
  • 历来对水书和水族古文字的研究主要采用人文社科的思想,侧重于对字源、字音、字义和文化内涵的破译和解读,现代化信息技术在水书研究领域的运用体现不明显,作用没有得到充分发挥;
  • 对水族文字提取和识别研究,破译成果的整理和运用不足,至今没有完成水书本体和水族古文字识别及数据库的建设。

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

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


二.数据集构造

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

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

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

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

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

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


三.数据增强

1.什么是数据增强

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

常见方法如下:

  • 空间几何变换– 镜像、翻转、旋转、缩放、平移、裁剪
  • .亮度变换 – 亮度、对比度、饱和度
  • 颜色通道变换
  • 噪声变换– 椒盐噪声、高斯噪声、白点噪声
  • 模拟雾或图像怀旧特效– 模拟传统水书碑刻、木刻等场景,针对特定场景进行模拟
  • GAN– 深度学习生成类似图像
  • 其它方法– SMOTE、 mixup(线性插值)、AutoAugment

2.几何变换增强数据

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

原理参考作者前文:

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

该部分关键代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-
"""
2022-12-24
By: Eastmount CSDN xiuzhang
"""
import os
import cv2
import numpy as np
import 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))

    #旋转180M = 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()

输出结果如下图所示:


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从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解

该部分关键代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#-----------------------------------------------------------------------
#亮度变换-增强、减弱
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.11.52.02.53.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.90.80.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)

输出结果如下图所示:


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

该部分关键代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#-----------------------------------------------------------------------
#颜色通道变换
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)

输出结果如下图所示:


5.高斯噪声和椒盐噪声

该部分关键代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#-----------------------------------------------------------------------
#添加高斯噪声和椒盐噪声
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)

输出结果如下图所示:


6.模拟怀旧和噪声添加

该部分关键代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#-----------------------------------------------------------------------
#模拟怀旧和噪声添加
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)

输出结果如下图所示:


五.完整代码

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# -*- coding: utf-8 -*-
"""
2022-12-24
By: Eastmount CSDN xiuzhang
"""
import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import 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))

    #旋转180M = 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.11.52.02.53.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.90.80.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张图像。

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


六.如何用GAN生成图像?

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

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

七.总结

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 娜璋AI安全之家 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
CV学习笔记(十二):图像金字塔
尺度,顾名思义就是说图像的尺寸和分辨率。在我们进行图像处理的时候,会经常对源图像的尺寸进行放大或者缩小的变换,进而转换为我们指定尺寸的目标图像。在对图像进行放大和缩小的变换的这个过程,我们称为尺度调整。
云时之间
2020/03/09
1.2K0
上下采样
算法:图像向上采样后,尺寸变为原来的4倍;向下采样后,尺寸变为原来的1/4,一幅图像在先后经过向下采样和向上采样或者先后经过向上采样和向下采样,所得到的图像尺寸大小和原始图像一致。图像金字塔是同一幅图像不同分辨率的子图集合。
裴来凡
2022/05/28
7820
上下采样
【从零学习OpenCV 4】图像金字塔
构建图像的高斯金字塔是解决尺度不确定性的一种常用方法。高斯金字塔是指通过下采样不断的将图像的尺寸缩小,进而在金字塔中包含多个尺度的图像,高斯金字塔的形式如图3-30所示,一般情况下,高斯金字塔的最底层为图像的原图,每上一层就会通过下采样缩小一次图像的尺寸,通常情况尺寸会缩小为原来的一半,但是如果有特殊需求,缩小的尺寸也可以根据实际情况进行调整。由于每次图像的尺寸都缩小为原来的一半,图像尺缩小的速度非常快,因此常见高斯金字塔的层数为3到6层。OpenCV 4中提供了pyrDown()函数专门用于图像的下采样计算,便于构建图像的高斯金字塔,该函数的函数原型在代码清单3-51中给出。
小白学视觉
2019/12/13
8150
CV学习笔记(十二):图像金字塔
尺度,顾名思义就是说图像的尺寸和分辨率。在我们进行图像处理的时候,会经常对源图像的尺寸进行放大或者缩小的变换,进而转换为我们指定尺寸的目标图像。在对图像进行放大和缩小的变换的这个过程,我们称为尺度调整。
云时之间
2020/03/19
7350
Python opencv图像处理基础总结(五) 图像金字塔 图像梯度 Canny算法边缘提取
图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效且概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低
叶庭云
2022/05/09
6960
Python opencv图像处理基础总结(五) 图像金字塔 图像梯度 Canny算法边缘提取
Python opencv图像处理基础总结(五) 图像金字塔 图像梯度 Canny算法边缘提取
图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低
叶庭云
2020/09/17
1.2K0
Python opencv图像处理基础总结(五)  图像金字塔  图像梯度  Canny算法边缘提取
【python-opencv】图像金字塔
通常,我们过去使用的是恒定大小的图像。但是在某些情况下,我们需要使用不同分辨率的(相同)图像。例如,当在图像中搜索某些东西(例如人脸)时,我们不确定对象将以多大的尺寸显示在图像中。在这种情况下,我们将需要创建一组具有不同分辨率的相同图像,并在所有图像中搜索对象。这些具有不同分辨率的图像集称为“图像金字塔”(因为当它们堆叠在底部时,最高分辨率的图像位于顶部,最低分辨率的图像位于顶部时,看起来像金字塔)。
西西嘛呦
2020/08/26
1.5K0
【python-opencv】图像金字塔
OpenCV Python 系列教程 4 - OpenCV 图像处理(上)
HSV 的色相范围为 [0,179],饱和度范围为 [0,255],值范围为 [0,255]。不同的软件使用不同的规模。
机器视觉CV
2019/07/15
3.1K0
OpenCV Python 系列教程 4 - OpenCV 图像处理(上)
Android OpenCV(十三):图像金字塔
参数二:dst,输出下采样后的图像,图像尺寸可以指定,但是数据类型和通道数与src相同,
Vaccae
2021/01/06
1.1K0
Android OpenCV(十三):图像金字塔
构建图像金字塔:探索 OpenCV 的尺度变换技术
在计算机视觉领域,图像金字塔是一种强大的技术,可用于在不同尺度下对图像进行分析和处理。金字塔的概念借鉴了古埃及的金字塔形状,其中每一级都是前一级的缩小版本。本篇博客将深入探讨如何构建图像金字塔,以及如何在实际应用中利用金字塔来解决各种计算机视觉问题。我们将使用 OpenCV 库和 Python 编程语言进行实际演示。
小蓝枣
2023/10/19
5520
构建图像金字塔:探索 OpenCV 的尺度变换技术
【走进OpenCV】图片缩放和图像金字塔
要缩小图像,一般推荐使用CV_INETR_AREA来插值;若要放大图像,推荐使用CV_INTER_LINEAR。
小白学视觉
2019/10/24
1.1K0
拉普拉斯金字塔
算法:拉普拉斯金字塔是对原图像进行低通滤波和降采样得到一个粗尺度的近似图像,即分解得到的低通近似图像,把这个近似图像经过插值,滤波,再计算它和原图像的插值,就得到分解的带通分量,下一级分解是在得到的低通近似图像上进行,迭代完成多尺度分解。
裴来凡
2022/05/28
5970
拉普拉斯金字塔
高斯金字塔
算法:高斯金字塔是信号的多尺度表示法,亦即将同一信号或图片多次的进行高斯模糊,并且向下取样,方向向上,逐渐丢失图像的信息,藉以产生不同尺度下的多组信号或图片以进行后续的处理。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
裴来凡
2022/05/28
7780
高斯金字塔
"大脑"生长系列(六)
上一讲是如何改变图像的分辨率和对比度,这一讲介绍一个听起来高大上的功能,图像金字塔,个人理解图像金字塔本质上也是图像大小的改变,只是改变的方式和算法有所不同。OpenCV实现了两种图像金字塔的功能,一种高斯金字塔,一种拉普拉斯金字塔。
视界音你而不同
2020/04/10
3610
"大脑"生长系列(六)
OpenCV金字塔图像分辨率重建与融合
图像金字塔是对一张输入图像先模糊再下采样为原来宽高的1/2(宽高缩小一半)、不断重复模糊与下采样的过程就得到了不同分辨率的输出图像,叠加在一起就形成了图像金字塔、所以图像金字塔是图像的空间多分辨率存在形式。这里的模糊是指高斯模糊,所以这个方式生成的金字塔图像又称为高斯金字塔图像。高斯金字塔图像有两个基本操作 reduce 是从原图生成高斯金字塔图像、生成一系列低分辨图像,OpenCV对应的相关API为:
OpenCV学堂
2018/11/06
1.6K0
opencv学习笔记python实现 图像金字塔(高斯金字塔与拉普拉斯金字塔)
使用拉普拉斯金字塔时,图像必须是2^n*2*m 使用拉普拉斯金字塔先要知道高斯金字塔 这两种过程是图片缩小与放大 缩小   reduce =  高斯模糊 + 降采样(pyrDown) 放大    ex
用户2965768
2018/09/29
3.1K0
opencv学习笔记python实现 图像金字塔(高斯金字塔与拉普拉斯金字塔)
OpenCV 图像变换之 —— 拉伸、收缩、扭曲和旋转
图像变换最直接的应用就是改变图像的形状、大小、方向等等,这些在OpenCV 中有部分现成的实现。
为为为什么
2022/08/09
11.3K0
OpenCV 图像变换之 —— 拉伸、收缩、扭曲和旋转
图像动态融合
算法:图像动态融合是以第一张图为主图,保留主图部分颜色信息和边缘信息,以第二张图为融入源,保留融入源部分颜色信息,动态调整融入比例。
裴来凡
2022/05/29
3830
图像动态融合
opencv(4.5.3)-python(十七)--图像金字塔
通常情况下,我们习惯于使用一个恒定大小的图像。但在某些情况下,我们需要处理不同分辨率的(相同)图像。例如,当我们在图像中搜索某个东西时,比如人脸,我们不确定该物体会以何种尺寸出现在所述图像中。在这种情况下,我们需要创建一组具有不同分辨率的相同图像,并在所有这些图像中搜索物体。这些具有不同分辨率的图像集被称为图像金字塔(因为当它们被保存在一个堆栈中,最高分辨率的图像在底部,最低分辨率的图像在顶部,它看起来像一个金字塔)。
用户9875047
2022/12/07
4130
opencv(4.5.3)-python(十七)--图像金字塔
C++ OpenCV图像上采样和降采样
图像金字塔是一种以多分辨率来解释图像的有效但概念简单的结构。应用于图像分割,机器视觉和图像压缩。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,直到达到某个终止条件才停止采样。金字塔的底部是待处理图像的高分辨率表示,而顶部是低分辨率的近似。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
Vaccae
2019/07/24
2K0
推荐阅读
相关推荐
CV学习笔记(十二):图像金字塔
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验