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

图像处理 -- 仿射变换之Affine Transformation

仿射变换(Affine Transformation)

仿射变换是图像处理中的一种基本操作,通过线性变换和平移实现图像的几何变换。仿射变换包括旋转、缩放、平移、翻转、错切(shear)等操作。

1. 仿射变换的作用
  • 旋转:将图像绕一个固定点(通常是图像中心)旋转一定角度。
  • 缩放:对图像进行放大或缩小,改变图像的尺寸。
  • 平移:将图像在平面上移动到指定位置。
  • 翻转:沿特定轴将图像反转,比如水平或垂直翻转。
  • 错切:将图像的某一个方向拉伸,使图像产生倾斜效果。

仿射变换在计算机视觉和图像处理中的应用非常广泛,比如在图像配准、目标检测、图像增强等领域中都可以看到仿射变换的身影。

2. 数学实现原理

仿射变换通过一个矩阵乘法和一个向量加法来实现。假设二维空间中的一个点的坐标为 ( x , y ) (x, y) (x,y),经过仿射变换后,该点的新坐标为 ( x ′ , y ′ ) (x', y') (x,y)。则有如下数学表达式:

( x ′ y ′ ) = ( a b c d ) ( x y ) + ( e f ) \begin{pmatrix} x' \\ y' \\ \end{pmatrix} = \begin{pmatrix} a & b \\ c & d \\ \end{pmatrix} \begin{pmatrix} x \\ y \\ \end{pmatrix} + \begin{pmatrix} e \\ f \\ \end{pmatrix} (xy)=(acbd)(xy)+(ef)

这里, ( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd) 是 2x2 仿射变换矩阵, ( e f ) \begin{pmatrix} e \\ f \end{pmatrix} (ef) 是平移向量。

具体仿射变换:
  1. 平移
    x ′ = x + e , y ′ = y + f x' = x + e, \quad y' = y + f x=x+e,y=y+f
    其中, e e e f f f 是平移量。

  2. 旋转
    x ′ = x ⋅ cos ⁡ ( θ ) − y ⋅ sin ⁡ ( θ ) , y ′ = x ⋅ sin ⁡ ( θ ) + y ⋅ cos ⁡ ( θ ) x' = x \cdot \cos(\theta) - y \cdot \sin(\theta), \quad y' = x \cdot \sin(\theta) + y \cdot \cos(\theta) x=xcos(θ)ysin(θ),y=xsin(θ)+ycos(θ)
    其中, θ \theta θ 是旋转角度。

  3. 缩放
    x ′ = x ⋅ s x , y ′ = y ⋅ s y x' = x \cdot s_x, \quad y' = y \cdot s_y x=xsx,y=ysy
    其中, s x s_x sx s y s_y sy 是在 x 轴和 y 轴上的缩放比例。

  4. 错切
    x ′ = x + λ y ⋅ y , y ′ = y + λ x ⋅ x x' = x + \lambda_y \cdot y, \quad y' = y + \lambda_x \cdot x x=x+λyy,y=y+λxx
    其中, λ x \lambda_x λx λ y \lambda_y λy 是在 x 轴和 y 轴上的错切系数。

3. 注意事项
  1. 矩阵可逆性:为了保证仿射变换能被逆变换,仿射变换矩阵 ( a b c d ) \begin{pmatrix} a & b \\ c & d \end{pmatrix} (acbd) 必须是非奇异的,即其行列式不为 0。这确保了变换后的图像可以通过逆变换恢复原状。

  2. 边界处理:仿射变换可能导致图像的一部分移出图像边界,或者图像空白区域增加。因此,通常需要对图像进行裁剪或填充处理。

  3. 插值方法:在仿射变换过程中,目标图像中的像素可能对应源图像中非整数坐标的点,因此需要使用插值方法(如最近邻插值、双线性插值或双三次插值)来计算这些点的像素值。

  4. 保持图像质量:频繁进行仿射变换可能导致图像质量下降,比如模糊、锯齿效应等。因此,在设计变换时需要考虑如何最小化质量损失。

  5. 变换顺序:如果需要执行多个变换,变换的顺序会影响最终结果。例如,旋转后再平移和先平移后旋转的结果是不一样的。因此,需要谨慎设计变换的顺序以达到预期效果。

C代码示例

