PIL Image 使用详解

news2024/11/15 5:26:58

文章目录

    • 1. 各种图像处理库介绍
      • 1.1 读取数据的通道顺序
      • 1.2 Python图像处理库(PIL、Pillow、Scikit-image、Opencv)
    • 2、PIL库与Pillow库的区别
    • 3 Pillow库
      • 3.1 Pillow库特点
      • 3.2 Pillow库安装
    • 4、Pillow的Image对象(PIL.Image)
      • 4.1 Image.open()
      • 4.2 Image.new()
      • 4.3 查看Image对象的属性
      • 4.4 )Image.save()
      • 4.5 图像模式转换:im.convert()
      • 4.6 图像缩放:im.resize()
      • 4.7 图像的缩略图:im.thumbnail()
      • 4.8 图像通道分离:im.split()
      • 4.9 图像通道合并:Image.merge()
    • 4.10 混合图像:Image.blend()
      • 4.11 图像裁剪:im.crop()
      • 4.12 图像拷贝:im.copy() —— 深拷贝
    • 4.13 图像粘贴:im.paste()
      • 4.14 图像几何变换(翻转):im.transpose()
      • 4.15 图像几何变换(旋转):im.rotate()
      • 4.16 图像几何变换(形状变换):im.transform()
      • 4.17 图像降噪处理:ImageFilter
      • 4.18 图像像素增强:ImageEnhance
      • 4.19 绘制图形:ImageDraw.Draw()
      • 4.20 获取 RGB 值:ImageColor.getrgb()
      • 4.21 获取颜色值:ImageColor.getcolor()
      • 4.22 numpy与PIL.Image的相互转换
      • 4.23 读取序列图像
    • 5. 应用
      • 应用1:批量修改图像尺寸
      • 应用2:图像添加水印
      • 应用3:生成GIF动态图
      • 应用4:读取和保存图片
      • 应用5:对图片不失真的resize
      • 应用6: 数据增强
      • 应用7: numpy 转PIL.Image
    • 参考

博客转自:Pillow图像处理(PIL.Image类的详细使用) , 仅供学习分享。

1. 各种图像处理库介绍

1.1 读取数据的通道顺序

需注意:Pillow加载图像后的尺寸是二维,图形化是三维,但无法打印三维尺寸。

详细区别:

  • Opencv: uint8的ndarray数据,通道顺序[h, w, c],颜色通道BGR

    • 导入模块:import cv2
      (1)cv2.imread()
      (2)cv2.imshow()
      (3)cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
  • Matplotlib(plt):uint8的ndarray数据,通道顺序[h, w, c],颜色通道RGB

    • 导入模块:import matplotlib.pyplot as plt
      (1)plt.imread()
      (2)plt.imshow()
  • Pillow(PIL):uint8的ndarray数据,通道顺序[h, w, c],颜色通道RGB。

    • 导入模块:import PIL
      (1)PIL.Image.open()
      (2)PIL.Image.show()
  • Pythorch:tensor数据,通道顺序[n, c, h, w],颜色通道RGB。

    • 导入模块:import torchvision
      (1)torchvision.transforms.ToTensor()
      (2)torchvision.transforms.ToPILImage(

1.2 Python图像处理库(PIL、Pillow、Scikit-image、Opencv)

图像(指数字图像)由许多像素点组成,像素是组成图像的基本单位,而每一个像素点又可以使用不同的颜色,最终呈现出了绚丽多彩的图像。

  • (1)PIL是一个免费开源的Python图像处理库。而Pillow是基于PIL库的一个派生分支,它在 PIL 库的基础上增加了许多新的特性。

    • 特点:PIL、Pillow只提供最基础的数字图像处理**,功能有限。
  • (2)Scikit-image:基于 scipy 科学计算的python图像处理软件包,由 scipy 社区开发和维护,以数组的形式对图像进行处理。

    • 特点:轻量,易安装,易使用,轻量级
  • (3)Opencv:由 C/C++ 语言编写的图像处理库,同时提供Python、Ruby、MATLAB等语言的接口。图像处理界中的绝对大佬

    • 特点:环境难搭建,重量型,集成功能较多

Pillow 官方文档(超详细,超推荐)
Pillow 官方文档:https://pillow.readthedocs.io/en/stable/index.html

2、PIL库与Pillow库的区别

PIL(Python Imaging Library)是一个免费开源的Python图像处理库,其功能丰富,API 简洁易用,一度深受好评

发展历程

  • 2011年,PIL官网宣布不再更新PIL,其最新版本仅支持 Python 2.7,而不支持 Python3。
  • 于是,一群 Python 社区的志愿者(主要贡献者:Alex Clark 和 Contributors)在 PIL 库的基础上,开发了一个支持 Python3 版本的图像处理库,它就是 Pillow。目前,已成为Linux发行版中原始PIL的替代品。

3 Pillow库

Pillow是基于PIL库的一个派生分支,它在 PIL 库的基础上增加了许多新的特性。发展至今,已经成为比PIL本身更具活力的图像处理库。

  • Pillow 安装后,导入库的使用方式仍是import PIL,但实际上使用的是 Pillow 库,这里的 PIL 可以看做是 Pillow 库的简称。
  • Pillow 支持跨平台运行,比如 Windows、Linux、MacOS 等。
  • Pillow支持python3,Pillow官网最新版:Pillow 8.4.0。

3.1 Pillow库特点

  • (1) 支持图像的多种输入格式:jpeg、png、bmp、gif、ppm、tiff 等。且支持图像格式之间的相互转换。
  • (2)支持多种图像操作:
    • 创建缩略图、生成预览图像图像批量处理等;
    • 图像裁剪、图像缩放像素点处理添加滤镜图像颜色处理等。
    • 添加水印合成 GIF 动态效果图等等。
  • (3)可以配合 Python GUI(图形用户界面)工具 Tkinter 一起使用。

3.2 Pillow库安装

备注:Pillow 和 PIL 不能共存于同一个环境中,在安装 Pillow 前,需要先卸载 PIL。

  • (1)pip安装:该方法是最简单、轻量级的一种安装方式,并且适用于任何平台。只需执行:pip install Pillow。

  • (2)whl轮子安装
    通过Python PyPi第三方库官网下载与平台系统相对应的版本。下载完成后,进入下载文件的所在位置,然后执行:pip install + whl文件名。

  • (3)Anaconda安装
    Anaconda 是一款开源的 Python 发行版(官网下载地址),是当下较为流行的科学计算平台,支持 Windows、Linux、MacOS 系统。Anaconda 自带许多已经安装完成软件包,其中就包含 Pillow,因此无须重新安装。但默认安装的 Pillow 版本可能会比较低或不是你需要的版本

4、Pillow的Image对象(PIL.Image)

Image 类是 Pillow 库中最为重要的类,该类被定义在和与其同名的 Image 模块中。

  • 导入 Image 模块:from PIL import Image
  • 使用 Image 类可以实例化 Image 对象,通过调用该对象的属性和方法对图像进行处理。
  • Pillow 提供了两种创建 Image 实例对象的方法:open()new()

4.1 Image.open()

可以加载任意图像格式

"""
函数说明:	im = Image.open(fp, mode = "r")
参数说明:
			(1)fp(file_path):文件路径, 字符串格式;
			(2)mode:(可选参数)。若使用,则必须设置mode="r",否则显示ValueError异常。
"""

from PIL import Image
im_open = Image.open("C:/Users/pc/Desktop/1.png")		# 打开图像
im_open.show()											# 显示图像

4.2 Image.new()

"""
函数说明:	im = Image.new(mode, size, color)
参数说明:
			(1)mode:指定图像模式,字符串格式。如: RGB真彩图像、L灰度图像、CMYK色彩图打印模式等;
			(2)size:指定图像大小(width, height)。
			(3)color:图像颜色,默认0表示黑色。参数值支持 [R,G,B] 三元组数字格式、颜色的十六进制值以及颜色英文单词。
"""

from PIL import Image
im_new = Image.new(mode='RGB', size=(260, 100), color="#ff0000")		# 使用颜色的十六进制格式
im_new.show()		# 显示图像

4.3 查看Image对象的属性

width + height + size + format + randonly + info + mode

from PIL import Image
im = Image.open("C:/Users/pc/Desktop/1.png")
print('打印image对象:', im)												
print("图像的宽=%s, 高=%s" %(im.width, im.height))		# width/height:查看图像的宽/高
print("图像的尺寸:", im.size)							# size:查看图像的尺寸
print("图像的格式:", im.format)							# format:查看图片的格式
print("图像是否为只读:", im.readonly)					# readonly:图片是否为只读
print("图像信息:", im.info)								# info:查看图片相关信息。包括每英寸像素点大小和截图软件信息
print("图像模式:", im.mode)								# mode:图像模式

"""
打印image对象:<PIL.PngImagePlugin.PngImageFile image mode=RGB size=1810x228 at 0x17426DA3610>
图像的宽=1810, 高=228
图像的尺寸:(1810, 228)
图像的格式:PNG
图像是否为可读:1
图像信息:{}
图像模式:PGB
"""

4.4 )Image.save()

