【pytorch】Pytorch 中的 grid 与 各种变换

Pytorch(三):数据变换 Transforms 目录0. 简介1. PIL Image and Tensor Image 都可用的转换(1) torchvision.transforms.CenterCrop(size) 一般情况下,预加载的数据集或自己构造的数据集并不能直接用于训练机器学习算法,为了将其转换为训练模型所需的最终形式,我们可以使用 transforms 对数据进行处理,以使其适合训练。 0. 简介 在介绍 Dataset 时,提到 torchvision.datasets 中的数据集都有两个参数: transform:可以对数据进行的变 阅读详情

Pytorch 中的 grid 与 各种变换

数学原理

**单应性(Homography) : 也就是透视变换。**单应性最初用来研究欧几里得几何中的透视和投影,而单应性一词,从词源学上来说,大致意思是“相似的绘图”。单应性的概念被引入来理解、解释和研究视觉透视,特别是从不同角度观察两个平面物体的外观差异。

Affine

Perspective

透视变换将二维图像坐标转换为三维齐次坐标,然后应用透视变换矩阵,最后将结果转换回二维坐标。通过旋转和平移将世界坐标中的点转换为相机坐标中的坐标,然后将这些坐标投影到传感器平面上。

其中 f 是焦距,(lx, ly) 是像素的物理尺寸,(cx, cy) 是相机的光学中心,以像素为单位。

方程 (1) 明确显示了针孔相机模型如何将 3D 点 (X, Y, Z) 投影到图像坐标 (u, v)

这里假设所有点**(X, Y, Z)**所在的scene是一个平面。也就是符合公式Z = αX + βY + γ。带入可得

将 P 的项与方程 (2) 中的 α、β 和 γ 混合,得到一个新的 3 x 3 未知矩阵 M,即透视变换矩阵:

为了求解 M 的项,我们必须首先将 λ=m20 X + m21 Y +m22 代入方程 (3),得到有 9 个未知数的齐次线性方程:

求解透视变换矩阵 M 的九个条目(最多一个缩放因子),以及物平面坐标 (X, Y) 与其像素值 (u, v) 之间的四个对应关系。

9个未知数,zero space为1维。因此有一个自由度,通常被设置为1。

Pytorch 官方文档解读

grid in pytorch

基础知识

grid in Pytorch

https://pytorch.org/docs/stable/generated/torch.nn.functional.grid_sample.html

grid in numpy

图像增强中的 变换api

torchvision.transforms.functional

torchvision.transforms.functional.affine(img: Tensor, angle: float, translate: List[int], scale: float, shear: List[float], interpolation: InterpolationMode = InterpolationMode.NEAREST, fill: Optional[List[float]] = None, center: Optional[List[int]] = None)

对比关系

torchvision.transforms.functional 中的 affine,通常用于图像处理和数据增强。

torch.nn.functional 中的 affine_grid 和 grid_sample 库,通常用于深度学习模型的操作和图像变换。torch.nn.functional.affine_grid 函数用于生成仿射变换的网格,torch.nn.functional.grid_sample 函数用于在输入图像上应用仿射变换。这些函数通常用于构建自定义的图像变换层或模型,以实现更灵活的图像空间变换。

另外图像变换中有perspective,而nn中没有。

torchvision.transforms.functional.perspective(img: Tensor, startpoints: List[List[int]], endpoints: List[List[int]], interpolation: InterpolationMode = InterpolationMode.BILINEAR, fill: Optional[List[float]] = None) → Tensor

  • img(Tensor):输入的图像,通常是一个PyTorch张量,可以是单通道或多通道的图像。
  • startpoints(List[List[int]]):一个包含4个起始点坐标的列表,每个起始点用一个 [x, y] 列表表示。这些起始点用于指定透视变换的原始四边形的四个顶点。
  • endpoints(List[List[int]]):一个包含4个目标点坐标的列表,每个目标点用一个 [x, y] 列表表示。这些目标点用于指定透视变换后的四边形的四个顶点。
  • interpolation(InterpolationMode,可选):指定插值方法的枚举类型。它表示在透视变换期间如何对图像进行插值。可选的插值方法包括 InterpolationMode.NEAREST(最近邻插值)和 InterpolationMode.BILINEAR(双线性插值)等。
  • fill(Optional[List[float]],可选):一个包含用于填充图像的颜色值的列表,通常表示为 [R, G, B]。如果未提供此参数,则使用默认值 [0, 0, 0] 进行填充。
  • startpoints 和 endpoints 分别指定了原始四边形和目标四边形的四个顶点,通过这些顶点之间的映射关系,函数将原始图像进行透视变换。 interpolation 参数允许你选择插值方法以保持图像的质量。如果需要在深度学习中执行透视变换,这个函数可以用于构建自定义的图像增强层。

