numpy 反球面翘曲

ifsvaxew  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(114)

我有一个相机矩阵K,一个旋转矩阵R,和一个比例因子sf。我已经使用这些来使用以下代码将点集pointset变形为球形图像:

import numpy as np
import cv2 as cv

sf =  1000

K = np.array([[1165, 0, 540],
              [0, 1165, 960],
              [0, 0, 1]], dtype=np.float32)

R = np.array([[-0.98932076, -0.03953766,  0.14028972],
              [0.05826942,  0.7749584,   0.6293204],
              [-0.13360056,  0.6307743,  -0.7643786]], dtype=np.float32)

pointset = np.array([[856,   51],
                     [1023,   51],
                     [792,   70],
                     [908,  103],
                     [540,  173],
                     [985,  180],
                     [1023,  180],
                     [1023,  270]], dtype=np.float32)

warper = cv.PyRotationWarper("spherical", sf)
warped_pt_set = []
for pt in pointset:
    wp_pt = warper.warpPoint(pt, K, R)
    warped_pt_set.append(
        (int(wp_pt[0]), int(wp_pt[1])))

warped_pt_set = np.array(warped_pt_set, dtype=np.float32)

现在我想使用函数dewarpPoint(pt,K,R,sf)从扭曲点集warped_pt_set获得原始点集pointset
你能帮我实现这个功能吗?

warped_pt_set

[[-3066.  1601.]
 [-2961.  1607.]
 [-3107.  1609.]
 [-3029.  1631.]
 [ 3002.  1658.]
 [-2972.  1676.]
 [-2948.  1676.]
 [-2937.  1729.]]
ugmeyewa

ugmeyewa1#

找到OpenCV的C++原始代码。所以我构建了函数DewarpPoint()
效果很好。

def dewarpPoint(uv, K, R, sf):
    k_rinv = np.dot(K, R.T)

    u, v = uv[0], uv[1]
    u /= sf
    v /= sf

    sinv = math.sin(math.pi - v)
    x_ = sinv * math.sin(u)
    y_ = math.cos(math.pi - v)
    z_ = sinv * math.cos(u)

    z = k_rinv[2][0] * x_ + k_rinv[2][1] * y_ + k_rinv[2][2] * z_
    x = (k_rinv[0][0] * x_ + k_rinv[0][1] * y_ + k_rinv[0][2] * z_) / z if z > 0 else -1
    y = (k_rinv[1][0] * x_ + k_rinv[1][1] * y_ + k_rinv[1][2] * z_) / z if z > 0 else -1

    return np.array([x, y])

但是**warpPoint()**产生错误的结果。

def warpPoint(xy, K, R, sf):
    r_kinv = np.dot(R, np.linalg.inv(K))

    x_, y_ = xy[0], xy[1]
    x_ = r_kinv[0][0] * x_ + r_kinv[0][1] * y_ + r_kinv[0][2]
    y_ = r_kinv[1][0] * x_ + r_kinv[1][1] * y_ + r_kinv[1][2]
    z_ = r_kinv[2][0] * x_ + r_kinv[2][1] * y_ + r_kinv[2][2]

    u = sf * np.arctan2(x_, z_)
    w = y_ / np.sqrt(x_ * x_ + y_ * y_ + z_ * z_)
    v = sf * (np.pi - np.arccos(w if not np.isnan(w) else 0))

    return np.array([u, v])

相关问题