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

第5章: 图像变换与仿射操作

图像变换和仿射操作是图像处理中常用的技术,通过旋转、缩放、平移、剪裁等操作,可以实现多种视觉效果以及数据增强。

1.1 图像旋转
1.1.1 基础旋转操作

使用 rotate() 方法可以对图像进行旋转操作,指定旋转的角度(以度为单位),图像将以其中心为轴进行旋转。

from PIL import Image

# 打开图像
image = Image.open("example.jpg")

# 旋转图像90度
rotated_image = image.rotate(90)
rotated_image.show()

参数说明

  • angle: 指定旋转角度,正值为顺时针旋转,负值为逆时针旋转。
  • expand: 设置为 True 时,图像旋转后调整画布大小以适应整个旋转后的图像。
1.1.2 自适应画布的旋转
# 自适应画布大小,防止图像被裁剪
rotated_image = image.rotate(45, expand=True)
rotated_image.show()

案例:制作旋转图像的拼图

通过将多个角度的旋转图像组合在一起,可以创建有趣的拼图效果。

angles = [0, 45, 90, 135]
collage = Image.new("RGB", (image.width * 2, image.height * 2))

for i, angle in enumerate(angles):
    rotated_part = image.rotate(angle, expand=True)
    x = (i % 2) * image.width
    y = (i // 2) * image.height
    collage.paste(rotated_part, (x, y))

collage.show()

1.2 图像缩放

缩放图像可以调整图像的分辨率和尺寸,Pillow 提供了 resize() 方法来实现该功能。

1.2.1 等比例缩放
# 等比例缩放至一半尺寸
scaled_image = image.resize((image.width // 2, image.height // 2))
scaled_image.show()
1.2.2 非等比例缩放

如果不保持宽高比,可以指定任意尺寸。

# 非等比例缩放
stretched_image = image.resize((300, 600))
stretched_image.show()

案例:生成缩略图

生成缩略图可以快速预览图像内容,Pillow 提供了 thumbnail() 方法,它会在等比例缩放下,将图像调整为目标尺寸以内。

thumbnail_image = image.copy()
thumbnail_image.thumbnail((100, 100))
thumbnail_image.show()

1.3 图像平移

图像平移可以让图像内容在画布上进行位置移动。Pillow 中可以使用 transform() 方法来实现平移操作。

from PIL import Image, ImageTransform

# 平移图像
shifted_image = image.transform(image.size, ImageTransform.AffineTransform((1, 0, 50, 0, 1, 30)))
shifted_image.show()

1.4 图像剪裁

图像剪裁用于提取图像的某个部分,可以使用 crop() 方法指定一个矩形区域,从而裁剪出该部分。

# 裁剪图像的中心部分
left = image.width // 4
top = image.height // 4
right = image.width * 3 // 4
bottom = image.height * 3 // 4

cropped_image = image.crop((left, top, right, bottom))
cropped_image.show()

案例:制作九宫格图像

将图像按均匀划分成九个区域,并分别提取。

rows, cols = 3, 3
grid_size = (image.width // cols, image.height // rows)
collage = Image.new("RGB", (image.width, image.height))

for i in range(rows):
    for j in range(cols):
        left = j * grid_size[0]
        top = i * grid_size[1]
        right = left + grid_size[0]
        bottom = top + grid_size[1]
        
        cropped_part = image.crop((left, top, right, bottom))
        collage.paste(cropped_part, (left, top))

collage.show()

1.5 仿射变换

仿射变换可以实现复杂的几何变换,如旋转、缩放、平移等的组合。Pillow 的 transform() 方法支持自定义矩阵,以实现仿射变换。

1.1.1 自定义仿射矩阵

仿射变换矩阵是一种 3x3 的矩阵,通常表示为:

[
a b c
d e f
0 0 1
]

在 Pillow 中,我们将此矩阵简化为六个参数 (a, b, c, d, e, f)

# 创建自定义仿射变换
matrix = (1, 0.3, 0, 0.3, 1, 0)
transformed_image = image.transform(image.size, Image.AFFINE, matrix)
transformed_image.show()

案例:生成透视效果

通过调整仿射变换矩阵的参数,可以创建透视效果,使图像看起来像从不同角度拍摄。

# 创建透视效果
perspective_matrix = (1, -0.5, 0, 0.5, 1, 0)
perspective_image = image.transform(image.size, Image.AFFINE, perspective_matrix)
perspective_image.show()

1.6 图像翻转

Pillow 提供了简单的图像翻转方法 transpose(),可以进行水平和垂直翻转。

1.6.1 水平翻转
# 水平翻转
flipped_image = image.transpose(Image.FLIP_LEFT_RIGHT)
flipped_image.show()
1.6.2 垂直翻转
# 垂直翻转
flipped_image = image.transpose(Image.FLIP_TOP_BOTTOM)
flipped_image.show()

1.7 图像变换综合案例

将本章学到的变换操作结合起来,可以实现复杂的图像效果。

案例:创建万花筒效果

将图像进行多次旋转和平移,从而生成万花筒的视觉效果。

kaleidoscope_image = Image.new("RGB", (image.width * 2, image.height * 2))

for angle in range(0, 360, 45):
    rotated = image.rotate(angle, expand=True)
    kaleidoscope_image.paste(rotated, (angle % 2 * image.width, angle // 2 * image.height))

kaleidoscope_image.show()

http://www.kler.cn/a/394550.html

相关文章:

  • ECharts 实现大屏地图功能
  • Linux系统编程多线程之条件变量和信号量讲解
  • 【LeetCode】【算法】581. 最短无序连续子数组
  • vue请求数据报错,设置支持跨域请求,以及2种请求方法axios或者async与await
  • 4.4 软件设计:UML顺序图
  • influxDB 时序数据库安装 flux语法 restful接口 nodjsAPI
  • vue3+vite+js env引入
  • 湾区聚力 开源启智 | 2024 CCF中国开源大会暨第五届OpenI/O启智开发者大会闪耀深圳
  • Scroll 生态全面启动为 Pencils Protocol 赋能,DAPP 将迎强势腾飞
  • 【MySQL】SQL语言
  • android studio new flutter project-运行第一个flutter项目
  • 网络安全教程:从基础到高级全面指南
  • 数据分析案例-笔记本电脑价格数据可视化分析
  • C# WPF FontDialog字体对话框,ColorDialog颜色对话框 引用
  • 批量重命名Excel文件并排序
  • 亮数据——助力全球数据抓取的高效代理平台
  • 力扣最热一百题——完全平方数(中等难度,详细分析)
  • 【Excel】ToRow超级查找函数
  • 随机数
  • Spring Boot中的自动装配机制
  • 【竞技宝】CS2-上海majorRMR:美洲区最后门票争夺战
  • Spark 共享变量:广播变量与累加器解析
  • spring-webmvc根据请求路径找到对应的 HandlerMethod
  • [代码随想录Day11打卡] 150. 逆波兰表达式求值 239. 滑动窗口最大值 (有点难度) 347.前 K 个高频元素 (有点难度) 总结
  • 28、dawn
  • .NET 中的虚拟内存