具体实现:

函数用于执行透视变换,它接受输入图像、原始四边形的四个顶点、变换后的四边形的四个顶点、插值方式和填充值作为参数。函数根据参数选择使用Pillow(F_pil.perspective)或PyTorch(F_t.perspective)来执行透视变换。如果输入是PIL图像,它将使用Pillow进行变换,如果输入是PyTorch张量,它将使用PyTorch进行变换。函数的返回值是变换后的图像。

def perspective(
    img: Tensor,
    startpoints: List[List[int]],
    endpoints: List[List[int]],
    interpolation: InterpolationMode = InterpolationMode.BILINEAR,
    fill: Optional[List[float]] = None,
) -> Tensor:
    """执行给定图像的透视变换。
    如果图像是 Torch 张量,则预期其具有 [..., H, W] 的形状,其中 ... 表示任意数量的前导维度。

    Args:
        img (PIL 图像或张量): 要进行变换的图像。
        startpoints (list of list of ints): 包含四个包含两个整数的列表的列表,对应于原始图像的四个角
            ``[左上角, 右上角, 右下角, 左下角]``。
        endpoints (list of list of ints): 包含四个包含两个整数的列表的列表,对应于变换后图像的四个角
            ``[左上角, 右上角, 右下角, 左下角]``。
        interpolation (InterpolationMode): 期望的插值方式枚举,由:class:`torchvision.transforms.InterpolationMode` 定义。
            默认为 ``InterpolationMode.BILINEAR``。
            如果输入为张量,则仅支持 ``InterpolationMode.NEAREST`` 和 ``InterpolationMode.BILINEAR``。
            也可以接受对应的Pillow整数常数,如 ``PIL.Image.BILINEAR``。
        fill (sequence 或数字,可选): 用于填充变换后图像之外区域的像素值。如果给定一个数字,则分别用于所有波段。

            .. 注意::
                在 TorchScript 模式下,不支持单个 int/float 值,请使用长度为 1 的序列:``[value, ]``。

    Returns:
        PIL 图像或张量: 变换后的图像。
    """
    # 检查是否处于 TorchScript 或 Tracing 模式下,如果不是,则记录 API 使用情况
    if not torch.jit.is_scripting() and not torch.jit.is_tracing():
        _log_api_usage_once(perspective)

    # 获取透视变换的系数,这些系数将在后续的变换中使用
    coeffs = _get_perspective_coeffs(startpoints, endpoints)

    # 如果 interpolation 是整数,将其转换为对应的 InterpolationMode
    if isinstance(interpolation, int):
        interpolation = _interpolation_modes_from_int(interpolation)
    elif not isinstance(interpolation, InterpolationMode):
        raise TypeError(
            "Argument interpolation should be a InterpolationMode or a corresponding Pillow integer constant"
        )

    # 如果输入不是 Torch 张量,则使用 Pillow 进行透视变换
    if not isinstance(img, torch.Tensor):
        pil_interpolation = pil_modes_mapping[interpolation]
        return F_pil.perspective(img, coeffs, interpolation=pil_interpolation, fill=fill)

    # 如果输入是 Torch 张量,则使用 Torch 进行透视变换
    return F_t.perspective(img, coeffs, interpolation=interpolation.value, fill=fill)

利用**_get_perspective_coeffs** 利用最小二乘法获取变换矩阵。

**def** **_get_perspective_coeffs(startpoints:** **List[List[**int**]],** **endpoints:** **List[List[**int**]])** **->** **List[**float**]:**

