当前位置: 首页 > news >正文

深度学习之 imgaug (图像增强)学习笔记

深度学习之 imgaug (图像增强)

    • 前言
    • 1\. 安装和卸载
    • 2\. 示例
      • 2.1 基本使用
      • 2.2 包含常用的变换示例
    • 3 Augmenters常用函数
      • 3.1 iaa.Sequential()
      • 3.2 iaa.someOf()
      • 3.3 iaa.OneOf()
      • 3.4 iaa.Sometimes()
      • 3.5 iaa.WithColorspace()
      • 3.6 iaa.WithChannels()
      • 3.7 iaa.Noop()
      • 3.8 iaa.Lambda()
      • 3.9 iaa.AssertShape()
      • 3.10 iaa.Scale()
      • 3.11 iaa.CropAndPad()
      • 3.12 iaa.Pad()
      • 3.13 iaa.Crop()
      • 3.14 iaa.Fliplr()
      • 3.15 Flipud()
      • 3.16 iaa.ChangeColorspace()
      • 3.17 iaa.Grayscale()
      • 3.18 iaa.GaussianBlur()
      • 3.19 iaa.AverageBlur()
      • 3.20 iaa.MedianBlur()
      • 3.21 iaa.Convolve()
      • 3.22 iaa.Sharpen()
      • 3.23 iaa.Emboss()
      • 3.24 iaa.EdgeDetect()
      • 3.25 iaa.DirectedEdgeDetect()
      • 3.26 iaa.Add()
      • 3.27 iaa.AddElementwise()
      • 3.28 iaa.AdditiveGaussianNoise()
      • 3.29 iaa.Multiply()
      • 3.30 iaa.MultiplyElementwise()
      • 3.31 iaa.Dropout()
      • 3.32 iaa.CoarseDropout()
      • 3.33 iaa.Invert()
      • 3.34 iaa.ContrastNormalization()
      • 3.35 iaa.Affine()
      • 3.36 iaa.PiecewiseAffine()
      • 3.37 iaa.ElasticTransformation()
    • 4\. keypoint变换
    • 5\. Bounding Boxes变换
      • 5.1 BBox
      • 5.2 绘制bbox
      • 5.3 对图像使用增强方法后绘制
      • 5.4 提取目标区域
      • 5.5 裁剪bbox
      • 5.6 将bbox投射到其他图像上
      • 5.7 交集、并集、交并比
    • 6\. Stochastic Parameter
    • 7\. Blending/Overlaying images

前言

本文为本人学习imgaug 笔记,来源于

  1. Python 第三方模块之 imgaug (图像增强)
  2. Image Processing 必备(五):Imgaug之增强标记BoundingBox

imgaug是一个封装好的用来进行图像augmentation的python库,支持关键点(keypoint)和bounding box一起变换。

1. 安装和卸载

 
# 通过pypi安装
pip install imgaug# 卸载
pip uninstall imgaug

2. 示例

2.1 基本使用

首先定义一个变换序列,然后直接将图像batch传入即可:

from imgaug import augmenters as iaaseq = iaa.Sequential([iaa.Crop(px=(0, 16)), # 从每边裁剪图像0到16px(随机选择)iaa.Fliplr(0.5), #0.5是概率,水平翻转50%的图像iaa.GaussianBlur(sigma=(0, 3.0)) # 用0到3.0的σ模糊图像
])for batch_idx in range(1000):# 'images'应该是一个4D numpy数组的形状(N,高度,宽度,通道)# 或一个3D numpy数组列表,每个数组都有形状(高度、宽度、通道)。# 灰度图像必须有形状(高度,宽度,1)每个。# 所有图片必须有numpy的dtype uint8。值被期望在# 范围0-255。images = load_batch(batch_idx)images_aug = seq.augment_images(images)train_on_images(images_aug)

2.2 包含常用的变换示例

import cv2
import numpy as np
from imgaug import augmenters as iaa
import imgaug as ia# 定义一个lambda表达式,以p=0.5的概率去执行sometimes传递的图像增强
sometimes = lambda aug: iaa.Sometimes(0.5, aug)
# 建立一个名为seq的实例,定义增强方法,用于增强
aug = iaa.Sequential([iaa.Fliplr(0.5),  # 对50%的图像进行镜像翻转iaa.Flipud(0.2),  # 对20%的图像做左右翻转sometimes(iaa.Crop(percent=(0, 0.1))),# 这里沿袭我们上面提到的sometimes,对随机的一部分图像做crop操作# crop的幅度为0到10%# 或者 sometimes(iaa.Crop(px=(0, 16))),随机在距离边缘的0-16像素中选择crop范围# 对一部分图像做仿射变换sometimes(iaa.Affine(scale={"x": (0.8, 1.2), "y": (0.8, 1.2)},  # 图像缩放为80%到120%之间translate_percent={"x": (-0.2, 0.2), "y": (-0.2, 0.2)},  # 平移±20%之间rotate=(-45, 45),  # 旋转±45度之间shear=(-16, 16),  # 剪切变换±16度,(矩形变平行四边形)order=[0, 1],  # 使用最邻近差值或者双线性差值cval=(0, 255),  # 全白全黑填充mode=ia.ALL  # 定义填充图像外区域的方法)),# 使用下面的0个到5个之间的方法去增强图像。注意SomeOf的用法iaa.SomeOf((0, 5),[# 将部分图像进行超像素的表示。o(╥﹏╥)o用超像素增强作者还是第一次见,比较孤陋寡闻sometimes(iaa.Superpixels(p_replace=(0, 1.0),n_segments=(20, 200))),# 用高斯模糊,均值模糊,中值模糊中的一种增强。注意OneOf的用法iaa.OneOf([iaa.GaussianBlur((0, 3.0)),iaa.AverageBlur(k=(2, 7)),  # 核大小2~7之间,k=((5, 7), (1, 3))时,核高度5~7,宽度1~3iaa.MedianBlur(k=(3, 11)),]),# 锐化处理iaa.Sharpen(alpha=(0, 1.0), lightness=(0.75, 1.5)),# 浮雕效果iaa.Emboss(alpha=(0, 1.0), strength=(0, 2.0)),# 边缘检测,将检测到的赋值0或者255然后叠在原图上sometimes(iaa.OneOf([iaa.EdgeDetect(alpha=(0, 0.7)),iaa.DirectedEdgeDetect(alpha=(0, 0.7), direction=(0.0, 1.0)),])),# 加入高斯噪声iaa.AdditiveGaussianNoise(loc=0, scale=(0.0, 0.05 * 255), per_channel=0.5),# 将1%到10%的像素设置为黑色# 或者将3%到15%的像素用原图大小2%到5%的黑色方块覆盖iaa.OneOf([iaa.Dropout((0.01, 0.1), per_channel=0.5),iaa.CoarseDropout((0.03, 0.15), size_percent=(0.02, 0.05),per_channel=0.2),]),# 5%的概率反转像素的强度,即原来的强度为v那么现在的就是255-viaa.Invert(0.05, per_channel=True),# 每个像素随机加减-10到10之间的数iaa.Add((-10, 10), per_channel=0.5),# 像素乘上0.5或者1.5之间的数字.iaa.Multiply((0.5, 1.5), per_channel=0.5),# 将整个图像的对比度变为原来的一半或者二倍iaa.ContrastNormalization((0.5, 2.0), per_channel=0.5),# 将RGB变成灰度图然后乘alpha加在原图上iaa.Grayscale(alpha=(0.0, 1.0)),# 把像素移动到周围的地方。这个方法在mnist数据集增强中有见到sometimes(iaa.ElasticTransformation(alpha=(0.5, 3.5), sigma=0.25)),# 扭曲图像的局部区域sometimes(iaa.PiecewiseAffine(scale=(0.01, 0.05)))],random_order=True  # 随机的顺序把这些操作用在图像上)],random_order=True  # 随机的顺序把这些操作用在图像上
)# 数据增强,针对单张图片
image = cv2.imread('1.jpg', 0)
h = image.shape[0]
w = image.shape[1]
enhance_num = 32aug_example_img = aug.augment_image(image=image)
print(image.shape, aug_example_img.shape)# 生成一个图片列表example_images = np.array([image for _ in range(enhance_num)],dtype=np.uint8
)
aug_imgs = aug(images=example_images)
# images_aug = aug.augment_images(images=img_array)
# 显示图片
ia.show_grid(aug_imgs, rows=4, cols=8)
# 保存图片
for i in range(aug_imgs.shape[0]):img = aug_imgs[i]cv2.imwrite("aug_%d.jpg" % i, img)# 保存为一张图片
img_array = np.array([image] * enhance_num, dtype=np.uint8)
write_img = np.zeros(shape=(h, (w+10) * enhance_num, 3), dtype=np.uint8)
for j, item in enumerate(aug_imgs):write_img[:, j * (w + 10): j * (w + 10) + w, :] = item