"""
函数说明:	Image.save(fp, format=None)
参数说明:
			(1)fp:图像的存储路径,包含图像的名称+后缀,字符串格式;
			(2)format:(可选参数),指定图像保存的格式。若不指定文件格式,则以默认的图片格式来存储。
"""

from PIL import Image
im = Image.open("C:/Users/pc/Desktop/1.png")			# 打开图像
im.save('C:/Users/pc/Desktop/2.bmp')					# 保存图像

注: 并非所有的图片格式都可以用 save() 方法转换完成,比如将 PNG 格式的图片(四通道 RGBA 模式)保存为 JPG 格式(三通道 RGB 模式)。保存之前,需要进行图像模型转换。

4.5 图像模式转换:im.convert()

不同格式之间的转换

常用的图像模式如下:
在这里插入图片描述
在这里插入图片描述

"""
函数说明:	im.convert(mode, parms**)
参数说明:
			(1)mode:指的是要转换成的图像模式;
			(2)parms:其他可选参数。如:matrix、dither 等。
			其中,最关键的参数是 mode,其余参数无须关心。
"""
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open("大黄蜂.jpg")	
print(im.mode)		# RGB
im1 = im.convert('1')								
im2 = im.convert('L')									
im3 = im.convert('P')									
im4 = im.convert('RGB')								
im5 = im.convert('RGBA')					
im6 = im.convert('CMYK')	
im7 = im.convert('YCbCr')	
# im8 = im.convert('LAB')			# ValueError: conversion from RGB to LAB not supported
im9 = im.convert('HSV')	
im10 = im.convert('I')			
im11 = im.convert('F')			
######################################################################
# 绘图
im_list = [im, im1, im2, im3, im4, im5, im6, im7, im9, im10, im11]
for i, j in enumerate(im_list):
    plt.subplot(3, 4, i+1)
    plt.title(['raw', '1', 'L', 'P', 'RGB', 'RGBA', 'CMYK', 'YCbCr', 'HSV', 'I', 'F'][i])
    plt.axis('off')
    plt.imshow(j)
plt.show()

"""
plt.subplot(3,4,1), plt.imshow(im), plt.title('raw'), plt.axis('off')
plt.subplot(3,4,2), plt.imshow(im1), plt.title('1'), plt.axis('off')
plt.subplot(3,4,3), plt.imshow(im2), plt.title('L'), plt.axis('off')
plt.subplot(3,4,4), plt.imshow(im3), plt.title('P'), plt.axis('off')
plt.subplot(3,4,5), plt.imshow(im4), plt.title('RGB'), plt.axis('off')
plt.subplot(3,4,6), plt.imshow(im5), plt.title('RGBA'), plt.axis('off')
plt.subplot(3,4,7), plt.imshow(im6), plt.title('CMYK'), plt.axis('off')
plt.subplot(3,4,8), plt.imshow(im7), plt.title('YCbCr'), plt.axis('off')
# plt.subplot(3,4,9), plt.imshow(im8), plt.title('LAB'), plt.axis('off')
plt.subplot(3,4,10), plt.imshow(im9), plt.title('HSV'), plt.axis('off')
plt.subplot(3,4,11), plt.imshow(im10), plt.title('I'), plt.axis('off')
plt.subplot(3,4,12), plt.imshow(im11), plt.title('F'), plt.axis('off')
plt.show()
"""

4.6 图像缩放:im.resize()

  • 整体缩放操作
    在这里插入图片描述
