【计算机视觉】二、图像形成——实验:2D变换编辑(Pygame)

文章目录

  • 一、向量和矩阵的基本运算
  • 二、几何基元和变换
    • 1、几何基元(Geometric Primitives)
    • 2、几何变换(Geometric Transformations)
    • 2D变换编辑器
      • 0. 程序简介
        • 环境说明
        • 程序流程
      • 1. 各种变换
        • 平移变换
        • 旋转变换
        • 等比缩放变换
        • 缩放变换
        • 镜像变换
        • 剪切变换
      • 2. 按钮
        • 按钮类
        • 创建按钮
      • 3. Pygame
        • 初始化变量
        • 初始化Pygame
        • 主循环
        • 退出Pygame
      • 4. 效果展示

一、向量和矩阵的基本运算

【计算机视觉】二、图像形成:1、向量和矩阵的基本运算:线性变换与齐次坐标

二、几何基元和变换

1、几何基元(Geometric Primitives)

  几何基元是计算机图形学中最基本的图形对象,它们是构建更复杂图形的基础单元。常见的几何基元包括:

  • 点(Point): 由一对或一组坐标值表示的零维对象。
  • 线段(Line Segment): 由两个端点确定的一维对象。
  • 多边形(Polygon): 由一系列顶点连接而成的闭合平面图形,是二维对象。
  • 曲线(Curve): 由一系列控制点和方程确定的平滑曲线,如贝塞尔曲线、样条曲线等。
  • 圆(Circle): 由一个圆心和半径确定的二维闭合曲线。
  • 球体(Sphere): 由一个球心和半径确定的三维闭合曲面。

  这些基本的几何基元可以通过组合、变换等操作构建出更加复杂的图形对象,如三维模型、场景等。

2、几何变换(Geometric Transformations)

【计算机视觉】二、图像形成:2、几何基元和几何变换:2D变换

在这里插入图片描述

2D变换编辑器

0. 程序简介

  本人使用 Pygame 库实现了一个图像变换程序,提供六种不同的变换操作,分别是平移、旋转、等比缩放、缩放、镜像和剪切。可以通过点击相应的按钮选择要执行的变换操作,然后使用鼠标拖动来调整变换的参数,实时查看变换后的图像效果。

环境说明

  安装Pygame库

pip install pygame
程序流程
  1. 确保图像"image.jpg"文件与Python文件在同一目录下。

  2. 运行Python文件,将会弹出一个888x888的窗口,显示原始图像和一排按钮。

  3. 点击任意一个按钮,选择相应的变换操作。按钮及对应的变换操作如下:

    • “Translate”: 平移变换
    • “Rotate”: 旋转变换
    • “Isotropic Scale”: 等比缩放变换
    • “Scale”: 缩放变换
    • “Mirror”: 镜像变换
    • “Shear”: 剪切变换
  4. 按住鼠标左键,并拖拽鼠标,可以实时调整变换效果:

    • 平移变换: 拖拽方向和距离决定平移的偏移量。
    • 旋转变换: 拖拽的水平距离决定旋转角度。
    • 等比缩放变换: 拖拽的水平距离决定缩放比例。
    • 缩放变换: 拖拽的水平距离决定x方向缩放比例,垂直距离决定y方向缩放比例。
    • 镜像变换: 向右拖拽进行水平镜像,向左拖拽进行垂直镜像。
    • 剪切变换: 拖拽的水平距离决定x方向剪切系数,垂直距离决定y方向剪切系数。
  5. 变换后的图像将显示在原始图像的右侧。

  6. 窗口上方会显示当前选择的变换类型。

  7. 要退出程序,请关闭窗口或按下键盘上的"Esc"键。

在这里插入图片描述

1. 各种变换

平移变换
def translate(img, x, y):width, height = img.get_size()translated_img = pygame.Surface((window_width, window_height), pygame.SRCALPHA)translated_img.blit(img, (x, y))return translated_img
旋转变换
def rotate(img, angle):rotated_img = pygame.transform.rotate(img, angle)return rotated_img
等比缩放变换
def isotropic_scale(img, scale_factor):width, height = img.get_size()new_size = (int(width * scale_factor), int(height * scale_factor))scaled_img = pygame.transform.scale(img, new_size)return scaled_img
缩放变换
def scale(img, scale_x, scale_y):width, height = img.get_size()new_width = int(width * scale_x)new_height = int(height * scale_y)scaled_img = pygame.transform.scale(img, (new_width, new_height))return scaled_img
镜像变换
def mirror(img, mirror_type):if mirror_type == 'horizontal':mirrored_img = pygame.transform.flip(img, True, False)elif mirror_type == 'vertical':mirrored_img = pygame.transform.flip(img, False, True)else:return imgreturn mirrored_img
剪切变换
def shear(img, shear_x, shear_y):width, height = img.get_size()sheared_img = pygame.Surface((width + abs(shear_x * height), height + abs(shear_y * width)))sheared_img.set_colorkey((0, 0, 0))for x in range(width):for y in range(height):sheared_img.blit(img, (x + shear_x * y, y + shear_y * x), (x, y, 1, 1))return sheared_img