用于计算透视变换的系数,这些系数会在透视变换时使用。函数根据给定的起始点(原始图像的四个角)和目标点(变换后图像的四个角)来计算这些系数,然后将它们返回供透视变换使用。函数内部使用了一些线性代数和矩阵运算,最终返回一个包含8个系数的列表,这些系数可以用于对图像进行透视变换。

def _get_perspective_coeffs(startpoints: List[List[int]], endpoints: List[List[int]]) -> List[float]:
    """Helper function to get the coefficients (a, b, c, d, e, f, g, h) for the perspective transforms.

    In Perspective Transform each pixel (x, y) in the original image gets transformed as,
     (x, y) -> ( (ax + by + c) / (gx + hy + 1), (dx + ey + f) / (gx + hy + 1) )

    Args:
        startpoints (list of list of ints): List containing four lists of two integers corresponding to four corners
            ``[top-left, top-right, bottom-right, bottom-left]`` of the original image.
        endpoints (list of list of ints): List containing four lists of two integers corresponding to four corners
            ``[top-left, top-right, bottom-right, bottom-left]`` of the transformed image.

    Returns:
        octuple (a, b, c, d, e, f, g, h) for transforming each pixel.
    """
    # 创建一个8x8的零矩阵 a_matrix,用于存储变换的系数
    a_matrix = torch.zeros(2 * len(startpoints), 8, dtype=torch.float)

    # 使用循环迭代四个角的坐标,计算变换系数并填充 a_matrix
    for i, (p1, p2) in enumerate(zip(endpoints, startpoints)):
        # 填充 a_matrix 的每一行
        a_matrix[2 * i, :] = torch.tensor([p1[0], p1[1], 1, 0, 0, 0, -p2[0] * p1[0], -p2[0] * p1[1]])
        a_matrix[2 * i + 1, :] = torch.tensor([0, 0, 0, p1[0], p1[1], 1, -p2[1] * p1[0], -p2[1] * p1[1]])

    # 创建 b_matrix,用于存储起始点坐标的矩阵并将其展平
    b_matrix = torch.tensor(startpoints, dtype=torch.float).view(8)

    # 使用最小二乘法计算变换系数 res
    res = torch.linalg.lstsq(a_matrix, b_matrix, driver="gels").solution

    # 将结果转换为列表并返回
    output: List[float] = res.tolist()
    return output

Pytorch 手写代码

perspective

# PyTorch 实现代码
import torch
import torch.nn.functional as F

def custom_perspective_transform(image, perspective_matrix):
    n, c, h, w = image.shape
    device = image.device

    # 创建二维坐标网格
    grid_x, grid_y = torch.meshgrid(
        torch.linspace(-1, 1, w, device=device),
        torch.linspace(-1, 1, h, device=device)
    )
    ones = torch.ones_like(grid_x)

    # 转换为齐次坐标
    grid_homogeneous = torch.stack([grid_x, grid_y, ones], dim=0).reshape(3, -1)  # [3, H*W]

    # 应用透视变换矩阵
    grid_transformed = torch.mm(perspective_matrix, grid_homogeneous)  # [3, H*W]

    # 将齐次坐标转换回普通坐标
    xy = (grid_transformed[:2, :] / grid_transformed[2:3, :]).t().reshape(h, w, 2)

    # 调整形状以适应 grid_sample
    xy = xy.unsqueeze(0).repeat(n, 1, 1, 1)  # [N, H, W, 2]

    # 应用网格采样
    transformed_image = F.grid_sample(image, xy, align_corners=True)

    return transformed_image

# 示例使用
# 假设 'checkerboard_tensor' 是之前创建的方格图像张量
# 'perspective_matrix' 是透视变换矩阵
transformed_checkerboard = custom_perspective_transform(checkerboard_tensor, perspective_matrix)

Perspective 可反向传播

import torch
import torch.nn.functional as F
from torch.autograd import Function
from torchvision.transforms.functional import InterpolationMode
from typing import List, Optional

