opencv - 反转实值索引网格

标签 opencv math image-processing remap bilinear-interpolation

OpenCV 的 remap()使用实值索引网格使用双线性插值从图像中采样值网格,并将样本网格作为新图像返回。

准确地说,让:

A = an image 
X = a grid of real-valued X coords into the image. 
Y = a grid of real-valued Y coords into the image.
B = remap(A, X, Y)

那么对于所有的像素坐标i,j,

B[i, j] = A(X[i, j], Y[i, j]) 

其中圆括号表示法 A(x, y) 表示使用双线性插值法使用浮点值坐标 xy

我的问题是:给定一个索引网格XY,我怎样才能生成一个“逆向网格”X^-1Y^-1 这样:

X(X^-1[i, j], Y^-1[i, j]) = i
Y(X^-1[i, j], Y^-1[i, j]) = j

X^-1(X[i, j], Y[i, j]) = i
Y^-1(X[i, j], Y[i, j]) = j

对于所有整数像素坐标i, j?

FWIW,图像和索引图 X 和 Y 的形状相同。但是,索引映射 X 和 Y 没有先验结构。例如,它们不一定是仿射或刚性变换。它们甚至可能是不可逆的,例如如果 X, YA 中的多个像素映射到 B 中相同的精确像素坐标。我正在寻找一种方法的想法,如果一个存在。

解决方案不需要基于 OpenCV,因为我使用的不是 OpenCV,而是另一个具有 remap() 实现的库。虽然欢迎提出任何建议,但我特别热衷于“数学上正确”的东西,即如果我的 map M 是完全可逆的,该方法应该在机器精度的一些小范围内找到完美的逆。

最佳答案

好吧,我只需要自己解决这个重映射反演问题,我将概述我的解决方案。

给定 XY 用于执行以下操作的 remap() 函数:

B[i, j] = A(X[i, j], Y[i, j])   

我计算了 XinvYinv 可以被 remap() 函数用来反转过程:

A[x, y] = B(Xinv[x,y],Yinv[x,y])

首先我构建一个 KD-Tree对于 2D 点集 {(X[i,j],Y[i,j]} 所以我可以有效地找到 N 给定点的最近邻居 (x,y). 我使用欧几里德距离作为我的距离度量。我在 GitHub 上找到了一个很棒的 C++ header lib for KD-Trees

然后我遍历 A 网格中的所有 (x,y) 值并找到 N = 5 最近的邻居 {(X[i_k,j_k],Y[i_k,j_k]) | k = 0 .. N-1} 在我的点集中。

  • 如果距离 d_k == 0 对于一些 k 那么 Xinv[x,y] = i_kYinv [x,y] = j_k,否则...

  • 使用 Inverse Distance Weighting (IDW)计算内插值:

    • 让权重w_k = 1/pow(d_k, p)(我使用p = 2)
    • Xinv[x,y] = (sum_k w_k * i_k)/(sum_k w_k)
    • Yinv[x,y] = (sum_k w_k * j_k)/(sum_k w_k)

请注意,如果 BW x H 图像,则 XYW x H float 组。如果 Aw x h 图像,则 XinvYinvw x h float 数组.与图像和 map 大小保持一致很重要。

工作起来很有魅力!我的第一个版本尝试了暴力搜索,我什至从未等待它完成。我切换到 KD-Tree 然后我开始获得合理的运行时间。如果有时间,我想将其添加到 OpenCV。

下面的第二张图片使用 remap() 去除第一张图片的镜头畸变。第三张图片是反转过程的结果。

enter image description here enter image description here enter image description here

关于opencv - 反转实值索引网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41703210/

相关文章:

mysql - Google BigQuery 中的 Haversine 距离

python - cv2.VideoCapture 无法在 Mac 主机上的 docker 容器中工作

python - 如何使用python在opencv中设置视频捕获格式?

python - opencv中的单应性和图像缩放

algorithm - 我如何找到大 C(n , r) 的模数

python - OpenCV : Python equivalent of `setTo` in C++

c++ - 无法从灰度图像访问像素值

math - 如何使用带有数学公式的对数似然相似度度量来计算相似度?

python - OpenCV 错误 : bitwise_and throws error that mask and image are not same size

java - Android 5 中的图像内存不足