2. 按钮

按钮类
class Button:def __init__(self, x, y, width, height, text, color):self.rect = pygame.Rect(x, y, width, height)self.text = textself.color = colordef draw(self, surface):pygame.draw.rect(surface, self.color, self.rect)font = pygame.font.Font(None, 24)text = font.render(self.text, True, (255, 255, 255))text_rect = text.get_rect(center=self.rect.center)surface.blit(text, text_rect)def is_clicked(self, pos):return self.rect.collidepoint(pos)
创建按钮
buttons = [Button(50, 50, 150, 50, "Translate", (255, 0, 0)),Button(250, 50, 150, 50, "Rotate", (255, 165, 0)),Button(450, 50, 150, 50, "Isotropic Scale", (0, 255, 0)),Button(650, 50, 150, 50, "Scale", (0, 255, 255)),Button(50, 150, 150, 50, "Mirror", (0, 0, 255)),Button(250, 150, 150, 50, "Shear", (128, 0, 128))
]
  • "Translate"按钮颜色为红色 (255, 0, 0)
  • "Rotate"按钮颜色为橙色 (255, 165, 0)
  • "Isotropic Scale"按钮颜色为绿色 (0, 255, 0)
  • "Scale"按钮颜色为青色 (0, 255, 255)
  • "Mirror"按钮颜色为蓝色 (0, 0, 255)
  • "Shear"按钮颜色为紫色 (128, 0, 128)
    问:为什么没有黄色
    答:黄色太耀眼了………

3. Pygame

初始化变量
selected_transform = None
transformed_img = original_img.copy()
mouse_dragging = False
drag_start_pos = (0, 0)
drag_offset = (0, 0)
translation_offset = (0, 0)  # 平移偏移量变量
初始化Pygame
pygame.init()# 设置窗口大小
window_width, window_height = 888, 888
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Image Transformations")# 加载并调整原始图像大小为256x256
original_img = pygame.image.load("image.jpg")
original_img = pygame.transform.scale(original_img, (256, 256))
主循环
running = True
while running:for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseelif event.type == pygame.MOUSEBUTTONDOWN:mouse_pos = pygame.mouse.get_pos()for button in buttons:if button.is_clicked(mouse_pos):selected_transform = button.texttransformed_img = original_img.copy()if event.button == 1:  # 鼠标左键mouse_dragging = Truedrag_start_pos = mouse_poselif event.type == pygame.MOUSEBUTTONUP:if event.button == 1:  # 鼠标左键mouse_dragging = Falseelif event.type == pygame.MOUSEMOTION:if mouse_dragging:mouse_pos = pygame.mouse.get_pos()drag_offset = (mouse_pos[0] - drag_start_pos[0], mouse_pos[1] - drag_start_pos[1])if selected_transform == "Translate":translation_offset = drag_offset  # 更新平移偏移量transformed_img = translate(original_img, translation_offset[0], translation_offset[1])elif selected_transform == "Rotate":angle = drag_offset[0]transformed_img = rotate(original_img, angle)elif selected_transform == "Isotropic Scale":scale_factor = max(0.1, 1 + drag_offset[0] / 100)  # 限制缩放比例在0.1到无穷大之间transformed_img = isotropic_scale(original_img, scale_factor)elif selected_transform == "Scale":scale_x = max(0.1, 1 + drag_offset[0] / 100)  # 限制x方向缩放比例在0.1到无穷大之间scale_y = max(0.1, 1 + drag_offset[1] / 100)  # 限制y方向缩放比例在0.1到无穷大之间transformed_img = scale(original_img, scale_x, scale_y)elif selected_transform == "Mirror":if drag_offset[0] > 0:mirror_type = 'horizontal'else:mirror_type = 'vertical'transformed_img = mirror(original_img, mirror_type)elif selected_transform == "Shear":shear_x = drag_offset[0] / 100shear_y = drag_offset[1] / 100transformed_img = shear(original_img, shear_x, shear_y)# 清空窗口window.fill((222, 222, 222))# 显示原始图像window.blit(original_img, (50, 250))# 显示变换后的图像if transformed_img is not None:window.blit(transformed_img, (350, 250))# 显示选择的变换if selected_transform is not None:font = pygame.font.Font(None, 36)text = font.render(f"Selected Transform: {selected_transform}", True, (255, 255, 255))text_rect = text.get_rect(center=(window_width // 2, 222))window.blit(text, text_rect)# 绘制按钮for button in buttons:button.draw(window)# 更新显示pygame.display.flip()
退出Pygame
pygame.quit()

