关于图像的warp操作是指利用一个旋转缩放矩阵对图像进行操作。
常见的操作有,平移,绕某个点旋转,缩放。
opencv中有getRotationMatrix2D,warpAffine, getAffineTransform等函数
pytorch有torch.nn.functional.grid_sample用处比较多
和affine_grid(theta, size, align_corners=None)函数

1. cv2.getRotationMatrix2D(center, angle, scale)


[1]https://blog.csdn.net/qq_34914551/article/details/107132145

cv2.getRotationMatrix2D(center, angle, scale)通过设置旋转中心,角度,缩放尺度来获取转换尺度

%matplotlib inline
import matplotlib.pyplot as pltimage = cv2.imread('featprop.png')
print(image.shape)
plt.imshow( image)
plt.show()# 4 个 转换矩阵,设置旋转中心,角度和 缩放尺度
center, angle, scale = (100,100), 0, 1             # center表示的是旋转的中心, angle==0时,center没有作用
t1 = cv2.getRotationMatrix2D(center, angle, scale)
print(t1)center, angle, scale = (0,0), 30, 1                # angle表示的是旋转的角度
t2 = cv2.getRotationMatrix2D(center, angle, scale)
print(t2)center, angle, scale = (0,0), 0, 0.6               # scale表示的是缩放的尺度
t3 = cv2.getRotationMatrix2D(center, angle, scale)
print(t3)center, angle, scale = (200,200), 45, 0.9          # 绕[200,200]逆时针旋转45读,并缩放为原来的0.9
t4 = cv2.getRotationMatrix2D(center, angle, scale)
print(t4)

return

2.对图像应用上面4个转换矩阵cv2.warpAffine(image, A, (width, height))得到如下

h, w, c = image.shape
it1 = cv2.warpAffine(image, t1, [w, h], borderValue = (255,133,133))
it2 = cv2.warpAffine(image, t2, [w, h], borderValue = (255,133,133))
it3 = cv2.warpAffine(image, t3, [w, h], borderValue = (255,133,133))
it4 = cv2.warpAffine(image, t4, [w, h], borderValue = (255,133,133))print(it1.shape, it2.shape, it3.shape, it4.shape)plt.subplot(221)
plt.imshow(it1)
plt.subplot(222)
plt.imshow(it2)
plt.subplot(223)
plt.imshow(it3)
plt.subplot(224)
plt.imshow(it4)
plt.show()

return

3. 通过3个对应点来求解转换矩阵(在实际应用时如果有多个对应点,可以利用最小二乘法求解转换矩阵)

import numpy as np
import cv2
import matplotlib.pyplot as plt
%matplotlib inline src = image
# 设置3个对应点的坐标
srcTri = np.array( [[0, 0], [src.shape[1] - 1, 0], [0, src.shape[0] - 1]] ).astype(np.float32)dstTri = np.array( [[0, src.shape[1]*0.33], [src.shape[1]*0.85, src.shape[0]*0.25], [src.shape[1]*0.15, src.shape[0]*0.7]] ).astype(np.float32)
# 求解旋转矩阵
warp_mat = cv2.getAffineTransform(srcTri, dstTri)
# warp操作
warp_dst = cv2.warpAffine(src, warp_mat, (src.shape[1], src.shape[0]))
print(warp_mat)plt.imshow(warp_dst)
plt.show()

return

[2]https://docs.opencv.org/3.4/d4/d61/tutorial_warp_affine.html

4. torch.nn.functional.grid_sample(input, grid, mode=‘bilinear’, padding_mode=‘zeros’, align_corners=None)

这个函数是网格采样函数,也可以理解为是查找表函数。
input 支持 4D 和 5D。
4D的时候,input with shape (N, C, H_in, W_in) ,
and grid with shape (N, H_out, W_out, 2) ,

the output will have shape (N, C, H_out, W_out)

5D的时候input with shape (N, C, D_in, H_in, W_in) ,
and grid with shape (N, D_out, H_out, W_out, 2) ,

the output will have shape (N, C, D_out, H_out, W_out)

想象不考虑N个样本和C个通道,其实就是2Dlut和3Dlut。 通过输入的position(x,y)或者(x,y,z), 查找原图中的值。由于position(x,y)或者(x,y,z)不一定在原图中的特定点,需要插值。

此外使用的时候,grid 被 input的尺寸归一化 到[-1,1]。建议 padding_mode=“border”。

具体的介绍可以参看 官方说明

basic_vsr中一个使用例子用于 warp image or feature