class PerspectiveTransformFunction(Function):
    @staticmethod
    def forward(ctx, img, startpoints, endpoints, interpolation, fill):
        # 计算透视变换的系数
        coeffs = _get_perspective_coeffs(startpoints, endpoints)

        # 执行透视变换
        if not isinstance(interpolation, InterpolationMode):
            interpolation = InterpolationMode(interpolation)
        output = F.grid_sample(img, coeffs.view(1, 8, 1, 1), interpolation=interpolation, padding_mode='border', align_corners=True)
        
        # 保存需要的信息以备反向传播
        ctx.save_for_backward(coeffs, img)
        ctx.interpolation = interpolation
        ctx.fill = fill

        return output

    @staticmethod
    def backward(ctx, grad_output):
        # 获取需要的信息
        coeffs, img = ctx.saved_tensors
        interpolation = ctx.interpolation
        fill = ctx.fill

        # 计算梯度
        grad_input = F.grid_sample(grad_output, coeffs.view(1, 8, 1, 1), interpolation=interpolation, padding_mode='border', align_corners=True)
        
        return grad_input, None, None, None, None

class PerspectiveTransform:
    def __init__(self, startpoints, endpoints, interpolation=InterpolationMode.BILINEAR, fill=None):
        self.startpoints = startpoints
        self.endpoints = endpoints
        self.interpolation = interpolation
        self.fill = fill

    def __call__(self, img):
        return PerspectiveTransformFunction.apply(img, self.startpoints, self.endpoints, self.interpolation, self.fill)

使用测试案例

from torchvision.transforms.functional import to_pil_image, to_tensor
from PIL import Image

# 步骤1: 生成棋盘格图像并保存到磁盘
# 创建一个函数来生成棋盘格图像
def generate_chessboard(width, height, rows, cols):
    image = Image.new("RGB", (width, height), (255, 255, 255))
    draw = ImageDraw.Draw(image)

    cell_width = width // cols
    cell_height = height // rows

    color1 = (0, 0, 0)
    color2 = (255, 255, 255)

    for row in range(rows):
        for col in range(cols):
            if (row + col) % 2 == 0:
                color = color1
            else:
                color = color2

            x0 = col * cell_width
            y0 = row * cell_height
            x1 = x0 + cell_width
            y1 = y0 + cell_height

            draw.rectangle([x0, y0, x1, y1], fill=color)

    image.save("chessboard.png")

# 调用生成函数来生成棋盘格图像
generate_chessboard(400, 400, 8, 8)

# 步骤2: 执行透视变换
# 创建一个透视变换对象
startpoints = [[0, 0], [300, 0], [300, 300], [0, 300]]
endpoints = [[50, 50], [250, 0], [250, 250], [50, 250]]
transform = PerspectiveTransform(startpoints, endpoints)

# 读取生成的棋盘格图像
chessboard_img = Image.open("chessboard.png")

# 将图像转换为Tensor
img_tensor = to_tensor(chessboard_img).unsqueeze(0)

# 执行透视变换
transformed_img = transform(img_tensor)

# 步骤3: 将变换后的图像显示或保存
output_img = to_pil_image(transformed_img.squeeze(0))
output_img.show()  # 显示变换后的图像
output_img.save("transformed_chessboard.png")  # 保存变换后的图像

库代码

OpenCV 文档:

Perspective

https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#warpperspective

Affine

https://docs.opencv.org/2.4/modules/imgproc/doc/geometric_transformations.html#warpaffine

https://docs.opencv.org/4.x/d4/d61/tutorial_warp_affine.html

尝试代码

import torch
import torch.nn.functional as F
import numpy as np
import matplotlib.pyplot as plt

def perspective_transform(image, perspective_matrix):
    n, c, h, w = image.shape
    # 生成标准网格
    grid = F.affine_grid(torch.eye(2, 3).unsqueeze(0), image.size(), align_corners=False)
    # 将网格转换为齐次坐标
    homogeneous_grid = torch.cat([grid, torch.ones(n, h, w, 1, device=grid.device)], dim=-1)
    # 应用透视变换矩阵
    warped_grid = torch.matmul(homogeneous_grid, perspective_matrix.transpose(1, 2))
    # 将齐次坐标转换回非齐次坐标
    warped_grid_xy = warped_grid[..., :2] / warped_grid[..., 2:3]
    warped_grid_xy = warped_grid_xy.permute(0, 3, 1, 2)  # 转换为 (N, C, H, W) 格式
    # 应用网格采样
    transformed_image = F.grid_sample(image, warped_grid_xy, align_corners=False, padding_mode='zeros')
    return transformed_image

