1、前言

在学习图像预处理的时候发现,之前用的图像预处理方法一般为 resize和letter box,这两种方法比较低效,后来在手写AI中接触到了warpaffine,只需要一步就能够对图像进行预处理,同时还能很方便的进行cuda加速,于是便记录下来。

欢迎正在学习或者想学的CV的同学进群一起讨论与学习,v:Rex1586662742,q群:468713665

2、学习内容

2.1、旋转变换

在图像处理过程中,图像主要有平移、缩放、旋转、放射、透视等变换,所有矩阵皆可用矩阵进行表示。首先通过下图来推导变换矩阵。

其中opencv中图像原点在左上方,点 p 绕原点O旋转角度 β \beta β 到 p’ ,同时顺时针旋转变换之后的的角度为

$ \alpha - \beta$ ,同时由图中的三角函数关系可以得到如下公式:

x ′ = c o s ( α − β ) × m x' = cos(\alpha-\beta)×m x′=cos(α−β)×m

y ′ = s i n ( α − β ) × m y' = sin(\alpha-\beta)×m y′=sin(α−β)×m

m = x / cos ⁡ α = y / s i n β m = x/\cos\alpha = y/sin\beta m=x/cosα=y/sinβ

$cos(\alpha-\beta) = cos\alpha cos\beta + sin\alpha sin\beta $

s i n ( α − β ) = s i n α c o s β − c o s α s i n β sin(\alpha-\beta) = sin\alpha cos\beta - cos\alpha sin\beta sin(α−β)=sinαcosβ−cosαsinβ

化简以后得到:

2.2、缩放变换

缩放变换实际上就是在x,y的基础上乘以一个倍数scale

2.3、平移变换

平移变换实际上就是在x,y的基础上减去一个偏移量dx,dy

2.4、齐次坐标

为了便于矩阵计算,利用齐次坐标来表示点的变换,其中平移变换矩阵可表示为:

2.5、缩放+旋转+平移变换

三种变换可以写在一个矩阵当中,可以一次计算到位

对于图像的预处理,通常需要对图片进行不失真的缩放,用变换矩阵可表示为

先通过缩放,再移动到目标图的中间位置如果图像的H>W,则需要进行如下缩放

反之

以其中的一张图片为例,先将原图等比缩放到与目标图宽度一致

现在定义目标图的左上角在opencv坐标系的原点,现在需要原图移动到目标位置可以分为两个步骤,将原图的中心点移动到坐标系原点,对应于公式中的 -scale×Ow/2,-scale×Oh/2

再将图片移动到目标图的中心位置,对应于公式中的 + Dw/2, + Dh/2.

其过程可表示为 p ′ = M p p' =Mp p′=Mp

2.6、逆变换

当图片进行仿射变换后需要恢复到原图或者模型推理得到结果之后需要恢复到原图尺寸时,可以利用逆变换能很方便的得到。

旋转矩阵R是正交的,得到R-1 = RT 于是求逆变换只需要对变换矩阵求逆即可,当然可以通过计算的方法得到

k = s c a l e k = scale k=scale

b 1 = − s c a l e × O w / 2 + D w / 2 b1 = -scale×Ow/2 + Dw/2 b1=−scale×Ow/2+Dw/2

b 2 = − s c a l e × O h / 2 + D h / 2 b2 = -scale×Oh/2 + Dh/2 b2=−scale×Oh/2+Dh/2

x ′ = k x + b 1 x' = kx + b1 x′=kx+b1

y ′ = k y + b 2 y'= ky + b2 y′=ky+b2