def flow_warp(x,flow,interpolation='bilinear',padding_mode='zeros',align_corners=True):"""Warp an image or a feature map with optical flow.Args:x (Tensor): Tensor with size (n, c, h, w).flow (Tensor): Tensor with size (n, h, w, 2). The last dimension isa two-channel, denoting the width and height relative offsets.Note that the values are not normalized to [-1, 1].interpolation (str): Interpolation mode: 'nearest' or 'bilinear'.Default: 'bilinear'.padding_mode (str): Padding mode: 'zeros' or 'border' or 'reflection'.Default: 'zeros'.align_corners (bool): Whether align corners. Default: True.Returns:Tensor: Warped image or feature map."""if x.size()[-2:] != flow.size()[1:3]:raise ValueError(f'The spatial sizes of input ({x.size()[-2:]}) and 'f'flow ({flow.size()[1:3]}) are not the same.')_, _, h, w = x.size()# create mesh gridgrid_y, grid_x = torch.meshgrid(torch.arange(0, h), torch.arange(0, w))grid = torch.stack((grid_x, grid_y), 2).type_as(x)  # (h, w, 2)grid.requires_grad = Falsegrid_flow = grid + flow# scale grid_flow to [-1,1]grid_flow_x = 2.0 * grid_flow[:, :, :, 0] / max(w - 1, 1) - 1.0grid_flow_y = 2.0 * grid_flow[:, :, :, 1] / max(h - 1, 1) - 1.0grid_flow = torch.stack((grid_flow_x, grid_flow_y), dim=3)  # n * h * w * 2output = F.grid_sample(x,grid_flow,mode=interpolation,padding_mode=padding_mode,align_corners=align_corners)return output

5.PyTorch中affine_grid(theta, size, align_corners=None)

def affine_grid(theta, size, align_corners=None):'''theta: 一个 N*2*3的张量,N是batch size。size: 是得到的网格的尺度,也就是希望仿射变换之后得到的图像大小'''

这个函数的意思是根据一个旋转矩阵 得到 一个映射网格表,得到的这个表可以用于F.grid_sample中的grid参数

import torch
import torch.nn.functional as F
angle = 30 * np.pi / 180  # np默认角度为弧度制
offsetx, offsety = -1, -1 # 平移的范围感觉像是[-2, 2]?为什么def torch_warp(angle, offsetx, offsety):theta = np.array([np.cos(angle), np.sin(-angle), offsetx,np.sin(angle), np.cos(angle), offsetx])  # 30度的旋转矩阵theta = theta.reshape(1, 2, 3)theta = torch.from_numpy(theta).float()  # 调整dtypegrid = F.affine_grid(theta, [1, 3, h, w], align_corners=True)  # 得到grid 用于grid sampleprint(grid.min(), grid.max())img_tensor = torch.from_numpy(image).float().permute(2, 0, 1).unsqueeze(0)warp_img = F.grid_sample(img_tensor, grid, align_corners=True).squeeze().permute(1, 2, 0).numpy()print(grid.shape, img_tensor.shape, image.shape, warp_img.shape)warp_img = np.clip(warp_img, 0, 255).astype(np.uint8)return warp_imgwarp_img1 = torch_warp(0, -1.9, -1.9)
warp_img2 = torch_warp(0, -1, -1)
warp_img3 = torch_warp(0, -0.5, -0.5)
warp_img4 = torch_warp(0, 0, 0)
warp_img5 = torch_warp(0, 0.5, 0.5)
warp_img6 = torch_warp(0, 1, 1)
warp_img7 = torch_warp(0, 1.9, 1.9)
plt.figure(figsize=(100,50))plt.subplot(241)
plt.imshow(warp_img1)
plt.subplot(242)
plt.imshow(warp_img2)
plt.subplot(243)
plt.imshow(warp_img3)
plt.subplot(244)
plt.imshow(warp_img4)
plt.subplot(245)
plt.imshow(warp_img5)
plt.subplot(246)
plt.imshow(warp_img6)
plt.subplot(247)
plt.imshow(warp_img7)
# offsetx和offsety实现的是图像的平移操作,整幅图像的尺寸好像是[-2,2]。 offsetx和offsety = 2的时候图像就完全消失。
angle = 30 * np.pi / 180  # np默认角度为弧度制
# pytorch 以图片中心为原点进行旋转,并且在旋转过程中会发生图片缩放(为什么有图片缩放呢,缩放系数是多少?有看过源码了解的同学欢迎指教)
warp_img1 = torch_warp(angle, -1.9, -1.9)
warp_img2 = torch_warp(angle, -1, -1)
warp_img3 = torch_warp(angle, -0.5, -0.5)
warp_img4 = torch_warp(angle, 0, 0)
warp_img5 = torch_warp(angle, 0.5, 0.5)
warp_img6 = torch_warp(angle, 1, 1)
warp_img7 = torch_warp(angle, 1.9, 1.9)
plt.figure(figsize=(100,50))plt.subplot(241)
plt.imshow(warp_img1)
plt.subplot(242)
plt.imshow(warp_img2)
plt.subplot(243)
plt.imshow(warp_img3)
plt.subplot(244)
plt.imshow(warp_img4)
plt.subplot(245)
plt.imshow(warp_img5)
plt.subplot(246)
plt.imshow(warp_img6)
plt.subplot(247)
plt.imshow(warp_img7)

return:

6. opencv的 warpAffine 和 warpPerspective

warpAffine 只包括旋转,缩放,平移操作 。仿射变换
warpPerspective 透视变换