# 创建一个简单的方格图像
def create_checkerboard(h, w, square_size):
    img = np.zeros((h, w))
    s = square_size
    for y in range(0, h, s*2):
        for x in range(0, w, s*2):
            img[y:y+s, x:x+s] = 1.0
            img[y+s:y+s*2, x+s:x+s*2] = 1.0
    return img

# 创建方格图像
h, w = 256, 256
square_size = 32
checkerboard = create_checkerboard(h, w, square_size)

# 转换为 PyTorch 张量
checkerboard_tensor = torch.tensor(checkerboard, dtype=torch.float32).unsqueeze(0).unsqueeze(0)

# 创建透视变换矩阵
perspective_matrix = torch.tensor([
    [1.0, 0.0, 0.0],
    [0.0, 1.0, 0.0],
    [0.0, 0.001, 1.0]
], dtype=torch.float32).unsqueeze(0)

# 应用透视变换
transformed_checkerboard = perspective_transform(checkerboard_tensor, perspective_matrix)

# 显示原始和变换后的图像
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.imshow(checkerboard, cmap='gray')
plt.title('Original Checkerboard')
plt.subplot(1, 2, 2)
plt.imshow(transformed_checkerboard[0, 0].detach().numpy(), cmap='gray')
plt.title('Transformed Checkerboard')
plt.show()

# 测试梯度
perspective_matrix.requires_grad = True
transformed_checkerboard_grad = perspective_transform(checkerboard_tensor, perspective_matrix)
loss = transformed_checkerboard_grad.sum()
loss.backward()

# 检查梯度是否存在
print("Perspective matrix gradient:", perspective_matrix.grad)

利用矩阵乘法解决这个问题。每次透视变换前,构造一个足够大的0值图像。对目标图像乘变换矩阵后,放入新建的图像中。注意不要让图像边缘超出去。

为了实现透视变换并确保梯度能够被正确计算,我们可以采取一种稍微不同的方法。这个方法包括以下步骤:

  1. 首先,我们会构建一个足够大的空白图像(全零值)作为变换后的画布。
  2. 然后,我们将使用透视变换矩阵来变换原始图像中的像素位置。
  3. 对于变换后的每个像素位置,我们将从原始图像中复制对应的像素值到新的位置上。
  4. 为了防止变换后的图像边缘超出新画布的边界,我们需要适当地选择画布的大小和变换矩阵。

这种方法可以通过矩阵乘法和索引操作来实现,允许在 PyTorch 中进行梯度的反向传播。我将编写一个示例实现来展示这个过程:

import torch
import numpy as np
import matplotlib.pyplot as plt

def apply_perspective_transform(image, perspective_matrix, output_size):
    n, c, h, w = image.shape
    # 创建输出图像(空白画布)
    output_image = torch.zeros(n, c, *output_size, device=image.device)

    # 生成网格
    y, x = torch.meshgrid(torch.linspace(-1, 1, h), torch.linspace(-1, 1, w))
    z = torch.ones_like(x)
    grid = torch.stack([x, y, z], dim=-1).view(-1, 3).t()  # 3 x (H*W)

    # 应用透视变换
    transformed_grid = torch.mm(perspective_matrix, grid)  # 3 x (H*W)

    # 将齐次坐标转换为笛卡尔坐标
    xy = transformed_grid[:2, :] / transformed_grid[2, :]
    xy = xy.t().view(h, w, 2)

    # 将变换后的坐标映射到输出图像上
    for i in range(h):
        for j in range(w):
            x, y = xy[i, j]
            if -1 <= x <= 1 and -1 <= y <= 1:
                # 将像素值复制到新位置
                xi, yi = int((x + 1) / 2 * (output_size[1] - 1)), int((y + 1) / 2 * (output_size[0] - 1))
                output_image[0, :, yi, xi] = image[0, :, i, j]

    return output_image