4. 效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RabbitMQ高级-高级特性

1.消息可靠性传递 在使用RabbitMQ的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ为我们提供了两种方式来控制消息的投递可靠性模式 1.confirm 确认模式 确认模式是由exchange决定的 2.return 退回模式 回退模式是由routing…

Ubuntu Linux - Primavera P6 EPPM 安装及分享

引言 根据计划,近日我制作了基于Ubuntu Linux 的P6虚拟机环境,同样里面包含了全套P6 最新版应用服务 此虚拟机仅用于演示、培训和测试目的。如您在生产环境中使用此虚拟机,请先与Oracle Primavera销售代表取得联系,以获取所需的应…

Python Web开发记录 Day12:Django part6 用户登录

名人说:东边日出西边雨,道是无晴却有晴。——刘禹锡《竹枝词》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 1、登录界面2、用户名密码校验3、cookie与session配置①cookie与session②配置…

【安全类书籍-3】XSS跨站脚剖析与防御

目录 内容简介 作用 下载地址 内容简介 这本书涵盖以下几点: XSS攻击原理:解释XSS是如何利用Web应用未能有效过滤用户输入的缺陷,将恶意脚本注入到网页中,当其他用户访问时被执行,实现攻击者的目的,例如窃取用户会话凭证、实施钓鱼攻击等。 XSS分类:分为存储型XSS(…

leetcode每日一题--矩阵中移动的最大次数

一.题目原型 二.思路解析 1.动态规划 这道题要求的是矩阵的最大移动次数。根据题目意思,从索引 0 列开始向右移动,每次移动一列,最多移动到 n - 1 列,也就是 n - 1次。其移动规则为:当前单元格可以移动到其右上方、正…

2核4g服务器够用吗?

2核4G服务器够用吗?够用。阿腾云以2核4G5M服务器搭建网站为例,5M带宽下载速度峰值可达640KB/秒,阿腾云以搭建网站为例,假设优化后平均大小为60KB,则5M带宽可支撑10个用户同时在1秒内打开网站,并发数为10&am…

SqlServer2008(R2)(一)SqlServer2008(R2)经典宝藏操作收集整理

一、常见操作 1、TRUNCATE TABLE 语句 删除表数据 TRUNCATE TABLE语句比DELET删除表中的所有行更快。从逻辑上讲,TRUNCATE TABLE它类似于DELETE没有WHERE子句的语句。 TRUNCATE TABLE语句从表中删除所有行,但表结构及其列,约束,…

​​SQLiteC/C++接口详细介绍之sqlite3类(十一)

返回目录:SQLite—免费开源数据库系列文章目录 上一篇:​​SQLiteC/C接口详细介绍之sqlite3类(十) 下一篇:​​SQLiteC/C接口详细介绍之sqlite3类(十二)(未发表) 33.sq…

flink1.18.0报错 an implicit exists from scala.Int => java.lang.Integer, but

完整报错 type mismatch;found : Int(100)required: Object Note: an implicit exists from scala.Int > java.lang.Integer, but methods inherited from Object are rendered ambiguous. This is to avoid a blanket implicit which would convert any scala.Int to a…

T1.数据库MySQL

二.SQL分类 2.1 DDL 2.1.1数据库操作 1). 查询所有数据库 show databases ; 2). 查询当前数据库 select database(); 3)创建数据库 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则] ; 4)删除数据库 drop database …

无人机助力智慧农田除草新模式,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建无人机航拍场景下的农田杂草检测识别系统

科技发展到今天,无人机喷洒药物已经不是一件新鲜事情了,在很多高危的工作领域中,比如高空电力设备除冰,电力设备部件传送更换等等,无人机都可以扮演非常出色的作用,前面回到老家一段时间,最近正…

高效使用 JMeter 生成随机数:探索 Random 和 UUID 算法

在压力测试中,经常需要生成随机值来模拟用户行为。JMeter 提供了多种方式来生成随机值,本文来具体介绍一下。 随机数函数 JMeter 提供了多个用于生成随机数的函数,其中最常用的是__Random函数。该函数可以生成一个指定范围内的随机整数或浮…