[1]http://man.hubwiz.com/docset/OpenCV.docset/Contents/Resources/Documents/da/d6e/tutorial_py_geometric_transformations.html
[2]https://opencv-python-tutorials.readthedocs.io/zh/latest/4. OpenCV中的图像处理/4.2. 图像的几何变换/

相关的一些方法介绍
[3]https://docs.opencv.org/4.x/da/d54/group__imgproc__transform.html
示例
[4]http://www.juzicode.com/opencv-python-warpaffine-rotate-warpperspective/

opencv和pytorch中的warp操作函数:cv2.warpAffine, torch.nn.functional.grid_sample, cv2.warpPerspective相关推荐

  1. NLP中的卷积操作详解(torch.nn.Conv1d)

    NLP领域中,由于自然文本是一维的,通常使用一维卷积即可达到要求. 在实际应用中,经embedding层处理后的数据格式一般为(batch_size, word_embeddings_dim, max ...

  2. PyTorch踩坑记录——torch.functional 与 torch.nn.functional的区别

    问题描述: 提示:刚入门深度学习,记录一些犯下的小错误: 由于本周开始试图复现华为的CTR库以增加记忆,熟悉代码细节,没想到第一天看基础模块的时候就遇到了麻烦,在torch.utils类中,有如下获取 ...

  3. pytorch中的卷积操作详解

    首先说下pytorch中的Tensor通道排列顺序是:[batch, channel, height, width] 我们常用的卷积(Conv2d)在pytorch中对应的函数是: torch.nn. ...

  4. pytorch中的乘法操作

    pytorch中提供了多种函数用于乘法操作,不同函数,功能有什么不一样呢? torch.mul multiply是mul的别名,与mul用法一致 torch.mul(input, other, *, ...

  5. 【C 语言】文件操作 ( C 语言中的文件操作函数 | 磁盘与内存缓冲区 | 缓冲区工作机制 )

    文章目录 一.C 语言中的文件操作函数 二.磁盘与内存缓冲区 三.缓冲区工作机制 一.C 语言中的文件操作函数 读取 文本文件 可以使用 getc , fgets , fscanf 函数 , 向 文本 ...

  6. C 中的内存操作函数-memcpy 等(to be continued)

    文章目录 C中的内存操作函数 1.memcpy() 1.1 函数介绍 1.2 示例代码 1.3 Reference C中的内存操作函数 1.memcpy() 1.1 函数介绍 void *memcpy ...

  7. python中squeeze函数_详解pytorch中squeeze()和unsqueeze()函数介绍

    squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...

  8. pytorch 中 expand ()函数

    pytorch 中 expand ()函数 expand函数的功能就是 用来扩展张量中某维数据的尺寸,它返回输入张量在某维扩展为更大尺寸后的张量. 例如: x = torch.tensor([1, 2 ...

  9. PyTorch 1.0 中文文档:torch.nn.functional

    译者:hijkzzz 卷积函数 conv1d torch.nn.functional.conv1d(input, weight, bias=None, stride=1, padding=0, dil ...

最新文章

  1. 创建新的用户以及一系列的操作
  2. ICCV2021最佳检测之一:主动学习框架较大提升目标检测精度(附论文下载)
  3. ajax 乱码问题 以及Response.charset=GB2312
  4. java引用变量_java代码声明引用变量经验
  5. Access to script at ‘xxx‘ from origin ‘null‘ has been blocked by CORS policy: Cross origin requests
  6. 【Java】深入理解Java随机数
  7. SpringCloud(二) 生产者、消费者工程搭建与调用(下)
  8. 程序员面试金典——9.9n皇后问题
  9. C语言 — 转义字符
  10. Linux C enum
  11. 使用作业异步调用存储过程的示例
  12. lua反射的一个例子
  13. Python+OpenCv实现摄像头人脸识别
  14. csgo靠谱的开箱网站有哪些?csgo开箱网站大全
  15. 15.2. switchport trunk encapsulation dot1q 提示 invaild input at^marker.
  16. 解锁网易云音乐客户端变灰歌曲
  17. 最新尚硅谷Java MyBatisPlus教程(完整)
  18. MySQL将表中的价格全部加五_MySQL浅见(五)修改表
  19. iOS开发中常用的那些工具
  20. RoboMaster视觉教程(4)装甲板识别算法

热门文章

  1. wangeditor 粘贴word内容带样式解决方法
  2. 笔记本如何同时上内外网
  3. 谷歌“隐私沙盒”引争议,广告业务与用户隐私难平衡?
  4. 消除Word文档被加密、限制编辑的解决方法
  5. 如何去除 aspose.cells 水印
  6. SVG中年月日相关的表达式
  7. Miller_Rabin和Pollard_Rho算法
  8. 点云旋转平移(三)—python open3d点云旋转
  9. 鸵鸟腿“半兽人”已学会跟踪避障,可自主移动到安全距离
  10. 耳机——AKG K450 及 Beats Solo2 对比