3 Augmenters常用函数

先导入Augmenters类

from imgaug import augmenters as iaa

3.1 iaa.Sequential()

产生一个处理图片的 Sequential 函数原型:

from imgaug import augmenters as iaa
iaa.Sequential(children=None,random_order=False,name=None,deterministic=False,random_state=None)

参数:

  • children: 想要应用在图像上的Augmenter或者Augmenter集合。默认None
  • random_order: bool类型, 默认False。是否对每个batch的图片应用不同顺序的Augmenter list。当设置为True时,不同batch之间图片的处理顺序都会不一样,但是同一个batch内顺序相同。
  • deterministic: bool类型, 默认False。

3.2 iaa.someOf()

将Augmenter中的部分变换应用在图片处理上,而不是应用所有的Augmenter。例如:可以定义20种变换,但每次只选择其中的5个。但是不支持固定选择某一个Augmenter。

函数原型:

from imgaug import augmenters as iaa
iaa.SomeOf(n=None,children=None,random_order=False,name=None,deterministic=False,random_state=None)

参数:

  • n: 从总的Augmenters中选择多少个。可以是一个int, tuple, list或者随机值。
  • random_order: 是否每次顺序不一样。

例子:

# 每次选择一个翻转方式
seq = iaa.SomeOf(1, [iaa.Fliplr(1.0),iaa.Flipud(1.0)])
imgs_aug = seq.augment_images(imgs)# 每次使用1~3个Augmenter来处理图片,每个batch中的Augmenters顺序一样。
seq = iaa.SomeOf((1, 3), [iaa.Fliplr(1.0),iaa.Flipud(1.0),iaa.GaussianBlur(1.0)])
imgs_aug = seq.augment_images(imgs)# 每次使用1到多个Augmenter来处理图片,每个batch中的Augmenters顺序不一样。
seq = iaa.SomeOf((1, None), [iaa.Fliplr(1.0),iaa.Flipud(1.0),iaa.GaussianBlur(1.0)], random_order=True)
imgs_aug = seq.augment_images(imgs)

3.3 iaa.OneOf()

每次从一系列Augmenters中选择一个来变换。

iaa.OneOf(children,name=None,deterministic=False,random_state=None)

参数含义与上面一样。

3.4 iaa.Sometimes()

对batch中的一部分图片应用一部分Augmenters,剩下的图片应用另外的Augmenters。

iaa.Sometimes(p=0.5,then_list=None,else_list=None,name=None,deterministic=False,random_state=None)
  • p: float。多大比例的图片会被 Augmente。
  • then_list: Augmenter集合。p概率的图片进行变换的Augmenters。
  • else_list: 1-p概率的图片会被进行变换的Augmenters。注意变换的图片应用的Augmenter只能是then_list或者else_list中的一个。

3.5 iaa.WithColorspace()

在某个特定的颜色空间对图像进行变换。即:先将图片从一个颜色空间变换到另一个颜色空间,然后在另一个颜色空间中对图像进行变换,最后再变换回原来的颜色空间。

iaa.WithColorspace(to_colorspace,from_colorspace='RGB',children=None,name=None,deterministic=False,random_state=None)
  • to_colorspace: 要变换的颜色空间。有以下选择:RGB, BGR, GRAY, CIE, YCrCb, HSV, HLS, Lab, Luv
  • from_colorspace: 原来的颜色空间, 默认RGB。
  • children: 要执行的变换。
# 先将图片从RGB变换到HSV,然后将H值增加10,然后再变换回RGB。
aug = iaa.WithColorspace(to_colorspace="HSV", from_colorspace="RGB",children=iaa.WithChannels(0, iaa.Add(10)))

3.6 iaa.WithChannels()

从图片中挑选出一个Channel来进行变换,变换完了之后再将该channel merge回去。

iaa.WithChannels(channels=None,children=None,name=None,deterministic=False,random_state=None)

参数:

  • channels: int或者int list。哪些channel要被用来变换。
  • children: channel被选出来之后要进行哪些变换。

3.7 iaa.Noop()

不进行任何变换。某些情况下只想使用一个Augmenter作为占位符,这样可以继续调用augment_image()函数,但实际不作变换。例如进行测试的时候可以使用这个。

3.8 iaa.Lambda()

自定义一些变换函数。

iaa.Lambda(func_images,func_keypoints,name=None,deterministic=False,random_state=None)

参数:

  • func_images: 对每一个image调用此函数。该函数必须返回变换后的图片。该函数的形式为:
function(images, random_state, parents, hooks)
  • func_keypoints: 对每个图像的关键点进行变换的函数。该函数返回变换后的keypoint。该函数形式为:
function(keypoints_on_images, random_state, parents, hooks)

例子:

def func_images(images, random_state, parents, hooks):images[:, ::2, :, :] = 0return imagesdef func_keypoints(keypoints_on_images, random_state, parents, hooks):return keypoints_on_imagesaug = iaa.Lambda(func_images=func_images,func_keypoints=func_keypoints
)

将每张图片没隔两行的像素点变成黑色的条带,关键点保留。

3.9 iaa.AssertShape()

assert要变换的图片和keypoint的shape。如果不满足就抛出异常。

iaa.AssertShape(shape,check_images=True,check_keypoints=True,name=None,deterministic=False,random_state=None)

参数:

  • shape: 元组,通常形式为(N, H, W, C)。元组中每个元素的值可以为:None, int, 两个int类型的tuple或者一个int类型的list。如果是None,表示所有值都可以接受。如果是int,则只有对应的位置是该值才会被接受。如果是int类型的tuple,例如(a,b),则对应位置的值必须是a<=x
# 检查输入的每张图片是否是32×32×3的,如果是则执行水平翻转,否则报错
seq = iaa.Sequential([iaa.AssertShape((None, 32, 32, 3)),iaa.Fliplr(0.5)
])# 先检查图片的高度是否是32<=H<64, 宽度是否是32, channel是否是1或者3。如果都满足则执行水平翻转,否则报错。
seq = iaa.Sequential([iaa.AssertShape((None, (32, 64), 32, [1, 3])),iaa.Fliplr(0.5)
])

3.10 iaa.Scale()

将图像缩放到固定大小。

iaa.Scale(size,interpolation='cubic',name=None,deterministic=False,random_state=None)