```![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a0b5ce4a275d4d68a95c885a513af1af.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/811d7261f2cc4b2d835bff3553258b59.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d52d11559e61484c98f7d4e1c502e16e.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/30dc001dbb0649b3a2e0e546c9e07a63.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/154dcdacf669468e8919ef0dffe6620e.png#pic_center)

GDI图像缩放算法类型 缩放时的算法模式(TInterpolationMode 枚举)列表: InterpolationModeInvalid = -1; {等效于 QualityMode 枚举的 Invalid 元素. } InterpolationModeDefault = 0; {指定默认模式. } InterpolationModeLowQuality = 1; {指定低质量插值法. } InterpolationModeHighQuality 阅读详情

相关推荐

pytorch---仿射变换

一、仿射变换 图片的旋转、平移、缩放等可以看做一个像素的重采样过程。将原图的像素映射到目标图像的对应位置上,可以 其中为原图的坐标,x,y为目标图的坐标,该变换称为前向变换,遍历原图像素,求出改像素在目标图像的对应位置。 前向变换虽然符合逻辑,但是却使得目标图...

goodxin_ie的博客 7460

pytorch: torch.nn.functional.affine_grid(theta,size)

# 仍有部分疑惑  torch.nn.functional.affine_grid(theta,size): 给定一组仿射矩阵(theta),生成一个2d的流场.通常与 grid_sample() 结合使用,用于空间变换网络. 参数:         theta(Tensor 类型):输入的一组仿射矩阵(N*2*3)         size(torch.Size 类型):要输出的图像的...

wzg2016的博客 5570

Pytorch中的仿射变换(F.affine_grid)

在pytorch框架中, F.affine_grid 与 F.grid_sample(torch.nn.functional as F)联合使用来对图像进行变形。F.affine_grid 根据形变参数产生sampling grid,F.grid_sample根据sampling grid对图像进行变形。需要注意,pytorch中的F.grid_sample是反向采样,这就导致了形变参数与直觉是相反的(后面有实验验证)(例如放射矩阵中的缩放因子是0.5,会使目标图像扩大两倍;

知识搬运者 3985

生成复杂形变:PyTorch中d维动态形变场与仿射变换的底层机制及grid_sample替代方案解析

本文详细讲解了PyTorch中d维随机变形场(DVFs)和仿射变换的实现方法及其在医学影像配准与计算机视觉中的应用。首先介绍了变形场和仿射变换的科研价值,然后通过数学原理和代码实例(包括2D正弦变形场、3D多项式变形场和2D仿射变换)展示了具体实现过程。此外,还提出了自定义双线性插值的方案作为grid_sample的替代方法,为科研工作者提供了灵活高效的技术解决方案。

m0_71589036的博客 4654

Windows 10下用vcpkg一键搞定libcurl开发环境(Code::Blocks 20.03配置指南)

本文详细介绍了在Windows 10系统下使用vcpkg工具快速配置libcurl开发环境的完整指南,特别针对Code::Blocks 20.03 IDE进行优化设置。通过vcpkg自动化管理依赖项,简化libcurl的安装与配置过程,帮助开发者高效搭建网络通信功能开发环境,并提供了常见问题解决方案和实际项目中的最佳实践。

weixin_28040125的博客 249

快速批量Radon变换的Python实现——使用PyTorch函数affine_grid和grid_sample

Radon变换的旋转过程 Radon变换的旋转过程可以使用ndimage.rotate()对图像进行特定角度的旋转,但这个过程比较耗时,不利于投影角度较多或者需要对批量图像进行Radon变换的情况。而通过利用PyTorch中的仿射变换相关函数affine_grid()和grid_sample()也可以实现旋转的过程,可以在GPU上进行运算,Radon变换所需的时间大幅减少。 快速批量Radon变换的Python实现 from scipy import ndimage import numpy as np i

kouwang9779的博客 2341

拆解英飞凌CoolGaN:如何用Silvaco TCAD仿真评估功率GaN HEMT的关键性能(BV、Qg、开关损耗)

本文详细解析了如何使用Silvaco TCAD仿真工具评估英飞凌CoolGaN功率GaN HEMT的关键性能指标,包括击穿电压(BV)、栅电荷(Qg)和开关损耗。通过精确建模极化效应、优化边缘终端结构以及高频开关损耗仿真技术,为功率器件工程师提供了一套完整的'设计-仿真-验证'方法论,助力GaN HEMT在快充、数据中心电源等领域的应用。

weixin_29159995的博客 427

opencv warpAffine 变换矩阵转换成pytorch F.affine_grid变换矩阵

opencv中的warpAffine为以图像原点旋转,而pytorch中的F.affine_grid为以图片中心旋转,此外warpAffine的平移变换以像素为单位进行,而F.affine_grid以宽高的比率进行平移变换,需要对其变换矩阵进行一个转换。 在warpAffine中的变换矩阵H为: 其中: ,为x与y方向的偏移量 将其转换成F.affine...

Eddy_Wu23的博客 1606

面板数据门槛归回分析,xthreg的安装,xthreg2安装包

我用的是Stata17,数据是不平衡的面板数据,需要用到xthreg2,虽然我找到了xthreg2.ado,但是还需要安装xthreg,因为运行xthreg2需要xthreg包顺带安装的lxthreg.mlib文件。但是!我后来发现还是不行,最后是去买了一个真正能用到xthreg2的lxthreg.mlib文件,才可以运行。

weixin_55252589的博客 1万+

告别卡顿!手把手教你用北鲲云超算平台图形化提交COMSOL仿真任务(附RDP连接技巧)

本文详细介绍了如何利用北鲲云超算平台图形化提交COMSOL仿真任务,解决本地计算资源不足导致的卡顿问题。通过云端高性能计算,用户可轻松配置多核CPU和大内存资源,实现高效仿真计算,并附有RDP连接优化技巧,提升远程操作体验。

weixin_42519781的博客 379

正常的仿射变换矩阵F和pytorch的affine_grid()中 “theta”的区别

记录一个大坑!!! https://discuss.pytorch.org/t/how-to-convert-an-affine-transform-matrix-into-theta-to-use-torch-nn-functional-affine-grid/24315/3

weixin_43905212的博客 1514

【Unity】Gif图片播放插件(支持UI及模型纹理渲染两种模式)

unity本身不支持GIF格式文件直接渲染, 因此一般的做法是通过加载图片,通过代码控制其循环播放、停止等,模拟动画效果,本文简单介绍一下某个现有开源工具,感谢开源作者。

灵境引路人 4036

【grid】pytorch中的Flow_filed,MES,affine_gridHGRID,GRID_SAMPLE详解

specifiesinputxandy根据输入值和映射网格(flow-field grid)计算输出。它主要用于在图像处理和计算机视觉任务中,根据给定的网格对输入数据进行采样和插值。提供一个input的Tensor以及一个对应的flow-field网格(比如光流,体素流等),然后根据grid中每个位置提供的坐标信息(这里指input中pixel的坐标),将input中对应位置的像素值填充到grid指定的位置,得到最终的输出。

prinTao的博客 2121

YOLOv8改进 | 主干篇 | 利用MobileNetV2替换Backbone(轻量化网络结构)

本文给大家带来的改进机制是,其是专为移动和嵌入式视觉应用设计的轻量化网络结构。这些模型基于简化的架构,并利用深度可分离卷积构建轻量级深度神经网络,其引入了两个简单的全局超参数,用于在延迟和准确性之间进行有效的权衡。实验表明,MobileNets在资源和准确性的权衡方面表现出色,并在多种应用(如对象检测、细粒度分类、面部属性识别和大规模地理定位)中展现了其有效性,这个模型非常适合轻量化的读者来使用。适用检测目标:轻量化网络结构适合轻量化的读者⭐⭐⭐⭐。

Snu77的博客 5683

最新Python爬虫实战(入门爬虫篇)——案例20:某股票数据采集(详细爬虫思路截图+抓包动图演示+完整爬虫代码+详细注释)

本次案例针对某股票行情网的静态HTML页面,实现了全市场股票数据的全自动化爬取,覆盖了从抓包分析、请求模拟、数据解析到数据存储的完整爬虫流程,非常适合入门学习者巩固基础,核心知识点和实现要点总结如下:首先是页面分析的核心逻辑,静态HTML页面的数据爬取,核心在于通过浏览器开发者工具,完成完整的抓包分析和标签结构定位。我们不需要像动态页面那样找隐藏的API接口,只需要确认数据在主文档的HTML源码中,然后通过元素选择器,精准找到每个字段对应的标签,总结出统一的标签结构规律,就能实现批量数据提取。

努力让自己发光,对的人才能迎着光而来 19万+

pytorch中的grid_sample()

torch.nn.functional.grid_sample 首先我们看pytorch文档中给出的描述: torch.nn.functional.grid_sample(input, grid, mode=‘bilinear’, padding_mode=‘zeros’, align_corners=None) Given an input and a flow-field grid, computes the output using input values and pixel location

weixin_43559672的博客 5701

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

关于F.grid_sample和F.affine_grid函数的介绍

Python中的PIL的img.show()函数不能显示图像 运行结果没有报错,但是不能显示图片,原因是由于没有设置默认打开图片的软件。 解决办法:搜索画图软件,将其设置为默认打开jpg或bmp等类型图片的软件,即可。 待更新:怎么将tensor类型的数据格式显示成图片? ...

Epoch511的博客 4614

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

PyTorch视觉工具箱:图像变换与上采样技术详解(2)

在这篇博客中,我们探讨了PyTorch中几个关键的视觉函数,它们在进行图像和视频处理时扮演着重要的角色。和用于上采样操作,通过最近邻和双线性插值方法来增加输入张量的空间尺寸;用于更复杂的空间变换,允许根据提供的网格对输入张量进行采样和变换;生成用于空间变换的采样网格,通常与结合使用来构建空间变换网络。所有这些函数都支持多种插值和填充模式,提供了对图像的高级操作能力。

CDBmax的博客 1289

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

pytorch tensor 实现 cv2.warpAffine( ) -- 未果

因为处理数据需求,要对tensor实现 cv2.warpAffine( )的功能 原图: size = 360 × 480 首先cv2.warpAffine( ), import cv2 import numpy as np img_path = r'C:\Users\优快云\Desktop\00000001.jpg' image = cv2.imread(img_path) mapping2 = np.array([[ 1.23704604, 0., -256], [ 0.,

Jee_King的博客 2456

一文彻底弄懂 PyTorch 的 `F.grid_sample`

通过上面的示例计算,我们可以看到如何将归一化坐标转换为输入张量的实际坐标,以及如何使用双线性插值计算采样点的值。具体示例展示了从输入张量和处采样的详细过程。通过双线性插值在输入张量中进行采样,即使坐标是小数,也能准确地计算出相应位置的值。这对于需要高精度变换和采样的任务非常有用。通过这种方法,我们可以实现高精度的图像处理和分析。

weixin_41496173的博客 1万+

pytorch实现图像中的仿射、平移、缩放、旋转等变换

最近在做关于深度图像配准、图像矫正等相关算法,因此需要实现对图像的仿射变换,总结一些方法: opencv实现各种图像变换: 1.cv2.warpAffine()放射变换函数,可实现旋转,缩放,平移;变换后的平行线依旧平行, 2.cv2.warpPerspective()透视变换函数,可保持直线不变形,但是平行线可能不再平行 可以参考下面的博客: cv2.warpAffine(),cv2.warpPerspective()函数解析 那么在使用深度学习中,就需要用到pytorch实现图像的各种变换,一般可以用F

qq_37516798的博客 5930

torch.nn.functional.grid_sample()详解

简单来说就是,提供一个input的Tensor以及一个对应的flow-field网格(比如光流,等),然后根据grid中每个位置提供的坐标信息(这里指input中pixel的坐标),将input中对应位置的像素值填充到grid指定的位置,得到最终的输出。是 PyTorch 中的一个函数,用于对输入图像或张量进行采样和插值。该函数通过指定的网格坐标 (grid) 来图像中的像素,实现图像的变换(如仿射变换、透视变换等)。

yiwangfl的博客 1349
上一篇: 【grid】pytorch中的Flow_filed,MES,affine_gridHGRID,GRID_SAMPLE详解
下一篇: 【cuda】一、基础知识 thread grid
prinTao
博客等级 码龄7年 5600粉丝 183原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值