"""
函数说明:	resize(size, resample=image.BICUBIC, box=None, reducing_gap=None)
参数说明:
            (1)size:元组参数 (width,height),图片缩放后的尺寸;
            (2)resample:(可选参数),指图像重采样滤波器,与 thumbnail() 的 resample 参数类似,默认为 Image.BICUBIC;
            (3)box:(可选参数),对指定区域进行缩放,默认对整个原图进行缩放。
                    备注1:指定区域必须在原图范围内,若超出范围则报错。每个像素点代表一个单位。
                    备注2:box 的参数值是长度为 4 的像素坐标元组,即 (x_左上, y_左下, x1_右上, y1_右下),分别表示被裁剪矩形区域的左上角(x, y)和右下角(x, y)。
                    例如:(0,0,120,180)表示以原图的左上角为原点,选择宽和高分别是(120,180)的图像区域。
            (4)reducing_gap:(可选参数),浮点参数值,用于优化图片的缩放效果,常用参数值有 3.0 和 5.0。
"""

from PIL import Image
import matplotlib.pyplot as plt

im = Image.new(mode='RGB', size=(260, 100), color="#ff0000")		# 使用颜色的十六进制格式
im1 = im.resize((550, 260))		# 放大图像
im2 = im.resize((80, 50))		# 缩小图像
######################################################################
# 绘图
im_list = [im, im1, im2]
for i, j in enumerate(im_list):
    plt.subplot(1, 3, i+1)
    plt.title(['raw', 'Enlarge image', 'Reduced image'][i])
    plt.imshow(j)
plt.show()
			

  • 局部放大操作
from PIL import Image
im = Image.open("大黄蜂.jpg")
try:
    image = im.resize((550, 260), resample=Image.LANCZOS, box=(0, 0, 120, 180))
    print("查看新图像的尺寸", image.size)
    image.show()
except IOError:
    print("操作有误")

4.7 图像的缩略图:im.thumbnail()

只能在原图上修改,返回None

"""
函数说明:	thumbnail(size, resample)
参数说明:
			(1)size:元组参数,指的是缩小后的图像大小;
			(2)resample:(可选参数),默认为 Image.BICUBIC。
			备注:有四种图像重采样滤波器,分别是 Image.BICUBIC(双立方插值法)、PIL.Image.NEAREST(最近邻插值法)、PIL.Image.BILINEAR(双线性插值法)、PIL.Image.LANCZOS(下采样过滤插值法)。
"""

from PIL import Image
im = Image.open("C:/Users/pc/Desktop/1.png")
im.thumbnail((150, 50))

注意:缩略图的尺寸与您指定的尺寸可能会出现不一致的情况。

  • 因为 Pillow 会对原图像的长、宽进行等比例缩小,当指定的尺寸不符合图像的尺寸规格时,缩略图就会创建失败。比如:指定的尺寸超出了原图像的尺寸规格

4.8 图像通道分离:im.split()

在这里插入图片描述

from PIL import Image
import matplotlib.pyplot as plt

im = Image.open("C:/Users/pc/Desktop/1.jpg")
r, g, b = im.split()				# 分离颜色通道,产生三个Image对象

plt.subplot(131), plt.imshow(im), plt.title('im'), plt.axis('off')
plt.subplot(132), plt.imshow(r), plt.title('r'), plt.axis('off')
plt.subplot(133), plt.imshow(g), plt.title('g'), plt.axis('off')
plt.subplot(133), plt.imshow(b), plt.title('b'), plt.axis('off')
plt.show()

# r.show()
# g.show()
# b.show()

4.9 图像通道合并:Image.merge()

颜色通道合并 + 图像融合(权重值五五开)

  • 颜色通道合并

在这里插入图片描述

"""
函数说明:	Image.merge(mode, bands)
参数说明:
			(1)mode:指定输出图像的模式
			(2)bands:参数类型为元组或者列表序列,其元素值是组成图像的颜色通道,比如 RGB 分别代表三种颜色通道(r,g,b)。
			备注:要求两张图片的模式、大小必须一致,否则不能合并。
"""
from PIL import Image
import matplotlib.pyplot as plt

im = Image.open("starry_night.jpg")
r, g, b = im.split()					# 分离颜色通道,产生三个 Image 对象
im1 = Image.merge('RGB', (r, g, b))		# 重新组合颜色通道,返回 Image 对象
im2 = Image.merge('RGB', (r, b, g))
im3 = Image.merge('RGB', (g, r, b))
im4 = Image.merge('RGB', (g, b, r))
im5 = Image.merge('RGB', (b, r, g))
im6 = Image.merge('RGB', (b, g, r))

plt.subplot(231), plt.imshow(im1), plt.title('rgb'), plt.axis('off')
plt.subplot(232), plt.imshow(im2), plt.title('rbg'), plt.axis('off')
plt.subplot(233), plt.imshow(im3), plt.title('grb'), plt.axis('off')
plt.subplot(234), plt.imshow(im4), plt.title('gbr'), plt.axis('off')
plt.subplot(235), plt.imshow(im5), plt.title('brg'), plt.axis('off')
plt.subplot(236), plt.imshow(im6), plt.title('bgr'), plt.axis('off')
plt.show()

  • 图像融合:每张图像的权重值都是50%

在这里插入图片描述

from PIL import Image
im_1 = Image.open("starry_night.jpg")
im_2 = Image.open("大黄蜂.jpg")

# 因为两种图片的图片格式一致,所以仅需要处理图片的大小,让它们保持一致
im_2 = im_2.resize(im_1.size)
r1, g1, b1 = im_1.split()
r2, g2, b2 = im_2.split()
im_3 = Image.merge('RGB', [r2, g2, b1])
im_3.show()

4.10 混合图像:Image.blend()

将两张图像叠加在一起,并可以选择其中一张图像的透明度,取值范围[0, 1]。
在这里插入图片描述

"""
函数说明:	Image.blend(image1, image2, alpha)
参数说明:
			(1)image1,image2:表示两个 Image 对象。
			(2)alpha:表示透明度,取值范围为 0 到 1。
				11:当取值为 0 时,等同于 image1 的拷贝。
				22:而取值为 1 时,等同于 image2 的拷贝。
				33:当取值为 0.5 时,与Image.merge()效果等同。
			备注:要求两张图片的模式、大小必须一致,否则不能合并。
"""

from PIL import Image

im_1 = Image.open("starry_night.jpg")
im_2 = Image.open("大黄蜂.jpg")
im_2 = im_2.resize(im_1.size)
im3 = Image.blend(im_1, im_2, 0.7)
im3.show()

4.11 图像裁剪:im.crop()

