如何从Python调用OpenCV focalsFromHomography



OpenCV文档显示

focalsFromHomography()
void cv::detail::focalsFromHomography   (const Mat &H,
double &    f0,
double &    f1,
bool &      f0_ok,
bool &      f1_ok 
)       
Python:
cv.detail.focalsFromHomography( H, f0, f1, f0_ok, f1_ok ) -> None

事实上,我可以这样称呼focalsFromHomography,没有错误:

f0 = 0.0
f1 = 0.0
f0_ok = False
f1_ok = False
r = cv.detail.focalsFromHomography(
mat,
f0, f1,
f0_ok, f1_ok
)

当然,它不会返回任何内容,也不会、不能更改f0和f1。

如果我这样称呼它:

f0 = c_double()
f1 = c_double()
f0_ok = c_bool()
f1_ok = c_bool()
r = cv.detail.focalsFromHomography(
mat,
byref(f0), byref(f1),
byref(f0_ok), byref(f1_ok)
)

我得到一个错误";TypeError:参数"f0"不能被视为双精度参数";,这是真的,f0不是一个double,而是对double的引用,因为我想在f0中接收结果。

我怎么能叫";focalsFromHomography";并接收估计的焦点?

到目前为止,我唯一的解决方案是从OpenCV源代码中复制算法,并逐行手动将其转换为Python代码。它只有20行,所以它是可行的,但并不好。

很遗憾,我在回答我自己的问题。用Python重写代码似乎是唯一的解决方案。

@staticmethod
def _focalsfromhomography(
mat: np.ndarray) -> tuple[float | None, float | None]:
"""
Estimate focal lengths from the given homography under
the assumption that the camera undergoes rotations
around its center only.
https://docs.opencv.org/4.x/d4/dbc/group__stitching__autocalib.html
https://github.com/opencv/opencv/blob/4.x/modules/stitching/src/autocalib.cpp
Rewriten in pure Python, because it was a bit difficult
to call the native OpenCV function.
:param mat: Homography matrix
:return: (f0, f1)
"""
# Fast access
h = np.reshape(mat, 9)
# f1
f1 = None
# Denominators
d1 = h[6] * h[7]
d2 = (h[7] - h[6]) * (h[7] + h[6])
# Focal squares value candidates
v1 = -(h[0] * h[1] + h[3] * h[4])
v1 = v1 / d1 if d1 != 0.0 else -1.0
v2 = (h[0] - h[1]) * (h[0] + h[1]) + (h[3] - h[4]) * (h[3] + h[4])
v2 = v2 / d2 if d2 != 0.0 else -1.0
if v1 < v2:
v1, v2 = v2, v1
if v1 > 0 and v2 > 0:
f1 = math.sqrt(v1 if abs(d1) > abs(d2) else v2)
elif v1 > 0:
f1 = math.sqrt(v1)
# f0
f0 = None
# Denominators
d1 = h[0] * h[3] + h[1] * h[4]
d2 = (h[0] - h[3]) * (h[0] + h[3]) + (h[1] - h[4]) * (h[1] + h[4])
# Focal squares value candidates
v1 = -h[2] * h[5]
v1 = v1 / d1 if d1 != 0.0 else -1.0
v2 = (h[5] - h[2]) * (h[5] + h[2])
v2 = v2 / d2 if d2 != 0.0 else -1.0
if v1 < v2:
v1, v2 = v2, v1
if v1 > 0 and v2 > 0:
f0 = math.sqrt(v1 if abs(d1) > abs(d2) else v2)
elif v1 > 0:
f0 = math.sqrt(v1)
return f0, f1

这是可行的,但这不是我想要的解决方案。我希望有人能做得更好。

最新更新