x = ( x ′ − b 1 ) / k = x ′ / k + ( − b 1 ) / k x = (x'-b1)/k = x'/k + (-b1)/k x=(x′−b1)/k=x′/k+(−b1)/k

y = ( y ′ − b 2 ) / k = y ′ / k + ( − b 2 ) / k y = (y'-b2)/k = y'/k + (-b2)/k y=(y′−b2)/k=y′/k+(−b2)/k

由此可以的到逆变换矩阵M-1

3、效果测试

import cv2
import matplotlib.pyplot as pltdef inv_mat(M):k = M[0,0],b1 = M[0,2]b2 = M[1,2],return np.array([[1/k,0,-b1/k],[0,1/k,-b2/k]])def transform(image,dst_size):oh,ow = image.shape[:2]dh,dw = dst_sizescale = min(dw/ow,dh/oh)M = np.array([[scale,0,-scale * ow * 0.5 + dw * 0.5],[0,scale,-scale * oh * 0.5 + dh * 0.5]])return cv2.warpAffine(image,M,dst_size),M,inv_mat(M)img = cv2.imread("/home/rex/Desktop/rex_extra/notebook/warpaffine/keji2.jpeg")
img_d,M,inv= transform(img,(640,640))
plt.subplot(1,2,1)
plt.title("WarpAffine")
plt.imshow(img_d[...,::-1])img_s = cv2.warpAffine(img_d,inv,img.shape[:2][::-1])
plt.subplot(1,2,2)
plt.title("or")
plt.imshow(img_s[...,::-1])

4、总结

本次学习内容介绍了高效的图像预处理方式,接下来将会对warpaffine进行cuda加速,进一步提高预处理的速度

【CV学习笔记】图像预处理warpaffine相关推荐

  1. CV学习笔记-图像滤波器

    图像滤波器 1. 图像滤波 1. 图像滤波&滤波器 图像滤波: 即在尽可能保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可不可缺少的操作,其处理效果的好坏将直接影响到后续图 ...

  2. CV学习笔记 — 数据集预处理常用脚本总结

    笔者在学习计算机视觉时,需要经常借助脚本对数据集进行预处理,现将常用的脚本总结如下: 1. 批量修改文件后缀名 # 批量修改 import os import sys # 需要修改后缀的文件目录 os ...

  3. PyTorch框架学习六——图像预处理transforms(二)

    PyTorch框架学习六--图像预处理transforms(二) (续)二.transforms的具体方法 4.图像变换 (1)尺寸变换:transforms.Resize() (2)标准化:tran ...

  4. PyTorch框架学习五——图像预处理transforms(一)

    PyTorch框架学习五--图像预处理transforms(一) 一.transforms运行机制 二.transforms的具体方法 1.裁剪 (1)随机裁剪:transforms.RandomCr ...

  5. y空间兑换代码_【CV学习笔记】色彩空间

    关注"深度学习冲鸭",一起学习一起冲鸭! 设为星标,第一时间获取更多干货 作者:云时之间来源:知乎链接:https://zhuanlan.zhihu.com/p/103387082 ...

  6. CV学习笔记-BP神经网络训练实例(含详细计算过程与公式推导)

    BP神经网络训练实例 1. BP神经网络 关于BP神经网络在我的上一篇博客<CV学习笔记-推理和训练>中已有介绍,在此不做赘述.本篇中涉及的一些关于BP神经网络的概念与基础知识均在< ...

  7. Task02:学习笔记文本预处理;语言模型;循环神经网络基础

    Task02:学习笔记文本预处理:语言模型:循环神经网络基础 文本预处理 文本是一类序列数据,一篇文章可以看作是字符或单词的序列,本节将介绍文本数据的常见预处理步骤,预处理通常包括四个步骤: 读入文本 ...

  8. cv学习笔记(3)神经网络数学原理

    cv学习笔记(3)神经网络数学原理 根据一个神经网络例子来介绍 输入是年龄.收入.性别,输出是买车和不买车的概率.该神经网络包含一个输入层.一个隐含层.一个输出层,每个节点和下一层的所有节点都有连接, ...

  9. 【CV学习笔记】图像预处理warpaffine-cuda加速

    1.前言 在上个学习笔记中学习warpaffine,并且在opencv下面实现了图像的预处理,而warpaffine可以很好的利用cuda加速来实现,于是基于手写AI的项目,又学习了warpaffie ...

最新文章

  1. 机器视觉中彩色成像必须考虑的十个问题
  2. java回退一格_api短信接口
  3. LINUX下如何重启动网络服务
  4. C/C++语言的特点
  5. 静态代理模式(多线程底部原理)
  6. 15必须阅读Java 8教程
  7. Multiple annotations found at this line: ---关于android string.xml %问题
  8. Redis:15---键迁移(move、dump、restore、migrate)
  9. Windows 编程[10] - WM_LBUTTONDOWN、WM_LBUTTONUP 和 WM_MOUSEMOVE 消息
  10. 开源:OpenJDK8 AARCH64(ARM)
  11. vue全局引入字体并使用
  12. 生信分析用python还是r_生信分析利器:JupyterLab
  13. css3 呼吸的莲花_心肾呼吸法—莲花能量冥想*
  14. 行业知识图谱调查报告(三):行业知识图谱应用及实践
  15. 【淘宝API开发系列】获取商品详情,商品评论、卖家订单接口
  16. vrchat新手教程_VRChat简易教程2-创建一个最基本的世界(world)
  17. HTML---下拉框、列表框使用详解(select 与 option)
  18. win12服务器文件设置只读,如何在Win10系统中更改文件夹的只读或系统属性
  19. 每日一问-ChapGPT-20230414-中医基础-四诊之问诊
  20. 电脑主板不能保存CMOS的问题及解决方法

热门文章

  1. PTA 7-192 浪漫的表白
  2. ActiveMQ学习(二)——MQ的工作原理
  3. ESP8266安卓TCP客户端开发(含全部源码)
  4. RS232/RS485信号转12路模拟信号 隔离D/A转换器WJ34
  5. linux 统计每个ip数量,日子IP统计
  6. 手机投屏电脑,无需第三方软件,鼠标控制手机
  7. 记账的目的和好处是什么
  8. Vue 表情输入组件,微信face表情组件
  9. 【转载】Android App应用启动分析与优化
  10. 欢乐的票圈重构——九宫格控件(上)