You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过矩阵运算实现numpy reshape后灰度图像的旋转与插值

图像绕指定点旋转的向量式实现思路

首先明确基础映射关系:假设输入灰度图像尺寸为高H、宽W,C风格展平为一维向量时,二维坐标(h, w)(h为行索引、w为列索引)对应的一维索引为idx = h * W + w。


核心逻辑说明

你需要的变换公式中,A是稀疏采样权重矩阵,形状为(M, N),其中M是输出图像总像素数、N是输入图像总像素数:

  • 每行对应一个输出像素,行内非零值为输入像素对当前输出像素的贡献权重
  • 要支持双线性插值的话,每行最多4个非零权重,总和为1
  • 偏移向量b如果仅做坐标旋转的话全为0,仅当需要调整整体灰度偏置时才需赋值,坐标变换的偏移已经隐含在A的权重分布中

如果要用齐次坐标简化为单矩阵运算,只需给输入一维向量补1个值为1的维度,构造形状为(M, N+1)的增广矩阵[A | b]即可直接完成乘法运算。

具体实现步骤

1. 计算输出图像尺寸

首先对输入图像四个角点做旋转变换,计算旋转后的坐标范围,避免内容截断:

import numpy as np
# 输入参数:原始图像img,旋转中心(cx, cy),旋转角theta(弧度,逆时针为正)
H, W = img.shape
corners = np.array([[0, 0], [W-1, 0], [0, H-1], [W-1, H-1]])
cos_t, sin_t = np.cos(theta), np.sin(theta)
# 角点旋转
rot_corners = np.zeros_like(corners)
rot_corners[:, 0] = (corners[:,0] - cx)*cos_t - (corners[:,1] - cy)*sin_t + cx
rot_corners[:, 1] = (corners[:,0] - cx)*sin_t + (corners[:,1] - cy)*cos_t + cy
# 计算输出尺寸
min_w, max_w = rot_corners[:,0].min(), rot_corners[:,0].max()
min_h, max_h = rot_corners[:,1].min(), rot_corners[:,1].max()
W_out = int(np.ceil(max_w - min_w)) + 1
H_out = int(np.ceil(max_h - min_h)) + 1

2. 构造权重矩阵A

如果图像尺寸较大,建议用scipy.sparse.csr_matrix存储稀疏矩阵,避免内存溢出:

from scipy.sparse import csr_matrix
N = H * W
M = H_out * W_out
data = []
row_idx = []
col_idx = []

for h_out in range(H_out):
    for w_out in range(W_out):
        # 输出坐标映射回旋转后的世界坐标
        w_rot = w_out + min_w
        h_rot = h_out + min_h
        # 逆旋转得到输入图像上的浮点采样坐标(避免正向变换产生孔洞)
        w_float = cx + (w_rot - cx)*cos_t + (h_rot - cy)*sin_t
        h_float = cy - (w_rot - cx)*sin_t + (h_rot - cy)*cos_t
        # 边界过滤:超出输入图像范围的像素直接填0
        if w_float < 0 or w_float >= W or h_float <0 or h_float >= H:
            continue
        # 双线性插值权重计算
        w0, w1 = int(np.floor(w_float)), int(np.ceil(w_float))
        h0, h1 = int(np.floor(h_float)), int(np.ceil(h_float))
        dw = w_float - w0
        dh = h_float - h0
        # 四个相邻点的权重
        weights = [
            (1-dw)*(1-dh), # w0,h0
            dw*(1-dh),     # w1,h0
            (1-dw)*dh,     # w0,h1
            dw*dh          # w1,h1
        ]
        # 四个相邻点的输入一维索引
        cols = [
            h0 * W + w0,
            h0 * W + w1 if w1 < W else h0*W +w0,
            h1 * W + w0 if h1 < H else h0*W +w0,
            h1 * W + w1 if (w1 < W and h1 < H) else h0*W +w0
        ]
        # 写入稀疏矩阵参数
        current_row = h_out * W_out + w_out
        for w, col in zip(weights, cols):
            if w > 0:
                data.append(w)
                row_idx.append(current_row)
                col_idx.append(col)
# 构造稀疏矩阵A
A = csr_matrix((data, (row_idx, col_idx)), shape=(M, N))

3. 执行变换得到结果

# 输入向量C风格展平
input_vec = img.reshape(-1)
# 执行变换,b全0时可省略
rotated_vec = A @ input_vec
# reshape为二维图像
rotated_img = rotated_vec.reshape(H_out, W_out)

优化提示

如果不需要双线性插值改用最近邻插值,只需取h_float和w_float四舍五入后的整数坐标,每行仅存1个权重为1的非零元素,矩阵尺寸会更小,运算速度更快。

内容的提问来源于stack exchange,提问作者E.G.A.L.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 21:57:02