参数:

  • size: 字符串”keep”,此时保持图像原大小不坐缩放。如果是一个整数n,则缩放成(n, n)。如果是一个float v,则每张图片会被缩放成(H*v, W*v),此时每张图像大小仍然不一样。如果是一个tuple类型(a, b), 如果a、b中至少有一个小数,则从[a,b]中挑选一个数作为缩放比例。如果a、b都是整数,则从[a,b]中挑选一个整数作为缩放后的大小。如果是1个list,则list中的数要么全是整数,要么全是小数(不能混用)。如果是一个dict类型,则该dict必须有两个key: height和width。每个key的值仍然可以按照上面的方法选取。此外, key的值还可以是”keep-aspect-ratio”, 表示按照比例缩放。
  • interpolation: 缩放方法。如果是All, 则会随机从下面挑选一个: nearest、linear、area、cubic,注意每张图片可能不一样。如果是int,则应该是下面的一种:cv2.INTER_NEAREST, cv2.INTER_LINEAR, cv2.INTER_AREA,cv2.INTER_CUBIC。如果是string,则该种方法会被一直使用,必须是下面的一种: nearest, linear, area, cubic。如果是int list或者string list, 则每张图片会从中随机选取一个。

3.11 iaa.CropAndPad()

截取(crop)或者填充(pad),填充时,被填充区域为黑色。

iaa.CropAndPad(px=None,percent=None,pad_mode='constant',pad_cval=0,keep_size=True,sample_independently=True,name=None,deterministic=False,random_state=None)

参数:

  • px: 想要crop(negative values)的或者pad(positive values)的像素点。注意与percent不能同时存在。如果是None, pixel级别的crop不会被使用。int或者int list与上面相同。如果是一个4个元素的tuple,那么4个元素分别代表(top, right, bottom, left),每个元素可以是int或者int tuple或者int list。
  • percent:按比例来crop或者pad, 与px相同。但是两者不能同时存在。
  • pad_mode: 填充方式。可以是All, string, string list。可选的填充方式有: constant, edge, linear_ramp, maximum, median, minimum, reflect, symmetric, wrap。具体含义可查numpy文档。
  • pad_cval: float、int、float tuple、int tuple、float list、int list。当pad_mode=constant的时候选择填充的值。
  • keep_size: bool类型。经过crop后,图像大小会改变。如果该值设置为1,则在crop或者pad后再缩放成原来的大小。
  • sample_independently : bool类型。如果设置为False,则每次从px或者percent中选出来的值会作用在四个方位。

3.12 iaa.Pad()

与iaa.CropAndPad()相同,只接受positive values。

3.13 iaa.Crop()

与iaa.CropAndPad()相同,只接受negative values。

3.14 iaa.Fliplr()

水平镜面翻转。

iaa.Fliplr(p=0, name=None, deterministic=False, random_state=None)

参数:

  • p: int或者float,每张图片呗翻转的概率

3.15 Flipud()

上下翻转,与上面相同。

3.16 iaa.ChangeColorspace()

改变图像空间。

iaa.ChangeColorspace(to_colorspace, from_colorspace='RGB', alpha=1.0, name=None, deterministic=False, random_state=None)

参数:

  • to_colorspace: 见上。
  • from_colorspace: 见上。
  • alpha: 覆盖旧的颜色空间时,新颜色空间的Alpha值。为int, float, int tuple, float tuple

3.17 iaa.Grayscale()

变成灰度图。

iaa.Grayscale(alpha=0, from_colorspace='RGB', name=None, deterministic=False, random_state=None)

参数:

  • alpha: 覆盖旧的颜色空间时,新颜色空间的Alpha值。

3.18 iaa.GaussianBlur()

高斯扰动。

iaa.GaussianBlur(sigma=0, name=None, deterministic=False, random_state=None)

参数:

  • sigma: 高斯变换的标准差。可为float, float tuple。常见的有0,不扰动。3,强扰动。

3.19 iaa.AverageBlur()

从最邻近像素中取均值来扰动。

iaa.AverageBlur(k=1, name=None, deterministic=False, random_state=None)

参数:

  • k:窗口大小。可为int, int tuple。当为int tuple时,如果每个元素也是tuple,每个元素分别作为height和width,窗口大小不一致。

3.20 iaa.MedianBlur()

通过最近邻中位数来扰动。

iaa.MedianBlur(k=1, name=None, deterministic=False, random_state=None)

与上面相同。

3.21 iaa.Convolve()

对图像使用卷积。

iaa.Convolve(matrix=None, name=None, deterministic=False, random_state=None)
  • matrix: 卷积矩阵。

3.22 iaa.Sharpen()

锐化。

iaa.Sharpen(alpha=0, lightness=1, name=None, deterministic=False, random_state=None)

3.23 iaa.Emboss()

浮雕效果。

iaa.Emboss(alpha=0, strength=1, name=None, deterministic=False, random_state=None)

3.24 iaa.EdgeDetect()

边缘检测。

iaa.EdgeDetect(alpha=0, name=None, deterministic=False, random_state=None)

3.25 iaa.DirectedEdgeDetect()

特定方向的边缘检测。

iaa.DirectedEdgeDetect(alpha=0, direction=(0.0, 1.0), name=None, deterministic=False, random_state=None)

3.26 iaa.Add()

随机加上一个值。