"""
函数说明:	crop(box=None)
参数说明:	box:表示裁剪区域,默认为 None,表示拷贝原图像。
			备注:box 是一个有四个数字的元组参数 (x_左上, y_左下, x1_右上, y1_右下),分别表示被裁剪矩形区域的左上角(x, y)和右下角(x, y)。默认(0, 0)表示坐标原点,宽度的方向为 x 轴,高度的方向为 y 轴,每个像素点代表一个单位。
"""

from PIL import Image

im = Image.open("大黄蜂.jpg")
im2 = im.crop((0, 0, 50, 50))
im2.show()

4.12 图像拷贝:im.copy() —— 深拷贝

"""
函数说明:	copy(image)
参数说明:	image:拷贝图像;
"""

from PIL import Image

im = Image.open("大黄蜂.jpg")
im_copy = im.copy()								
im_copy.show()

4.13 图像粘贴:im.paste()

在这里插入图片描述

"""
函数说明:	im.paste(image, box=None, mask=None)
参数说明:	
			(1)image:指被粘贴的图像;
			(2)box:指定图像被粘贴的位置或者区域,其参数值是长度为 2 或者 4 的元组序列。
				备注1:长度为 2 时,表示具体的某一点 (x, y)。
				备注2:长度为 4 时,表示具体的粘贴的区域,此时区域的大小必须要和被粘贴的图像大小保持一致。
			(3)mask:(可选参数),为图片添加蒙版效果。
"""

from PIL import Image

im = Image.open("starry_night.jpg")
im1 = Image.open("大黄蜂.jpg")
im_copy = im1.copy()							# 图像拷贝
im_crop = im_copy.crop((0, 0, 200, 100))		# 图像裁剪

# 创建一个新的图像作为蒙版,L模式,单颜色值
image_new = Image.new('L', (200, 100), 200)
# 将裁剪后的副本粘贴至副本图像上,并添加蒙版
im.paste(im_crop, (100, 100, 300, 200), mask=image_new)		# 图像粘贴
im.show()

4.14 图像几何变换(翻转):im.transpose()

在这里插入图片描述

"""
函数说明:	im.transpose(method)
常见方法:	
			(1)Image.FLIP_LEFT_RIGHT:左右水平翻转;
			(2)Image.FLIP_TOP_BOTTOM:上下垂直翻转;
			(3)Image.ROTATE_90:图像旋转 90 度;
			(4)Image.ROTATE_180:图像旋转 180 度;
			(5)Image.ROTATE_270:图像旋转 270 度;
			(6)Image.TRANSPOSE:图像转置;
			(7)Image.TRANSVERSE:图像横向翻转。
"""

from PIL import Image
import matplotlib.pyplot as plt

im = Image.open("starry_night.jpg")
im1 = im.transpose(Image.FLIP_LEFT_RIGHT)
im2 = im.transpose(Image.FLIP_TOP_BOTTOM)
im3 = im.transpose(Image.ROTATE_90)
im4 = im.transpose(Image.ROTATE_180)
im5 = im.transpose(Image.ROTATE_270)
im6 = im.transpose(Image.TRANSPOSE)
im7 = im.transpose(Image.TRANSVERSE)
############################################################
# 绘图
im_list = [im, im1, im2, im3, im4, im5, im6, im7]
for i, j in enumerate(im_list):
    plt.subplot(2, 4, i+1)
    plt.title(['raw', 'Image.FLIP_LEFT_RIGHT', 'Image.FLIP_TOP_BOTTOM', 'Image.ROTATE_90', 'Image.ROTATE_180', 'Image.ROTATE_270', 'Image.TRANSPOSE', 'Image.TRANSVERSE'][i])
    plt.axis('off')
    plt.imshow(j)
plt.show()

"""
plt.subplot(421), plt.imshow(im), plt.title('raw_image'), plt.axis('off')
plt.subplot(422), plt.imshow(im1), plt.title('Image.FLIP_LEFT_RIGHT'), plt.axis('off')
plt.subplot(423), plt.imshow(im2), plt.title('Image.FLIP_TOP_BOTTOM'), plt.axis('off')
plt.subplot(424), plt.imshow(im3), plt.title('Image.ROTATE_90'), plt.axis('off')
plt.subplot(425), plt.imshow(im4), plt.title('Image.ROTATE_180'), plt.axis('off')
plt.subplot(426), plt.imshow(im5), plt.title('Image.ROTATE_270'), plt.axis('off')
plt.subplot(427), plt.imshow(im6), plt.title('Image.TRANSPOSE'), plt.axis('off')
plt.subplot(428), plt.imshow(im7), plt.title('Image.TRANSVERSE'), plt.axis('off')
plt.show()
"""

4.15 图像几何变换(旋转):im.rotate()

在这里插入图片描述

"""
函数说明:	im.rotate(angle, resample=PIL.Image.NEAREST, expand=None, center=None, translate=None, fillcolor=None)
参数说明:	
			(1)angle:表示任意旋转的角度;
			(2)resample:重采样滤波器,默认为 PIL.Image.NEAREST 最近邻插值方法;
			(3)expand:可选参数,表示是否对图像进行扩展,如果参数值为 True 则扩大输出图像,如果为 False 或者省略,则表示按原图像大小输出;
			(4)center:可选参数,指定旋转中心,参数值是长度为 2 的元组,默认以图像中心进行旋转;
			(5)translate:表示对旋转后的图像进行平移。参数值为二元组,以左上角为原点;可以为负数
			(6)fillcolor:可选参数,填充颜色,图像旋转后,对图像之外的区域进行填充。
"""

from PIL import Image

im = Image.open("starry_night.jpg")
im_out = im.rotate(angle=30, translate=(0, -25), fillcolor="green")
im_out.show()

4.16 图像几何变换(形状变换):im.transform()

在这里插入图片描述

"""
函数说明:	im.transform(size, method, data=None, resample=0) 
参数说明:	
			(1)size:指定变换后的图像尺寸;
			(2)method:指定图像的变化方式。比如:Image.EXTENT 表示矩形变换;
			(3)data:截取原图像的区域
			(4)resample:图像重采样滤波器,默认参数值为 PIL.Image.NEAREST。
"""

from PIL import Image