#include <stdio.h>
#include <stdlib.h>
#include <math.h>#define IMAGE_WIDTH 1088
#define IMAGE_HEIGHT 1288
#define DEGREE_TO_RADIAN(deg) ((deg) * M_PI / 180.0)// 图像数据结构
typedef struct {int width;int height;unsigned char *data; // 指向图像像素数据的指针
} Image;// 从RAW8文件读取图像数据
Image *read_raw8_image(const char *filename, int width, int height) {FILE *file = fopen(filename, "rb");if (!file) {printf("无法打开文件 %s\n", filename);return NULL;}// 在堆上为图像数据分配内存unsigned char *data = (unsigned char *)malloc(width * height * sizeof(unsigned char));if (!data) {printf("内存分配失败\n");fclose(file);return NULL;}// 读取图像数据fread(data, sizeof(unsigned char), width * height, file);fclose(file);// 创建Image结构并返回Image *image = (Image *)malloc(sizeof(Image));image->width = width;image->height = height;image->data = data;return image;
}// 将图像数据写入RAW8文件
void write_raw8_image(const char *filename, Image *image) {FILE *file = fopen(filename, "wb");if (!file) {printf("无法打开文件 %s\n", filename);return;}// 写入图像数据fwrite(image->data, sizeof(unsigned char), image->width * image->height, file);fclose(file);
}
// 释放图像内存
void free_image(Image *image) {if (image) {if (image->data) {free(image->data);}free(image);}
}// 仿射变换函数:旋转图像
Image *affine_transform(Image *image, float angle) {int width = image->width;int height = image->height;// 角度转弧度float radians = DEGREE_TO_RADIAN(angle);float cos_theta = cos(radians);float sin_theta = sin(radians);// 中心点int center_x = width / 2;int center_y = height / 2;// 在堆上为旋转后的图像数据分配内存Image *rotated_image = (Image *)malloc(sizeof(Image));rotated_image->width = width;rotated_image->height = height;rotated_image->data = (unsigned char *)malloc(width * height * sizeof(unsigned char));// 初始化旋转后图像为0(黑色)for (int i = 0; i < width * height; i++) {rotated_image->data[i] = 0;}// 遍历原始图像的每一个像素for (int y = 0; y < height; y++) {for (int x = 0; x < width; x++) {// 计算相对于中心点的偏移int x_offset = x - center_x;int y_offset = y - center_y;// 进行仿射变换(旋转)int new_x = (int)(cos_theta * x_offset + sin_theta * y_offset) + center_x;int new_y = (int)(-sin_theta * x_offset + cos_theta * y_offset) + center_y;// 检查新坐标是否在图像范围内if (new_x >= 0 && new_x < width && new_y >= 0 && new_y < height) {rotated_image->data[new_y * width + new_x] = image->data[y * width + x];}}}return rotated_image;
}
int main() {// 读取RAW8图像Image *image = read_raw8_image("input.raw", IMAGE_WIDTH, IMAGE_HEIGHT);if (!image) {return 1;}// 对图像进行15度旋转Image *rotated_image = affine_transform(image, 15.0);// 保存旋转后的图像write_raw8_image("rotated_output.raw", rotated_image);// 释放内存free_image(image);free_image(rotated_image);return 0;
}

相关文章:

图像处理 -- 仿射变换之Affine Transformation

仿射变换&#xff08;Affine Transformation&#xff09; 仿射变换是图像处理中的一种基本操作&#xff0c;通过线性变换和平移实现图像的几何变换。仿射变换包括旋转、缩放、平移、翻转、错切&#xff08;shear&#xff09;等操作。 1. 仿射变换的作用 旋转&#xff1a;将图…...

Nuxt3【项目配置】nuxt.config.ts