iaa.Add(value=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.27 iaa.AddElementwise()

按像素加。

iaa.AddElementwise(value=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.28 iaa.AdditiveGaussianNoise()

添加高斯噪声。

iaa.AdditiveGaussianNoise(loc=0, scale=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.29 iaa.Multiply()

给图像中的每个像素点乘一个值使得图片更亮或者更暗。

iaa.Multiply(mul=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.30 iaa.MultiplyElementwise()

按像素值乘。

iaa.MultiplyElementwise(self, mul=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.31 iaa.Dropout()

随机去掉一些像素点, 即把这些像素点变成0。

iaa.Dropout(p=0, per_channel=False, name=None, deterministic=False, random_state=None)

3.32 iaa.CoarseDropout()

将矩形框的值设置为0。

iaa.CoarseDropout(p=0, size_px=None, size_percent=None, per_channel=False, min_size=4, name=None, deterministic=False, random_state=None)

3.33 iaa.Invert()

将每个像素值p变成255-p。

iaa.Invert(p=0, per_channel=False, min_value=0, max_value=255, name=None, deterministic=False, random_state=None)

3.34 iaa.ContrastNormalization()

改变图像的对比度。

iaa.ContrastNormalization(alpha=1.0, per_channel=False, name=None, deterministic=False, random_state=None)

3.35 iaa.Affine()

仿射变换。包含:平移(Translation)、旋转(Rotation)、放缩(zoom)、错切(shear)。仿设变换通常会产生一些新的像素点,我们需要指定这些新的像素点的生成方法,这种指定通过设置cvalmode两个参数来实现。参数order用来设置插值方法。

iaa.Affine(scale=1.0,translate_percent=None,translate_px=None,rotate=0.0,shear=0.0,order=1,cval=0,mode='constant',name=None, deterministic=False, random_state=None)

参数:

  • scale: 图像缩放因子。1表示不缩放,0.5表示缩小到原来的50%。此参数可以是float, float tuple, dict。如果是float, 则所有图片按照这种比例缩放。如果是float tuple, 则随机选取一个值来进行缩放,此时x-axisy-axis的缩放比例相同。如果是一个dict,则应该有两个key:x, y,每个xy的值都可以是float, float tuple,此时x-axisy-axis的缩放比例不一样。
  • translate_percent: 平移比例,0表示不平移,0.5表示平移50%。可以是float, float tuple, dict,具体含义与scale相同。用正负来表示平移方向。
  • translate_px: 按照像素来进行平移。可以是int, int tuple, dict,具体含义与translate_percent相同。
  • rotate: 平移角度,0~360度之间,正负也可以表示方向。可以为float, float tuple
  • shear: 错切的程度,0~360度之间,正负表示方向。可以为float, int, float tuple, int tuple
  • order: 插值顺序,与skimage中定义相同。下面0和1方法快,3比较慢,4、5特别慢。可以是int, int list, ia.ALL。如果是ia.ALL,则每次从所有的插值方法中随机选取。
    • 0:最邻近插值。
    • 1: 双线性插值(默认)。
    • 2: 双二次插值(不推荐)。
    • 3:双三次插值。
    • 4: Bi-quartic。
    • 5:Bi-quintic。
  • cval: 当平移后使用常量填充的时候指定填充的常量值,只有在mode=constant的时候才会生效。可以是int, float, tuple, ia.ALL。如果是ia.ALL,则会从[0,255]之间随机选取一个值填充。
  • mode: 采用何种方式填充经过变换后空白的像素点。可以是string, string list, ia.ALL。基本用法与上面相同。其中字符串的选取范围是:
    • constant: 采用一个常量填充。
    • edge: 边缘填充。
    • symmetric: 镜面对称填充。
    • reflect: Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis.
    • wrap: Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning.

3.36 iaa.PiecewiseAffine()

随机放置一些规则的网格点然后移动这些点的周围的像素。这回导致局部的扭曲。

iaa.PiecewiseAffine(scale=0,nb_rows=4,nb_cols=4,order=1,cval=0,mode='constant',name=None, deterministic=False, random_state=None)

3.37 iaa.ElasticTransformation()

通过移动局部像素来变换。

iaa.ElasticTransformation(alpha=0,sigma=0,name=None,deterministic=False,random_state=None)

4. keypoint变换

imgaug支持在图像变换的同时变换图像中的关键点。例子如下:

import imgaug as ia
from imgaug import augmenters as iaaiaa.seed(1)image=ia.quokka(size=(256,256))# 定义4个关键点
keypoints=ia.KeypointsOnImage([ia.Keypoint(x=65, y=100),ia.Keypoint(x=75, y=200),ia.Keypoint(x=100, y=100),ia.Keypoint(x=200, y=80)
], shape=image.shape)# 定义一个变换序列
seq=iaa.Sequential([iaa.Multiply((1.2, 1.5)), # 改变亮度,不影响关键点iaa.Affine(rotate=10,scale=(0.5, 0.7)) # 旋转10度然后缩放,会影响关键点
])# 固定变换序列,之后就可以先变换图像然后变换关键点,这样可以保证两次的变换完全相同。
# 如果调用次函数,需要在每次batch的时候都调用一次,否则不同的batch执行相同的变换。
seq_det = seq.to_deterministic()# 转换成list或者batch来变换。由于只有一张图片, 因此用[0]来取出该图和关键点。
image_aug = seq_det.augment_images([image])[0]
keypoints_aug = seq_det.augment_keypoints([keypoints])[0]# print coordinates before/after augmentation (see below)
# use after.x_int and after.y_int to get rounded integer coordinates
for i in range(len(keypoints.keypoints)):before = keypoints.keypoints[i]after = keypoints_aug.keypoints[i]print("Keypoint %d: (%.8f, %.8f) -> (%.8f, %.8f)" % (i, before.x, before.y, after.x, after.y))# 将关键点画在图片上。
# image with keypoints before/after augmentation (shown below)
image_before = keypoints.draw_on_image(image, size=7)
image_after = keypoints_aug.draw_on_image(image_aug, size=7)fig, axes = plt.subplots(2, 1, figsize=(20, 15))
plt.subplots_adjust(left=0.2, bottom=0.2, right=0.8, top=0.8, hspace=0.3, wspace=0.0)
axes[0].set_title("image before")
axes[0].imshow(image_before)
axes[1].set_title("image after augmentation")
axes[1].imshow(image_after)plt.show()

5. Bounding Boxes变换

对应于BBox,存在两个API,一个用于生成BBox,另一个整合BBox。

  • BoundingBox

  • BoundingBoxesOnImage

5.1 BBox

对于BBox,通常用于目标检测中对物体进行标记,此处为矩形。因此,其通过左上角点和右下角点的坐标表示(x1,y1,x2,y2)。

其只受改变图像几何外观的图像增强技术的影响,高斯噪声之类的对其没有影响。

API: BoundingBox

BBox的输入参数:

imgaug.augmentables.bbs.BoundingBox(x1, y1, x2, y2, label=None):

可以看到,包含5个输入,4个坐标和1个物体类别标签label。

BoundingBox有一些重要的属性:.x1, .y1, .x2, .y2, .height, .width, .center_x, .center_y, .area

BBox的一些方法:

  • project(from_shape, to_shape) : 投射一个bbox从一个尺寸大小的图像到另一个尺寸大小。

  • *extend([all_sides], [top], [right], [bottom], [left]) *

  • *intersection(other, [default]) * :交集

  • *union(other) * :并集

  • *iou(other) * : 交并比

  • *is_fully_within_image(image) * 判断所有的bbox是否都在图像内

  • *is_partly_within_image(image) * 确定bbox至少有一部分在图像内

  • *clip_out_of_image(image) * :剪切掉在图像外侧的BBox

  • *shift([x], [y]) * : 移动bbox

  • *draw_on_image(image, [color], [alpha], [size], [copy], [raise_if_out_of_image]) *:绘制BBox和它的label

  • *draw_label_on_image(image, [color], [color_text], [color_bg], [alpha], [size], [size_text], [height], [copy], [raise_if_out_of_image]) * :只绘制label

  • *draw_box_on_image(image, [color], [alpha], [size], [copy], [raise_if_out_of_image) * :只绘制边框

  • *extract_from_image(image, [pad], [pad_max], [prevent_zero_size] *:从图像中提取边框中包含的像素

API:BoundingBoxesOnImage

BoundingBoxesOnImage()输入参数:

imgaug.augmentables.bbs.BoundingBoxesOnImage(bounding_boxes, shape)

BoundingBoxesOnImage中包含的一些方法:

  • on(image): 图形变化后bbox的再计算

  • *from_xyxy_array(xyxy, shape) *: 通过(N, 4)numpy数组生成

  • *to_xyxy_array([dtype]) *: 生成(N, 4)的numpy数组

  • *draw_on_image([color], [alpha], [size], [copy], [raise_if_out_of_image]) *:绘制bbox和image

  • *remove_out_of_image([fully], [partly]) *: 移除掉一些完全不在或者部分不在图像中的bbox

  • *clip_out_of_image() *: 剪切掉所有的bbox

  • *shift([x], [y]) *:平移所有的bbox

另外,imgaug中还有一些其他的API,例如增强BBOx和图像aug.augment(images=…, bounding_boxes=…) && aug.augment_bounding_boxes()

5.2 绘制bbox

import imgaug as ia
import imageio
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
%matplotlib inline
ia.seed(1)
img = imageio.imread("samoye.jpg")
bbs = BoundingBoxesOnImage([BoundingBox(x1=65, y1=1, x2=417, y2=396)], shape=img.shape)
ia.imshow(bbs.draw_on_image(img, size=2))

png

5.3 对图像使用增强方法后绘制

 # 定义方法
from imgaug import augmenters as iaa
ia.seed(1)seq = iaa.Sequential([iaa.GammaContrast(1.5),iaa.Affine(translate_percent={"x":0.1}, scale=0.8)])# 作用于图像和bbox上
image_aug, bbs_aug = seq(image=img, bounding_boxes=bbs)# 取出结果
bbs_aug[0].x1, bbs_aug[0].y1, bbs_aug[0].x2, bbs_aug[0].y2# 绘制
ia.imshow(bbs_aug.draw_on_image(image_aug, size=2))

png

image_aug, bbs_aug = iaa.Affine(rotate=45)(image=img, bounding_boxes=bbs)
ia.imshow(bbs_aug.draw_on_image(image_aug, size=1))

png

官方教程中使用的图像旋转后可以看到bbox,但bbox并未很好的跟随目标进行旋转。这里使用的图像旋转后,并不能看到bbox。官方教程中解释说这种问题源于非目标像素是边框的一部分。在旋转之后,必须绘制一个新的边界框来合并这些非对象像素。

bbox的draw_on_image()方法同样可以通过color、size、alpha等参数调节bbox的颜色 粗细 透明度。

import numpy as np
image_bbs = np.copy(img)
image_bbs = bbs.draw_on_image(img, color=[255, 0, 0], size=3)
print("color=[255,0,0],size=3,")
ia.imshow(image_bbs)
print("color=[0,255,0],size=10,alpha=0.5")
image_bbs_1=bbs.draw_on_image(img, color=[0,255,0],size=10,alpha=0.5)ia.imshow(image_bbs_1)
color=[255,0,0],size=3,

png

color=[0,255,0],size=10,alpha=0.5

png

从中又可以看出,当size较大时,靠近边缘的bbox边界有可能绘制不出。

另外,bbox通常用于目标检测,需要添加目标的label进行可视化。bbox中还包含label的字段。当bbox初始化时包含了label,显示时就会直接显示label;若初始化时未赋值label,则需要赋值才可以显示。

bbs_label = bbs.deepcopy()
bbs_label[0].label = "dog"image_bbs = bbs_label.draw_on_image(img, size=1)
ia.imshow(image_bbs)

png

但由于上边框贴近图像边缘,label并未绘制显示。

换一张图像…

image = imageio.imread("fox.jpg")bbox = BoundingBoxesOnImage([BoundingBox(x1=58, y1=19, x2=203, y2=183)], shape=image.shape)
bbox[0].label = "fox"
image_bbox = bbox.draw_on_image(image, size=2)
ia.imshow(image_bbox)

png

5.4 提取目标区域

BoundingBox包含extract_from_image(image)方法,可以提取出目标区域的图像。

fox = bbox.bounding_boxes[0].extract_from_image(image)
ia.imshow(fox)

png

如果想要提取到目标及目标周边的一些区域,可以结合使用extend方法,先将bbox进行延伸,再提取延伸后的bbox区域的图像。

fox = bbox.bounding_boxes[0].extend(all_sides=0, left=30, right=10).extract_from_image(image)
ia.imshow(fox)

png

除了extend方法,shift方法可以对bbox进行移动,就像Keypoints。

bb = bbox.bounding_boxes[0].shift(x=20, y=20)
ia.imshow(bb.draw_on_image(image, size=2))
ia.imshow(bb.extract_from_image(image))

png

png

综上所述,extend可以更改bbox的形状,可以扩张或者缩小bbox;而shift只能对bbox进行平移,不会影响bbox的尺寸。

同时,当对原有的bbox往y轴方向移动20个像素点,bbox将会处于图像外界。如上述第二张图像,会有一溜黑边。当然,如果不希望出现这种情况,可以增加参数pad=False,如下述图所示,生成的图像将不会有黑边。

bb = bbox.bounding_boxes[0].shift(x=20, y=20)
ia.imshow(bb.extract_from_image(image, pad=False))

png

5.5 裁剪bbox

当图像经过变换后,对应的bbox有可能部分处于图像的外侧,剪掉图像平面外的边界框的部分可以使用.clip_out_of_image()方法。下述代码首先将bbox移动到部分处于图像外侧,并对bbox进行裁剪。

print("-------------------")
print("shifted by 50 px - y")
print("-------------------")
bb = bbox.bounding_boxes[0].shift(y=50)
print("before clip")
ia.imshow(bb.draw_on_image(image, size=2))
ia.imshow(bb.extract_from_image(image))
bb_clip =bb.clip_out_of_image(image.shape)
print("after clip")
ia.imshow(bb_clip.draw_on_image(image, size=2))
ia.imshow(bb_clip.extract_from_image(image))
-------------------
shifted by 50 px - y
-------------------
before clip

png

png

after clip

png

png

可以看出,当剪切掉图像外侧的bbox后,在原图中显示的bbox可以很好的显示边界。

5.6 将bbox投射到其他图像上

与Keypoints相同,bbox也具有应对图像缩放后保持bbox一致的方法:

  • project

  • on

import numpy as np
import imageio
import imgaug as ia
from imgaug.augmentables.bbs import BoundingBox, BoundingBoxesOnImage
from imgaug import augmenters as iaa 
%matplotlib inline
img = imageio.imread("koala.jpg")
bbox = BoundingBoxesOnImage([BoundingBox(x1=26, y1=8, x2=109, y2=160), BoundingBox(x1=39, y1=4, x2=245, y2=194)], shape=img.shape)
bbox[0].label = "koala"
bbox[1].label = "koala"
ia.imshow(bbox.draw_on_image(img, size=2))
print(img.shape)

png

(194, 259, 3)

将图像缩放到120*120

img_resize = ia.imresize_single_image(img, (120, 120))
ia.imshow(img_resize)

png

print("Bounding box without changes:")
ia.imshow(bbox.draw_on_image(img_resize, size=2))print("Bounding box with project(from, to)")  # 需要对bbox中的Boundingbox进行处理
ia.imshow(bbox.bounding_boxes[0].project(from_shape=img.shape, to_shape=img_resize.shape).draw_on_image(img_resize, size=2, copy=False))
ia.imshow(bbox.bounding_boxes[1].project(from_shape=img.shape, to_shape=img_resize.shape).draw_on_image(img_resize, size=2, copy=False))print("Bounding box with on(shape)")   # 可以对整个bbox进行处理
ia.imshow(bbox.on(img_resize.shape).draw_on_image(img_resize, color=(255,255,0), size=2))
Bounding box without changes:

png

Bounding box with project(from, to)

png

png

Bounding box with on(shape)

png

5.7 交集、并集、交并比

bbox之间通常会计算IoU,imgaug中提供了相应的方法:

  • BoundingBox.intersection(other_bounding_box)

  • BoundingBox.union(other_bounding_box)

  • BoundingBox.iou(other_bounding_box)

1. intersection

bb_intersection = bbox.bounding_boxes[0].intersection(bbox.bounding_boxes[1])
ia.imshow(bb_intersection.draw_on_image(img, size=2))

png

如上图所示,返回的bb_intersection实际上是两个bbox交集的bbox。

同时,可以通过bb_intersection获取到交集的高度、宽度、面积等信息。

print("The intersection has a height of %.4f, width of %.4f and an area of %.4f"%(
bb_intersection.height, bb_intersection.width, bb_intersection.area))
The intersection has a height of 152.0000, width of 70.0000 and an area of 10640.0000

2. union

bb_union = bbox.bounding_boxes[0].union(bbox.bounding_boxes[1])
ia.imshow(bb_union.draw_on_image(img, size=2))

png

如上图所示,返回的bb_union实际上是两个bbox并集的bbox。

同理,可以通过bb_bb_union获取到交集的高度、宽度、面积等信息。

print("The union has a height of %.4f, width of %.4f and an area of %.4f"%(
bb_union.height, bb_union.width, bb_union.area))
The union has a height of 190.0000, width of 219.0000 and an area of 41610.0000

3. IoU

iou = bbox.bounding_boxes[0].iou(bbox.bounding_boxes[1])
print("IoU: %.4f"%(iou))
IoU: 0.2588

6. Stochastic Parameter

在做变换的时候,我们希望每张图片的变换都不一样,通过参数随机化选取可以实现。但是想要复现之前的变换,需要通过determinism来实现,比较繁琐。为了避免这种情况,使用Stochastic Parameters来实现。这个变量通常是一个抽象的概率分布,例如正太分布、均匀分布等等。通常所有的augmenter都能接受这个参数,这样就很方便控制变量范围。他们都可以和determinism结合。

例子:

from imgaug import augmenters as iaa
from imgaug import parameters as iapseq = iaa.Sequential([iaa.GaussianBlur(sigma=iap.Uniform(0.0, 1.0)),iaa.ContrastNormalization(iap.Choice([1.0, 1.5, 3.0],p=[0.5, 0.3, 0.2])),iaa.Affine(rotate=iap.Normal(0.0, 30),translate_px=iap.RandomSign(iap.Poisson(3))),iaa.AddElementwise(iap.Discretize((iap.Beta(0.5, 0.5) * 2 - 1.0) * 64)),iaa.Multiply(iap.Positive(iap.Normal(0.0, 0.1)) + 1.0)
])

所有可用的概率分布有:

6.1 正态分布

Normal(loc, scale): 均值为loc,标准差scale。

from imgaug import parameters as iap
params = [iap.Normal(0, 1),iap.Normal(5, 3),iap.Normal(iap.Choice([-3, 3]), 1),iap.Normal(iap.Uniform(-3, 3), 1)
]
iap.show_distributions_grid(params)

6.2 拉普拉斯分布

Laplace(loc, scale): 峰值loc, 宽度scale:

from imgaug import parameters as iap
params = [iap.Laplace(0, 1),iap.Laplace(5, 3),iap.Laplace(iap.Choice([-3, 3]), 1),iap.Laplace(iap.Uniform(-3, 3), 1)
]
iap.show_distributions_grid(params)

6.3 其他连续概率分布还有:

  • 卡方分布(ChiSquare)
  • 韦伯分布(Weibull)
  • 均匀分布(Uniform )
  • Beta分布

6.4 离散概率分布

  • 二项分布(Binomial)
  • 离散均匀分布(DiscreteUniform)
  • 泊松分布(Poisson distribution)

6.5 对分布的数学运算

imgaug支持随机参数的算术运算。 允许修改从分布中抽取的值或者将几个分布相互组合。支持的操作有:

  • Add
  • Subtract
  • Multiply
  • Divide
  • Power

6.6 特殊参数

支持的操作有:

  • Deterministic
  • Choice
  • Clip
  • Discretize
  • Absolute
  • RandomSign
  • ForceSign
  • Positive
  • Negative
  • FromLowerResolution

具体含义和用法见文档。

7. Blending/Overlaying images

augment会直接改变图片而把原图舍弃掉了。有时我们需要改变图像的局部,或者将原来的图片跟新变换的图片结合起来。这可以通过给变换前后的图片配上一定的权重(αα参数)或者使用一个pixel-wise的mask。
一个例子如下:

# First row
iaa.Alpha((0.0, 1.0),first=iaa.MedianBlur(11),per_channel=True
)# Second row
iaa.SimplexNoiseAlpha(first=iaa.EdgeDetect(1.0),per_channel=False
)# Third row
iaa.SimplexNoiseAlpha(first=iaa.EdgeDetect(1.0),second=iaa.ContrastNormalization((0.5, 2.0)),per_channel=0.5
)# Forth row
iaa.FrequencyNoiseAlpha(first=iaa.Affine(rotate=(-10, 10),translate_px={"x": (-4, 4), "y": (-4, 4)}),second=iaa.AddToHueAndSaturation((-40, 40)),per_channel=0.5
)# Fifth row
iaa.SimplexNoiseAlpha(first=iaa.SimplexNoiseAlpha(first=iaa.EdgeDetect(1.0),second=iaa.ContrastNormalization((0.5, 2.0)),per_channel=True),second=iaa.FrequencyNoiseAlpha(exponent=(-2.5, -1.0),first=iaa.Affine(rotate=(-10, 10),translate_px={"x": (-4, 4), "y": (-4, 4)}),second=iaa.AddToHueAndSaturation((-40, 40)),per_channel=True),per_channel=True,aggregation_method="max",sigmoid=False
)

相关文章:

深度学习之 imgaug (图像增强)学习笔记

深度学习之 imgaug &#xff08;图像增强&#xff09;前言1\. 安装和卸载2\. 示例2.1 基本使用2.2 包含常用的变换示例3 Augmenters常用函数3.1 iaa.Sequential()3.2 iaa.someOf()3.3 iaa.OneOf()3.4 iaa.Sometimes()3.5 iaa.WithColorspace()3.6 iaa.WithChannels()3.7 iaa.No…...

mysql字符串等值查询中条件字段值末尾有空格也能查到数据问题

一、事故还原 我们仍然使用学生信息表&#xff0c;但是我们只需要保留两个字段即可&#xff1a; CREATE TABLE student_info (id int(11) NOT NULL AUTO_INCREMENT COMMENT 学号,name varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT 姓名, PRIMARY KEY (id) ) ENGINEIn…...

一个关于事件溯源Event Sourcing的小荔枝,Golang实现

最后更新于2023年3月1日 10:23:13 参考的这个文章&#xff1a;https://martinfowler.com/eaaDev/EventSourcing.html 用C sharp实现的&#xff0c;我改写成Golang了 最简单的例子 func main() {eProc : NewEventProcessor()//refact : Cargo{Name: "Refactoring"}…...

Vue3 组合式函数,实现minxins

截至目前&#xff0c;组合式函数应该是在VUE 3应用程序中组织业务逻辑最佳的方法。它让我们可以把一些小块的通用逻辑进行抽离、复用&#xff0c;使我们的代码更易于编写、阅读和维护。 一. 什么是“组合式函数”&#xff1f; 根据官方文档说明&#xff0c;在 Vue 应用的概念中…...

什么是钉钉消息推送?

我是3y&#xff0c;一年CRUD经验用十年的markdown程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;常年被誉为职业八股文选手 在前阵子我就已经接入了钉钉的群机器人和工作消息推送&#xff0c;一直没写文章同步到给大家。 像这种接入渠道的工作&#xff0c;虽然我没接入过&…...

利用 NVIDIATAO 和 WeightBias 加速AI开发

利用 NVIDIATAO 和 Weight&Bias 加速AI开发 利用图像分类、对象检测、自动语音识别 (ASR) 和其他形式的 AI 可以推动公司和商业部门内部的大规模转型。 然而&#xff0c;从头开始构建人工智能和深度学习模型是一项艰巨的任务。 构建这些模型的一个共同先决条件是拥有大量高…...

token - 令牌

文章目录token - 令牌学前须知&#xff1a;1&#xff0c;base64 防君子不防小人2&#xff0c;SHA-256 安全散列算法的一种&#xff08;hash&#xff09;3&#xff0c;HMAC-SHA2564&#xff0c;RSA256 非对称加密2.1 JWT - json-web-token1&#xff0c;三大组成2&#xff0c;jwt…...

应用模型开发指南上新介绍

Module、HAP、Ability、AbilitySta-ge、Context……您是否曾经被这些搞不懂又绕不开的知识点困扰&#xff1f; 现在&#xff0c;全新的《应用程序包基础知识》及《应用模型开发指南》为您答疑解惑&#xff01; 这里有您关注的概念解析、原理机制阐述&#xff0c;也有丰富的…...

Dbeaver连接Hive数据库操作指导

背景&#xff1a;由于工作需要&#xff0c;当前分析研究的数据基于Hadoop的Hive数据库中&#xff0c;且Hadoop服务端无权限进行操作且使用安全模式&#xff0c;在研究了Dbeaver、Squirrel和Hue三种连接Hive的工具&#xff0c;在无法绕开useKey认证的情况下&#xff0c;只能使用…...

【RabbitMQ笔记09】消息队列RabbitMQ之常见方法的使用

这篇文章&#xff0c;主要介绍消息队列RabbitMQ之常见方法的使用。 目录 一、消息队列常见方法 1.1、连接工厂ConnectionFactory 1.2、连接Connection 1.3、通道Channel 1.4、交换机相关方法 &#xff08;1&#xff09;exchangeDeclare()声明交换机 1.5、队列相关方法 …...

Linux字符设备驱动模型之设备号

从上文中可知&#xff0c;在Linux用户空间中&#xff0c;如若需要操作硬件设备&#xff0c;均通过/dev目录下的设备文件节点进行操作&#xff0c;基本上每一种设备都会存在一个或者多个的设备节点。 并且在Linux内核中&#xff0c;其表示字符设备的结构成员也提供了相应的设备号…...

C++多态原理

请看下面的程序&#xff0c;该程序演示了多态类对象存储空间的大小。 #include <iostream> using namespace std; class A {public:int i;virtual void func() {}virtual void func2() {} }; class B : public A {int j;void func() {} }; int main() {cout << si…...

PMP认证与NPDP认证哪个含金量高?

两个证涉及的领域不一样的&#xff0c;一个是项目管理&#xff0c;对应的是项目经理&#xff1b;一个是产品管理&#xff0c;对应的是产品经理。含金量不能相比&#xff0c;但在各自的领域的含金量是很高的&#xff0c;至少专业程度或者知名度是最高的。 我来分别说一下PMP认证…...

改进YOLOv7-Tiny系列:首发改进结合BiFPN结构的特征融合网络,网络融合更多有效特征,高效涨点

💡该教程为改进进阶指南,属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 内容出品:CSDN博客独家更新 @CSDN芒果汁没有芒果 💡本篇文章 基于 YOLOv5、YOLOv7芒果改进YOLO系列:芒果改进YOLOv7-Tiny系列:首发改进结合BiFPN结…...

PPC Insights系列:洞见安全多方图联邦

开放隐私计算开放隐私计算开放隐私计算OpenMPC是国内第一个且影响力最大的隐私计算开放社区。社区秉承开放共享的精神&#xff0c;专注于隐私计算行业的研究与布道。社区致力于隐私计算技术的传播&#xff0c;愿成为中国 “隐私计算最后一公里的服务区”。183篇原创内容公众号知…...

SQLite注入记录(目前最全、核心函数用法、布尔盲注、时间盲注、webshell、动态库,绕过方式)

目录 与Mysql区别 全部核心函数 普通注入 查询所有列 查看所有表名...

Java简单的生成/解析二维码(zxing qrcode)

Hi I’m Shendi Java简单的生成/解析二维码&#xff08;zxing qrcode&#xff09; 在之前使用 qrcode.js 方式生成二维码&#xff0c;但在不同设备上难免会有一些兼容问题&#xff0c;于是改为后端&#xff08;Java&#xff09;生成二维码图片 这里使用 Google 的 zxing包 Jar…...

若依项目导出后端响应的Excel文件流处理

若依开源项目&#xff1a;http://doc.ruoyi.vip/ruoyi-vue 问题 前端 1. download.js 添加自定义方法 /*** 自定义方法&#xff1a;导出后端响应的 excel 文件流* param url 请求后端的接口地址 例如&#xff1a;"/downloadExcel"* param name 响应后的文件名称&…...

华为OD机试【独家】提供C语言题解 - 数组排序

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明数组…...

JVM详解——内存结构

文章目录内存结构1、 运行时数据区2、虚拟机栈3、本地方法栈4、程序计数器5、 堆6、方法区7、运行时常量池8、内存溢出和内存泄漏9、 堆溢出内存结构 1、 运行时数据区 Java虚拟机在运行Java程序期间将管理的内存划分为不同的数据区&#xff0c;不同的区域负责不同的职能&…...

Jvisualvm监控Tomcat以及相关参数优化

Tomcat阻塞模式 阻塞模式&#xff08;BIO&#xff09; 客户端和服务器创建一个连接&#xff0c;它就会创建一个线程来处理这个连接&#xff0c;以为这客户端创建了几个连接&#xff0c;服务端就需要创建几个线程来处理你&#xff0c;导致线程会产生很多&#xff0c;有很多线程…...

界面组件DevExpress WinForms v22.2 - 全面升级数据展示功能

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…...

正点原子第一期

ZYNQ是一个fpga用来硬件编程&#xff0c;外加一个软件编程 FPGA是可通过编程来修改其逻辑功能的数字集成电路 第三篇语法篇 第七章 verilog HDL语法 Verilog的简介 可编程逻辑电路&#xff1a;允许用户自行修改内部连接的集成电路&#xff0c;其内部的电路结构可以通过编程数…...

「mysql是怎样运行的」第24章 一条记录的多幅面孔---事务的隔离级别与MVCC

「mysql是怎样运行的」第24章 一条记录的多幅面孔—事务的隔离级别与MVCC 文章目录「mysql是怎样运行的」第24章 一条记录的多幅面孔---事务的隔离级别与MVCC一、事前准备二、事务的隔离级别事务并发执行遇到的问题SQL标准中的四种隔离级别MySQL中支持的四种隔离级别三、MVCC原…...

入门Java第十五天 线程

一、多线程 1.1进程和线程 进程&#xff1a;进程就是操作系统中运行的每一个应用程序。例如&#xff1a;微信&#xff0c;QQ 线程&#xff1a;线程是进程中的每一个任务。 多线程&#xff1a;在一个进程中&#xff0c;可以同时执行多个线程。同时完成多个任务。 并发&#x…...

探索用卷积神经网络实现MNIST数据集分类

问题对比单个全连接网络&#xff0c;在卷积神经网络层的加持下&#xff0c;初始时&#xff0c;整个神经网络模型的性能是否会更好。方法模型设计两层卷积神经网络&#xff08;包含池化层&#xff09;&#xff0c;一层全连接网络。选择 5 x 5 的卷积核&#xff0c;输入通道为 1&…...

MySQL 索引失效场景

1&#xff0c;前言 索引主要是为了提高表的查询速率&#xff0c;但在某些情况下&#xff0c;索引也会失效的情况。 2&#xff0c;失效场景 2.1 最左前缀法则 查询从索引最左列开始&#xff0c;如果跳过索引中的age列&#xff0c;那么age后面字段的索引都将失效&#xff0c;…...

Xcode开发工具,图片放入ios工程

Xcode开发工具&#xff0c;图片放入ios工程&#xff0c;有三种方式&#xff1a; 一&#xff1a;Assets Assets.xcassets 一般是以蓝色的Assets.xcassets的文件夹形式在工程中&#xff0c;以Image Set的形式管理。当一组图片放入的时候同时会生成描述文件Contents.jso…...

操作系统权限提升(十九)之Linux提权-SUID提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 SUID提权 SUID介绍 SUID是一种特殊权限&#xff0c;设置了suid的程序文件&#xff0c;在用户执行该程序时&#xff0c;用户的权限是该程序文件属主的权限&#xff0c;例如程序文件的属主是root&#xff0c;那么执行该…...

直播 | StarRocks 实战系列第三期--StarRocks 运维的那些事

2023 年开春&#xff0c; StarRocks 社区重磅推出入门级实战系列直播&#xff0c;手把手带你从 Zero to Hero 成为一个 “StarRocks Pro”&#xff01;通过实际操作和应用场景的结合&#xff0c;我们将帮你系统性地学习 StarRocks 这个当今最热门的开源 OLAP 数据库。本次&…...

KingabseES执行计划-分区剪枝(partition pruning)

概述 分区修剪(Partition Pruning)是分区表性能的查询优化技术 。在分区修剪中&#xff0c;优化器分析SQL语句中的FROM和WHERE子句&#xff0c;以在构建分区访问列表时消除不需要的分区。此功能使数据库只能在与SQL语句相关的分区上执行操作。 参数 enable_partition_pruning 设…...

Operator-sdk 在 KaiwuDB 容器云中的使用

一、使用背景KaiwuDB Operator 是一个自动运维部署工具&#xff0c;可以在 Kubernetes 环境上部署 KaiwuDB集群&#xff0c;借助 Operator 可实现无缝运行在公有云厂商提供的 Kubernetes 平台上&#xff0c;让 KaiwuDB 成为真正的 Cloud-Native 数据库。使用传统的自动化工具会…...

【数据挖掘】2、数据预处理

文章目录一、数据预处理的意义1.1 缺失数据1.1.1 原因1.1.2 方案1.1.3 离群点分析1.2 重复数据1.2.1 原因1.2.2 去重的方案1.3 数据转换1.4 数据描述二、数据预处理方法2.1 特征选择 Feature Selection2.2 特征提取 Feature Extraction2.2.1 PCA 主成分分析2.2.2 LDA 线性判别分…...

(四十六)大白话在数据库里,哪些操作会导致在表级别加锁呢?

之前我们已经给大家讲解了数据库里的行锁的概念&#xff0c;其实还是比较简单&#xff0c;容易理解的&#xff0c;因为在讲解锁这个概念之前&#xff0c;对于多事务并发以及隔离&#xff0c;我们已经深入讲解过了&#xff0c;所以大家应该很容易在脑子里有一个多事务并发执行的…...

【Android源码面试宝典】MMKV从使用到原理分析(二)

上一章节,我们从使用入手,进行了MMKV的简单讲解,我们通过分析简单的运行时日志,从中大概猜到了一些MMKV的代码内部流程,同时,我们也提出了若干的疑问?还是那句话,带着目标(问题)去阅读一篇源码,那么往往收获的知识,更加深入&扎实。 本节,我们一起来从源码层次…...

如何使用ADFSRelay分析和研究针对ADFS的NTLM中继攻击

关于ADFSRelay ADFSRelay是一款功能强大的概念验证工具&#xff0c;可以帮助广大研究人员分析和研究针对ADFS的NTLM中继攻击。 ADFSRelay这款工具由NTLMParse和ADFSRelay这两个实用程序组成。其中&#xff0c;NTLMParse用于解码base64编码的NTLM消息&#xff0c;并打印有关消…...

【Python学习笔记】第二十二节 Python XML 解析

一、什么是XMLXML即ExtentsibleMarkup Language(可扩展标记语言)&#xff0c;是用来定义其它语言的一种元语言。XML 被设计用来传输和存储数据。XML 是一套定义语义标记的规则&#xff0c;它没有标签集(tagset)&#xff0c;也没有语法规则(grammatical rule)。任何XML文档对任何…...

5分钟轻松拿下Java枚举

文章目录一、枚举(Enum)1.1 枚举概述1.2 定义枚举类型1.2.1 静态常量案例1.2.2 枚举案例1.2.3 枚举与switch1.3 枚举的用法1.3.1 枚举类的成员1.3.2 枚举类的构造方法1&#xff09;枚举的无参构造方法2&#xff09;枚举的有参构造方法1.3.3 枚举中的抽象方法1.4 Enum 类1.4.1 E…...

华为OD机试【独家】提供C语言题解 - 最小传递延迟

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明最小…...

【Web前端】关于JS数组方法的一些理解

一、具备栈特性的方法unshift(...items: T[]) : number将一个或多个元素添加到数组的开头&#xff0c;并返回该数组的新长度。shift(): T | undefined从数组中删除第一个元素&#xff0c;并返回该元素的值。此方法更改数组的长度。二、具备队列特性的方法push(...items: T[]): …...

多智能体集群协同控制笔记(1):线性无领航多智能体系统的一致性

对于连续时间高阶线性多智能体系统的状态方程为&#xff1a; x˙i(t)Axi(t)Bui(t),i1,2..N\dot {\mathbf{x}}_i(t)A\mathbf{x}_i(t)B\mathbf{u}_i(t),i1,2..N x˙i​(t)Axi​(t)Bui​(t),i1,2..N 下标iii代表第iii个智能体&#xff0c;ui(t)∈Rq1\mathbf{u}_i(t)\in R^{q \time…...

hadoop-Yarn资源调度器【尚硅谷】

大数据学习笔记 Yarn资源调度器 Yarn是一个资源调度平台&#xff0c;负责为运算程序提供服务器运算资源&#xff0c;相当于一个分布式的操作系统平台&#xff0c;而MapReduce等运算程序则相当于运行与操作系统之上的应用程序。 &#xff08;也就是负责MapTask、ReduceTask等任…...

聊聊如何避免多个jar通过maven打包成一个jar,多个同名配置文件发生覆盖问题

前言 不知道大家在开发的过程中&#xff0c;有没有遇到这种场景&#xff0c;外部的项目想访问内部nexus私仓的jar&#xff0c;因为私仓不对外开放&#xff0c;导致外部的项目没法下载到私仓的jar&#xff0c;导致项目因缺少jar而无法运行。 通常遇到这种场景&#xff0c;常用…...

Flume 使用小案例

案例一&#xff1a;采集文件内容上传到HDFS 1&#xff09;把Agent的配置保存到flume的conf目录下的 file-to-hdfs.conf 文件中 # Name the components on this agent a1.sources r1 a1.sinks k1 a1.channels c1 # Describe/configure the source a1.sources.r1.type spoo…...

DLO-SLAM代码阅读

文章目录DLO-SLAM点评代码解析OdomNode代码结构主函数 main激光回调函数 icpCB初始化 initializeDLO重力对齐 gravityAlign点云预处理 preprocessPoints关键帧指标 computeMetrics设定关键帧阈值setAdaptiveParams初始化目标数据 initializeInputTarget设置源数据 setInputSour…...

X和Ku波段小尺寸无线电设计

卫星通信、雷达和信号情报(SIGINT)领域的许多航空航天和防务电子系统早就要求使用一部分或全部X和Ku频段。随着这些应用转向更加便携的平台&#xff0c;如无人机(UAV)和手持式无线电等&#xff0c;开发在X和Ku波段工作&#xff0c;同时仍然保持极高性能水平的新型小尺寸、低功耗…...

推荐算法 - 汇总

本文主要对推荐算法整体知识点做汇总&#xff0c;做到总体的理解&#xff1b;深入理解需要再看专业的材料。推荐算法的意义推荐根据用户兴趣和行为特点&#xff0c;向用户推荐所需的信息或商品&#xff0c;帮助用户在海量信息中快速发现真正所需的商品&#xff0c;提高用户黏性…...

Android 系统的启动流程

前言&#xff1a;从开机的那一刻&#xff0c;到开机完成后launcher将所有应用进行图标展示的这个过程&#xff0c;大概会有哪一些操作&#xff1f;执行了哪些代码&#xff1f;作为Android开发工程师的我们&#xff0c;有必要好好的梳理一遍。既然要梳理Android系统的启动流程&a…...

自学5个月Java找到了9K的工作,我的方式值得大家借鉴 第二部分

我的学习心得&#xff0c;我认为能不能自学成功的要素有两点。 第一点就是自身的问题&#xff0c;虽然想要转行学习Java的人很多&#xff0c;但是非常强烈的想要转行学好的人是小部分。而大部分人只是抱着试试的心态来学习Java&#xff0c;这是完全不可能的。所以能不能学成Jav…...

Vue 3 第五章:reactive全家桶

文章目录1. reactive1.1. reactive函数创建一个响应式对象1.2. 修改reactive创建的响应式对象的属性2. readOnly2.1. 使用 readonly 函数创建一个只读的响应式对象2.2. 如何修改嵌套在只读响应式对象中的对象?3. shallowReactive3.1. 使用 shallowReactive 函数创建一个浅层响…...