im = Image.open("starry_night.jpg")
im_out = im.transform((500, 500), Image.EXTENT, data=[0, 0, 100 + im.width//2, im.height//3])
im_out.show()


4.17 图像降噪处理:ImageFilter

常见的降噪滤波器如下表:官网Fillow:对每个滤波器的详细定义
在这里插入图片描述
在这里插入图片描述

from PIL import Image, ImageFilter
import matplotlib.pyplot as plt

im = Image.open("大黄蜂.jpg")
im1 = im.filter(ImageFilter.BLUR)
im2 = im.filter(ImageFilter.CONTOUR)
im3 = im.filter(ImageFilter.DETAIL)
im4 = im.filter(ImageFilter.FIND_EDGES)
im5 = im.filter(ImageFilter.EMBOSS)
im6 = im.filter(ImageFilter.EDGE_ENHANCE)
im7 = im.filter(ImageFilter.EDGE_ENHANCE_MORE)
im8 = im.filter(ImageFilter.SMOOTH)
im9 = im.filter(ImageFilter.SMOOTH_MORE)
im10 = im.filter(ImageFilter.SHARPEN)
im11 = im.filter(ImageFilter.GaussianBlur())
im12 = im.filter(ImageFilter.UnsharpMask())
im13 = im.filter(ImageFilter.Kernel((3,3),(1,1,1,0,0,0,2,0,2)))
im14 = im.filter(ImageFilter.MinFilter(3))
im15 = im.filter(ImageFilter.MedianFilter(3))
im16 = im.filter(ImageFilter.MaxFilter(3))
im17 = im.filter(ImageFilter.ModeFilter())
############################################################
# 绘图
im_list = [im, im1, im2, im3, im4, im5, im6, im7, im8, im9, im10, im11, im12, im13, im14, im15, im16, im17]
for i, j in enumerate(im_list):
    plt.subplot(4, 5, i+1)
    plt.title(['raw', 'ImageFilter.BLUR', 'ImageFilter.CONTOUR', 'ImageFilter.DETAIL', 'ImageFilter.FIND_EDGES', 'ImageFilter.EMBOSS', 'ImageFilter.EDGE_ENHANCE', 'ImageFilter.EDGE_ENHANCE_MORE', 'ImageFilter.SMOOTH', 'ImageFilter.SMOOTH_MORE', 'ImageFilter.SHARPEN', 'ImageFilter.GaussianBlur', 'ImageFilter.UnsharpMask', 'ImageFilter.Kernel', 'ImageFilter.MinFilter', 'ImageFilter.MedianFilter', 'ImageFilter.MaxFilter', 'ImageFilter.ModeFilter'][i])
    plt.axis('off')
    plt.imshow(j)
plt.show()

"""
plt.subplot(4,5,1), plt.imshow(im), plt.title('raw_image'), plt.axis('off')
plt.subplot(4,5,2), plt.imshow(im1), plt.title('ImageFilter.BLUR'), plt.axis('off')
plt.subplot(4,5,3), plt.imshow(im2), plt.title('ImageFilter.CONTOUR'), plt.axis('off')
plt.subplot(4,5,4), plt.imshow(im3), plt.title('ImageFilter.DETAIL'), plt.axis('off')
plt.subplot(4,5,5), plt.imshow(im4), plt.title('ImageFilter.FIND_EDGES'), plt.axis('off')
plt.subplot(4,5,6), plt.imshow(im5), plt.title('ImageFilter.EMBOSS'), plt.axis('off')
plt.subplot(4,5,7), plt.imshow(im6), plt.title('ImageFilter.EDGE_ENHANCE'), plt.axis('off')
plt.subplot(4,5,8), plt.imshow(im7), plt.title('ImageFilter.EDGE_ENHANCE_MORE'), plt.axis('off')
plt.subplot(4,5,9), plt.imshow(im8), plt.title('ImageFilter.SMOOTH'), plt.axis('off')
plt.subplot(4,5,10), plt.imshow(im9), plt.title('ImageFilter.SMOOTH_MORE'), plt.axis('off')
plt.subplot(4,5,11), plt.imshow(im10), plt.title('ImageFilter.SHARPEN'), plt.axis('off')
plt.subplot(4,5,12), plt.imshow(im11), plt.title('ImageFilter.GaussianBlur'), plt.axis('off')
plt.subplot(4,5,13), plt.imshow(im12), plt.title('ImageFilter.UnsharpMask'), plt.axis('off')
plt.subplot(4,5,14), plt.imshow(im13), plt.title('ImageFilter.Kernel'), plt.axis('off')
plt.subplot(4,5,15), plt.imshow(im14), plt.title('ImageFilter.MinFilter'), plt.axis('off')
plt.subplot(4,5,16), plt.imshow(im15), plt.title('ImageFilter.MedianFilter'), plt.axis('off')
plt.subplot(4,5,17), plt.imshow(im16), plt.title('ImageFilter.MaxFilter'), plt.axis('off')
plt.subplot(4,5,18), plt.imshow(im17), plt.title('ImageFilter.ModeFilter'), plt.axis('off')
plt.show()
"""

4.18 图像像素增强:ImageEnhance

对选择的属性增强N倍(颜色平衡、对比度、亮度、锐度)
常见的降噪滤波器如下表:
在这里插入图片描述
在这里插入图片描述

from PIL import Image, ImageEnhance
import matplotlib.pyplot as plt

im = Image.open("大黄蜂.jpg")
im1 = ImageEnhance.Color(im).enhance(2)
im2 = ImageEnhance.Contrast(im).enhance(2)
im3 = ImageEnhance.Brightness(im).enhance(2)
im4 = ImageEnhance.Sharpness(im).enhance(8)
############################################################
# 绘图
im_list = [im, im1, im2, im3, im4]
for i, j in enumerate(im_list):
    plt.subplot(2, 3, i+1)
    plt.title(['raw', 'ImageEnhance.Color', 'ImageEnhance.Contrast', 'ImageEnhance.Brightness', 'ImageEnhance.Sharpness'][i])
    plt.axis('off')
    plt.imshow(j)
plt.show()

"""
plt.subplot(2,3,1), plt.imshow(im), plt.title('raw_image'), plt.axis('off')
plt.subplot(2,3,2), plt.imshow(im1), plt.title('ImageEnhance.Color'), plt.axis('off')
plt.subplot(2,3,3), plt.imshow(im2), plt.title('ImageEnhance.Contrast'), plt.axis('off')
plt.subplot(2,3,4), plt.imshow(im3), plt.title('ImageEnhance.Brightness'), plt.axis('off')
plt.subplot(2,3,5), plt.imshow(im4), plt.title('ImageEnhance.Sharpness'), plt.axis('off')
plt.show()
"""

4.19 绘制图形:ImageDraw.Draw()

添加文字 + 绘制点、直线、矩形、多边形、椭圆、圆弧、弦、饼图
在这里插入图片描述
在这里插入图片描述

"""
函数说明:	ImageColor.getrgb(color)
参数说明:	一个颜色名称,字符串格式,可以是颜色的英文单词,或者十六进制颜色名。如果是不支持的颜色,会报 ValueError 错误;
			备注:该模块支持不同格式的颜色,比如 RGB 格式的颜色三元组、十六进制的颜色名称(#ff0000)以及颜色英文单词("red")。
"""

from PIL import Image, ImageDraw, ImageFont

im = Image.new('RGB', (600, 600), color='gray')		# 创建 Image 对象,当做背景图
draw = ImageDraw.Draw(im)							# 创建 ImageDraw 对象

######################################################################
# 绘制文字
font = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc', size=25)			# 加载计算机本地字体文件
draw.text(xy=(200, 200), text='胖墩会武术', fill=(255, 0, 0), font=font)	# 在原图像上添加文本
"""
函数说明:	font = ImageFont.truetype(font, size)
参数说明:	
			(1)font:指定的字体格式文件路径,字符串格式。如:TrueType 和 OpenType 类型的字体
			(2)size:字体大小
"""
######################################################################
# 绘制点 —— 点的pixel为1,若觉得太小可以使用绘制圆来替代
draw.point(((400, 250), (400, 200), (400, 220)), fill=(255, 255, 0))
###################################
# 绘制直线
draw.line(((5,5), (5,100)), fill=(255,0,0), width=5)
###################################
# 绘制矩形
draw.rectangle(((10,10), (50,50)), fill=(0,255,0), outline=(255,0,0))
# 绘制正方形
draw.rectangle(((50,50), (100,100)), fill=None, outline=(0,0,255), width=5)
# 绘制多边形
draw.polygon(((400, 400), (350, 380), (420, 350)), fill=(255, 255, 0), outline=(0, 0, 0))
###################################
# 绘制椭圆形
draw.ellipse(((100, 100), (120, 150)), fill=(0, 255, 0), outline=(255, 0, 0))
# 绘制圆形
draw.ellipse(((250, 250), (300, 300)), fill=None, outline=(0, 0, 255), width=5)
# 绘制圆弧
draw.arc((25, 50, 175, 200), start=30, end=270, fill=(255, 255, 0))
# 绘制弦
draw.chord((225, 50, 375, 200), start=30, end=270, fill=(255, 255, 0), outline=(0, 0, 0))
# 绘制饼图
draw.pieslice((425, 50, 575, 200), start=30, end=270, fill=(255, 255, 0), outline=(0, 0, 0))

im.show()

4.20 获取 RGB 值:ImageColor.getrgb()

RGB 色彩模式、HSL (色调-饱和度-明度)、HSB (又称 HSV,色调-饱和度-亮度)。
下面对 HSL 做简单介绍:

H:即 Hue 色调,取值范围 0 -360,其中 0 表示红色(red),120 表示绿色(green),240 表示蓝色(blue);
S:即 Saturation 饱和度,代表色彩的纯度,取值 0~100%,其中 0 代表灰色(gry),100% 表示色光最饱和;
L:即 Lightness 明度,取值为 0~100%,其中 0 表示黑色(black),50% 表示正常颜色,100% 则表示白色。

"""
函数说明:	ImageColor.getrgb(color)
参数说明:	一个颜色名称,字符串格式,可以是颜色的英文单词,或者十六进制颜色名。如果是不支持的颜色,会报 ValueError 错误;
			备注:该模块支持不同格式的颜色,比如 RGB 格式的颜色三元组、十六进制的颜色名称(#ff0000)以及颜色英文单词("red")。
"""

from PIL import Image, ImageColor

color1 = ImageColor.getrgb("blue")
color2 = ImageColor.getrgb('#DCDCDC')
color3 = ImageColor.getrgb('HSL(0, 100%, 50%)')		# 使用HSL模式红色

print(color1)		# (0, 0, 255)
print(color2)		# (220, 220, 220)
print(color3)		# (255, 0, 0)

4.21 获取颜色值:ImageColor.getcolor()

"""
函数说明:	ImageColor.getcolor(color, mode)
参数说明:	
			(1)color:一个颜色名称,字符串格式,可以是颜色的英文单词,或者十六进制颜色名。如果是不支持的颜色,会报 ValueError 错误;
			(2)mode:指定色彩模式,如果是不支持的模式,会报 KeyError 错误。
			备注:该模块支持不同格式的颜色,比如 RGB 格式的颜色三元组、十六进制的颜色名称(#ff0000)以及颜色英文单词("red")。
"""

from PIL import Image, ImageColor

color4 = ImageColor.getcolor('#EEA9B8','L')
color5 = ImageColor.getcolor('yellow','RGBA')

print(color4)		# 191
print(color5)		# (255, 255, 0, 255)

4.22 numpy与PIL.Image的相互转换

from PIL import Image
import numpy as np

img = Image.open("C:/Users/pc/Desktop/1.png")
img_2 = np.array(img)					# Image图像转换为ndarray数组
arr_img = Image.fromarray(img_2)		# ndarray转换为Image图像
arr_img.show()

4.23 读取序列图像

seek() + tell() 、ImageSequence()
Pillow 库也包含对图像序列(动画格式)的一些基本支持。支持的序列格式文件包括:GIF、TIFF 和 FLI 等等。当加载序列图像时,默认加载的是第一帧。

  • 方法一:除使用 seek() 方法读取图像序列外,ImageSequence 模块还提供了 for 循环迭代遍历图像序列的方法。你可以使用 seek() 和 tell() 方法访问不同的帧。
from PIL import Image
import matplotlib.pyplot as plt

fname = r'C:\Users\my\Desktop\image\my.gif'
im = Image.open(fname)
im_list = [im.copy()]
try:
    while True:
        im.seek(im.tell()+1)
        im_list.append(im.copy())
except EOFError:
    pass
#################################################
# 绘图
for i, j in enumerate(im_list):
    plt.subplot(1, 4, i+1)
    plt.title(str(i+1))
    plt.axis('off')
    plt.imshow(j)
plt.show()

  • 方法二:除使用 seek() 方法读取图像序列外,ImageSequence 模块还提供了 for 循环迭代遍历图像序列的方法。
from PIL import Image, ImageSequence
import matplotlib.pyplot as plt

fname = r'C:\Users\my\Desktop\image\my.gif'
im = Image.open(fname)
im_list = []
for frame in ImageSequence.Iterator(im):
    im_list.append(frame.copy())
##############################################
# 绘图
for i, j in enumerate(im_list):
    plt.subplot(1, 4, i+1)
    plt.title(str(i+1))
    plt.axis('off')
    plt.imshow(j)
plt.show()

5. 应用

应用1:批量修改图像尺寸

import os
from PIL import Image

# 若文件夹不存在,则新建:NewImage
if not os.path.exists('C:/Users/pc/Desktop/NewImage/'):
    os.mkdir('C:/Users/pc/Desktop/NewImage/')		
    
fileName = os.listdir('C:/Users/pc/Desktop/image01/')		# 指定图像的文件夹:image01
for img in fileName:
    raw_image = Image.open('C:/Users/pc/Desktop/image01/' + img)
    new_image = raw_image.resize((350, 350), Image.BILINEAR)
    new_image.save('C:/Users/pc/Desktop/NewImage/'+img)

应用2:图像添加水印

ImageDraw + ImageFont`
在这里插入图片描述

from PIL import Image, ImageFont, ImageDraw


def creating_watermark(im, text, font):
    # 给水印添加透明度,因此需要转换图片的格式
    im_rgba = im.convert('RGBA')
    im_text_canvas = Image.new('RGBA', im_rgba.size, (255, 255, 255, 0))
    draw = ImageDraw.Draw(im_text_canvas)

    text_x_width, text_y_height = draw.textsize(text, font=font)    # 设置文本文字大小
    text_xy = (im_rgba.size[0] - text_x_width, im_rgba.size[1] - text_y_height)
    draw.text(text_xy, text, font=font, fill=(0, 125, 125))         # 设置文本
    im_text = Image.alpha_composite(im_rgba, im_text_canvas)        # 将原图片与文字复合
    return im_text


image = Image.open("大黄蜂.jpg")
font1 = ImageFont.truetype('C:/Windows/Fonts/msyh.ttc', size=100)
image_water = creating_watermark(image, '胖墩会武术', font=font1)
image_water.show()

应用3:生成GIF动态图

import os
import random
from PIL import Image


def png_to_gif(png_path, gif_name):
    """png合成gif图像:保存图像的文件夹路径, gif保存路径"""
    frames = []
    png_files = os.listdir(png_path)
    print(png_files)
    
    # 读取文件内的静态图
    for frame_id in range(1, len(png_files)+1):
        frame = Image.open(os.path.join(png_path, 'image%d.jpg'%frame_id))
        frames.append(frame)

	frames[0].save(gif_name, save_all=True, append_images=frames[1:], transparency=0, duration=2000, loop=0, disposal=2)
# 函数作用:以第一张图片作为开始,将后续5张图片合并成 gif 动态图
# 参数说明:
# 			save_all 保存图像;
#			transparency 设置透明背景色; 
#			duration 单位毫秒,动画持续时间。
# 			loop=0 无限循环;
#			disposal=2 恢复原背景颜色。
# 注意:Pillow 总是以灰度模式(L)或调色板模式(P)来读取 GIF 文件。
png_to_gif("C:/Users/pc/Desktop/image", 'C:/Users/pc/Desktop/t.gif')

应用4:读取和保存图片

import os
from tqdm import tqdm
from PIL import Image

img_names = os.listdir(dir_origin_path)
for img_name in tqdm(img_names):
    if img_name.lower().endswith(('.bmp', '.dib', '.png', '.jpg', '.jpeg', '.pbm', '.pgm', '.ppm', '.tif', '.tiff')):
        image_path  = os.path.join(dir_origin_path, img_name)
        image       = Image.open(image_path)
        r_image     = deeplab.detect_image(image)
        if not os.path.exists(dir_save_path):
            os.makedirs(dir_save_path)
        r_image.save(os.path.join(dir_save_path, img_name))
  • 应用5:预处理Letterbox
def (image,label,w,h)
	iw, ih  = image.size
	scale   = min(w/iw, h/ih)
	nw      = int(iw*scale)
	nh      = int(ih*scale)
	
	image       = image.resize((nw,nh), Image.BICUBIC)
	new_image   = Image.new('RGB', [w, h], (128,128,128))
	new_image.paste(image, ((w-nw)//2, (h-nh)//2))
	
	label       = label.resize((nw,nh), Image.NEAREST)
	new_label   = Image.new('L', [w, h], (0))
	new_label.paste(label, ((w-nw)//2, (h-nh)//2))
return new_image, new_label

应用5:对图片不失真的resize

def resize_image(image, size):
    iw, ih  = image.size
    w, h    = size

    scale   = min(w/iw, h/ih)
    nw      = int(iw*scale)
    nh      = int(ih*scale)

    image   = image.resize((nw,nh), Image.BICUBIC)
    new_image = Image.new('RGB', size, (128,128,128))
    new_image.paste(image, ((w-nw)//2, (h-nh)//2))

    return new_image, nw, nh

应用6: 数据增强

flip = self.rand()<.5
if flip: 
    image = image.transpose(Image.FLIP_LEFT_RIGHT)
    label = label.transpose(Image.FLIP_LEFT_RIGHT)

应用7: numpy 转PIL.Image

PIL.Image.fromarray(img).save(osp.join(jpgs_path, count[i].split(".")[0]+'.jpg'))

参考

https://github.com/bubbliiiing/deeplabv3-plus-pytorch

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1439824.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Spring源码解读!底层原理进阶】【下】探寻Spring内部:BeanFactory和ApplicationContext实现原理揭秘✨

&#x1f389;&#x1f389;欢迎光临&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;特别推荐给大家我的最新专栏《Spring 狂野之旅&#xff1a;底层原理高级进阶》 &#x1f680…

代码随想录算法训练营29期|day43 任务以及具体任务

第九章 动态规划 part05 1049. 最后一块石头的重量 II class Solution {public int lastStoneWeightII(int[] stones) {int sum 0;for (int i : stones) {sum i;}int target sum >> 1;//初始化dp数组int[] dp new int[target 1];for (int i 0; i < stones.lengt…

HttpServletResponse接口用于表示状态代码的字段

1. HttpServletResponse接口用于表示状态代码的字段 您已学习了状态代码以及可用于从servlet向客户机发送状态代码的HttpServletResponse接口的字段。下表列出了HttpServletResponse接口表示状态代码的一些其他字段。 字段状态代码描述SC_HTTP_VERSION_NOT_SUPPORTED505服务器…

TCP相关知识点

TCP相关知识点 参考&#xff1a; 《计算机网络》 (建议收藏)TCP协议灵魂之问&#xff0c;巩固你的网路底层基础 关于 TCP 三次握手和四次挥手&#xff0c;满分回答在此 (值得看) TCP处于网络体系结构中的运输层。 运输层主要为应用进程提供端到端的逻辑通信&#xff0c;然后对…

牛客网SQL进阶137:第二快/慢用时之差大于试卷时长一半的试卷

官网链接&#xff1a; 第二快慢用时之差大于试卷时长一半的试卷_牛客题霸_牛客网现有试卷信息表examination_info&#xff08;exam_id试卷ID, tag试卷类别,。题目来自【牛客题霸】https://www.nowcoder.com/practice/b1e2864271c14b63b0df9fc08b559166?tpId240 0 问题描述 试…

Java实现网上药店系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 药品类型模块2.3 药品档案模块2.4 药品订单模块2.5 药品收藏模块2.6 药品资讯模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 药品表3.2.3 药品订单表3.2.4 药品收藏表3.2.5 药品留言表…

codemirror光标样式问题

输入框为空时会显示placeholder&#xff0c;文字有点长换行了&#xff0c;光标竟然变成上图那样了&#xff0c;我试过如果placeholder文字是三行&#xff0c;那么光标就是三行高。真是见了鬼了。查到最后&#xff0c;原因竟然是因为我在用vue-codemirror时为了去掉一些basicSet…

JavaScript中call、apply、bind方法的应用与区别

在JavaScript中&#xff0c;call、apply和bind是函数的三个重要方法&#xff0c;它们虽然功能不同&#xff0c;但都可以用来改变函数的执行上下文或者传递参数。本文将分别介绍call、apply和bind方法的应用和区别&#xff0c;并附带示例代码。 一、call方法 call方法的作用是…

FX110网:高盛因监管不力被罚51.2万美元

近日&#xff0c;高盛因其监控流程和系统存在漏洞&#xff0c;被美国金融业监管局(FINRA)处以512500美元的罚款。 FINRA调查发现&#xff0c;2009年2月至2023年4月中旬&#xff0c;高盛未能将认证权证、股权、单位信托和部分场外交易股票证券纳入9份用于检测该公司及其客户是否…

vue 实现 手机号中间4位分格输入框(暂无选中标识

vue 实现 手机号中间4位分格输入框 效果图 <!--4位分格输入框--> <!--<template><div><div style"display: flex;"><div class"phone-input"><inputv-for"(digit, index) in digits":key"index"…

vue项目文件夹介绍

目录 Vue项目目录结构 项目介绍: node_modules 文件及子目录 src目录 assets 文件夹 components 文件夹 实例:简单的注册并使用组件 Vue项目目录结构 项目介绍: node_modules 文件及子目录 这个文件夹里面全部都是node的一些基础的依赖包&#xff0c;当我们拓展的安…

【Python4Delphi】学习笔记(一):介绍篇

一、前言&#xff1a; 1. python语言简介&#xff1a; 众所周知&#xff0c;python是目前非常流行的编程语言之一&#xff0c;自20世纪90年代初Python语言诞生至今&#xff0c;它已被逐渐广泛应用于系统管理任务的处理和Web编程。 由于Python语言的简洁性、易读性以及可扩展性…

大规模块存储 EC 系统构建

本文整理自 2023 年 7 月 DataFunSummit 2023 数据基础架构峰会——大规模存储架构分论坛的同名主题分享。 非常欢迎大家的到来&#xff0c;今天由我来分享百度智能云块存储 EC 系统的构建。块存储系统在百度智能云的产品名叫 CDS&#xff0c;底层 EC 系统由 Aries 承担。 今天…

04-Java建造者模式 ( Builder Pattern )

建造者模式 摘要实现范例 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象 一个Builder 类会一步一步构造最终的对象&#xff0c;该 Builder 类是独立于其他对象的 建造者模式属于创建型模式&#xff0c;它提供了一种创建对…

[当人工智能遇上安全] 11.威胁情报实体识别 (2)基于BiGRU-CRF的中文实体识别万字详解

您或许知道&#xff0c;作者后续分享网络安全的文章会越来越少。但如果您想学习人工智能和安全结合的应用&#xff0c;您就有福利了&#xff0c;作者将重新打造一个《当人工智能遇上安全》系列博客&#xff0c;详细介绍人工智能与安全相关的论文、实践&#xff0c;并分享各种案…

Spring 的奇幻起源:从 IoC 容器到 Bean 的魔法世界 ✨

目录 什么是 Spring&#xff1f;为什么它如此流行&#xff1f; IoC 容器&#xff1a;从“依赖倒置”到“控制反转” Bean&#xff1a;IoC 容器中的基本组件 Spring 中的配置方式&#xff1a;XML、注解和 JavaConfig Bean 的作用域和生命周期管理 Bean 的属性装配和自动装配…

[大厂实践] Netflix容器平台内核panic可观察性实践

在某些情况下&#xff0c;K8S节点和Pod会因为出错自动消失&#xff0c;很难追溯原因&#xff0c;其中一种情况就是发生了内核panic。本文介绍了Netflix容器平台针对内核panic所做的可观测性增强&#xff0c;使得发生内核panic的时候&#xff0c;能够导出信息&#xff0c;帮助排…

Java ieda 抽风报错导致无法正常启动项目

Java ieda 抽风报错导致无法正常启动项目 问题描述&#xff1a;新建模块运行时出现下面报错&#xff0c;不能正常启动程序。 Error:Module 你的项目名 production: java.lang.ClassCastException: class org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveT…

适用于 Windows 11/10/8.1/8/7 的最佳 SD 卡恢复软件

丢失了 SD 卡中的一些重要照片或文档&#xff0c;并且不知道如何恢复&#xff1f;好吧&#xff0c;别担心&#xff01;&#xff01;以下是一些适用于 Windows 的最佳 SD 卡恢复工具&#xff0c;可增加您检索意外删除、丢失或丢失数据的机会。 什么是 SD 卡恢复软件&#xff1f;…

华为配置访客接入WLAN网络示例(MAC优先的Portal认证)

配置访客接入WLAN网络示例&#xff08;MAC优先的Portal认证&#xff09; 组网图形 图1 配置WLAN MAC优先的Portal认证示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 某企业为了提高WLAN网络的安全性&#xff0c;采用MAC优先的外置Portal认…