按环境添加配置 export default defineNuxtConfig({// 生产环境的配置$production: {routeRules: {/**: { isr: true }}},// 开发环境的配置$development: {//} })运行时的配置 runtimeConfig export default defineNuxtConfig({runtimeConfig: {// 只在服务器端可用的私有键ap…...

中智讯“2024高校人工智能边缘应用项目实战师资培训班”圆满举办

7月24日——7月28日&#xff0c;中智讯“2024高校人工智能&边缘应用项目实战师资培训班”在昆明理工大学成功举办。本次培训由昆明理工大学人工智能产业学院主办&#xff0c;中智讯&#xff08;武汉&#xff09;科技有限公司承办。来自昆明理工大学、西南林业大学、云南民族…...

IIS发布打包后文件

1.打开IIS软件 2 添加网站&#xff0c; 自定义网站名称-选择要放置的资源路径-选择IP地址 3.打开放置的资源目录放置打包后文件 4.选择浏览 搜索不到IIS可进行一下操作 控制面板-程序和功能-启用或关闭windows功能-勾选IIS...

四个自定义 SHAP 图

超越 Python 包&#xff0c;创建 SHAP 值的定制可视化 SHAP 值是了解模型如何进行预测的绝佳工具。SHAP 包提供了许多可视化效果&#xff0c;使这个过程更加简单。话虽如此&#xff0c;我们不必完全依赖这个包。我们可以通过创建自己的 SHAP 图来进一步了解模型的工作原理。在本…...

为什么使用HTTPS?

HTTPS现在是所有Web活动的首选协议&#xff0c;因为它是用户保护敏感信息的最安全方式。 HTTPS不仅对请求用户信息的网站至关重要。除了用户直接发送的信息外&#xff0c;攻击者还可以从不安全的连接中跟踪行为和身份数据。 HTTP为网站所有者带来的好处除了数据安全之外&…...

软件设计-系统架构师(五十五)

1在网络规划中&#xff0c;政府内外网之间应该部署网络安全防护设备。在下图部署的设备A是&#xff08;&#xff09;&#xff0c;对设备A作用描述错误的是&#xff08;&#xff09;。 问题1 A IDS B 防火墙 C 网闸 D UTM 问题2 A 双主机系统&#xff0c;即使外网被黑客攻击…...

三分钟学会线缆电流估算

今天带你用三分钟的时间,学会电源线承受电流估算,不浪费时间,直接开始吧。 工作温度30℃,长期连续90%负载下的载流量 1.5平方毫米――14A  2.5平方毫米――26A   4平方毫米――32A   6平方毫米――47A    16平方毫米――92A   25平方毫米――120A   3…...

Snipaste 的一款替代工具 PixPin,支持 gif 截图、长截图和 OCR 文字识别,功能不是一点点强!

Snipaste 的一款替代工具 PixPin&#xff0c;支持 gif 截图、长截图和 OCR 文字识别&#xff0c;功能不是一点点强&#xff01; PixPin 的名字来源于“Pixel Pin”&#xff0c;简单来说是一个截图、贴图的工具&#xff0c;但是 PixPin 以截图和贴图两大功能为核心做了大量的优…...

Oracle基础教程

体系结构 数据库 一个操作系统仅有一个数据库 实例 拥有一系列后台进程和存储结构&#xff0c;一个数据库可拥有一个或多个实例&#xff0c;一般只有1个实例 数据文件&#xff08;.dbf/.ora&#xff09; 数据文件是数据库的物理存储单元&#xff0c;一个表空间由一个或多…...

电脑如何录屏?三款电脑录屏工具分享

电脑如何录屏&#xff1f;作为一个经常需要录制电脑屏幕大职场人&#xff0c;不是为了制作教程、记录会议&#xff0c;就是偶尔想自己做个游戏解说视频。市面上的录屏软件琳琅满目&#xff0c;经过一番尝试和比较&#xff0c;我选出了三款我个人认为表现不错的软件&#xff0c;…...

idea2024建立maven web项目servlet 6.0

(1) 下载好tomcat 10.1.28 打开tomcat.apache.org官网下载 &#xff08;2&#xff09;配置好maven &#xff08;3&#xff09;idea 2024打开&#xff0c;建立项目 选择maven java项目 &#xff08;4&#xff09;在项目src/main/下 建立webapp/WEB-INF目录&#xff0c;在…...

游戏开放式新手引导框架设计

强制性引导&#xff1a;只能点某个按钮 优&#xff1a;程序简单 缺&#xff1a; 玩家体验差 开放式引导&#xff1a;不强制点 优&#xff1a;玩家体验好 缺&#xff1a; 程序复杂 需求分析&#xff1a; 1.开放式引导&#xff0c;引导是到达某个条件后进行一系列行为&#xff08…...

【Hot100】LeetCode—189. 轮转数组

目录 1- 思路自定义 reverse 翻转函数 2- 实现⭐189. 轮转数组——题解思路 3- ACM 实现 原题链接&#xff1a;189. 轮转数组 1- 思路 自定义 reverse 翻转函数 2- 实现 ⭐189. 轮转数组——题解思路 class Solution {public void rotate(int[] nums, int k) {k % nums.lengt…...

javaweb学习之HTML(一)

推荐学习使用网站 w3school 在线教程 认识HTML HTML&#xff08;HyperText Markup Language&#xff09;是超文本标记语言&#xff0c;它是一个用于创建网页和网页应用程序的标准标记语言。HTML文档由一系列的元素&#xff08;elements&#xff09;组成&#xff0c;这些元素通…...

项目实战:Qt+Opencv相机标定工具v1.3.0(支持打开摄像头、视频文件和网络地址,支持标定过程查看、删除和动态评价误差率,支持追加标定等等)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141334834 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、Op…...

【数据结构】汇总八、排序算法

排序Sort 【注意】本章是 排序 的知识点汇总&#xff0c;全文1万多字&#xff0c;含有大量代码和图片&#xff0c;建议点赞收藏&#xff08;doge.png&#xff09;&#xff01;&#xff01; 【注意】在这一章&#xff0c;记录就是数据的意思。 排序可视化网站&#xff1a; D…...

Java-分割list并执行多线程任务的工具类

要创建一个用于分割列表并执行多线程任务的工具类,你可以使用 Java 的 ExecutorService 和 ThreadPoolExecutor 来实现。下面是一个详细的示例,展示了如何创建这样一个工具类。 步骤 1: 创建线程池 首先,创建一个线程池来执行任务。 步骤 2: 分割列表 接着,定义一个方…...

Springboot-从服务器获取一个输入流,转成视频文件存到oss

要在Spring Boot应用中从服务器获取一个输入流,然后将该流转换为视频文件并存储到阿里云 OSS中,你可以遵循以下步骤: 设置阿里云OSS客户端:首先,你需要配置阿里云OSS客户端,以便能够上传文件到OSS。 获取输入流:使用HTTP客户端(如RestTemplate或WebClient)从服务器…...

[Meachines] [Easy] Bastion SMB未授权访问+VHD虚拟硬盘挂载+注册表获取NTLM哈希+mRemoteNG远程管理工具权限提升

信息收集 IP AddressOpening Ports10.10.10.134TCP:22, 135, 139, 445, 5985, 47001, 49664, 49665, 49666, 49667, 49668, 49669, 49670 $ nmap -p- 10.10.10.134 --min-rate 1000 -sC -sV PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH fo…...

STM32标准库学习笔记-9.DMA 直接存储器存取

参考教程&#xff1a;【STM32入门教程-2023版 细致讲解 中文字幕】 DMA&#xff08;Direct Memory Access&#xff09; DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取DMA可以提供外设和存储器或者存储器和存储器之间的高速数据传输&#xff0c;无须CPU干预…...

ubuntu VCS+verdi安装遇到的一些问题

主体流程&#xff1a;https://blog.51cto.com/u_15346322/4995147 我的是Ubuntu22.4 安装目录问题 执行 ./installer -gui 只能安装到home 或者 sudo ./setup.sh -install_as_root 能安装到/usr/ 目录 运行 vcs 出现 bin/sh: Illegal option -h sudo rm -f /bin/sh sudo…...

使用Poi-tl对word模板生成动态报告

一、pom依赖问题&#xff1a; <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.2</version> </dependency> 使用 poi-tl 的 1.12.2版本&#xff0c;如果使用了poi依赖&#x…...

day45-dynamic programming-part12-8.16

tasks for today: 1. 115.不同的子序列 2. 583.两个字符串选的删除操作 3. 72.编辑距离 4. 总结编辑两个序列关系的问题 ------------------------------------------------------------------- 1. 115.不同的子序列 In this practice, it is necessary to compare with t…...

C# String的方法

目录 #region 知识点九 字符串切割 #region 知识点一 字符串指定位置获取 #region 知识点二 字符串拼接 #region 知识点三 正向查找字符位置 #region 知识点四 反向查找指定字符串位置 #region 知识点五 移除指定位置后的字符 #region 知识点六 替换指定字符串 #region 知识点七…...

Oracle RAC vs Clusterware vs ASM

Oracle RAC vs Clusterware vs ASM Oracle RACCache FusionRAC后台进程自动负载管理DBA管理工具Oracle ClusterwareCRS组件HAS组件管理工具Oracle ASMASM实例ASM磁盘组镜像和故障组ASM磁盘ASM文件Oracle RAC RAC即Real Application Clusters,是一种Oracle高可用部署架构。Orac…...

“华为杯”第十五届中国研究生数学建模竞赛-F题:机场新增卫星厅对中转旅客影响的研究

目录 摘 要: 一、 问题重述 1.1 研究背景 1.2 已知信息 1.3 需要解决的问题 二、 模型假设 三、 符号说明 四、 问题一模型的建立与求解 4.1 问题描述与分析 4.2 模型的求解 4.3 求解结果与分析 五、 问题二模型的建立与求解 5.1 问题描述与分析 5.2 模型的求解 5.3 求解结果与…...

正点原子linux开发板 qt程序交叉编译执行

1.开发板光盘 A-基础资料->5、开发工具->1、交叉编译器->fsl-imx-x11-glibc-x86_64-meta-toolchain-qt5-cortexa7hf-neon-toolchain-4.1.15-2.1.0.sh 拷贝到 Ubuntu 虚拟机 用文件传输系统或者共享文件夹传输到linux虚拟机 用ls -l查看权限&#xff0c;如果是白色的使…...

聚星文社和虹猫哪个好

聚星文社和虹猫是两个不同的公司&#xff0c;各有各的特点。下面是它们各自的优点&#xff1a; 聚星文社&#xff1a;Docshttps://docs.qq.com/doc/DRU1vcUZlanBKR2xy 聚星文社是一家传媒公司&#xff0c;专注于出版漫画、动画、小说等内容&#xff0c;拥有丰富的IP资源和创作…...

三十八、【人工智能】【机器学习】【监督贝叶斯网络(Bayesian Networks)学习】- 算法模型

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…...