Closed1
OpenCV形式のDistortion係数の計算
Distortionの係数をOpenCV形式で保持しておけば、OpenCVの関数が使えるので便利。Distortionが作用する前後の点(理想とズレた点のペア)がわかっているとして、係数を最適化で求められるかやってみる。
DistortionモデルはOpenCVの公式から式をもってくる。
これをPythonに落とすと
@np.vectorize
def dist(x, y, k1, k2, k3, k4, k5, k6, p1, p2, s1, s2, s3, s4):
#x, y = X[0], X[1]
r2 = x**2 + y**2
r4 = r2**2
r6 = r2**3
a = (1 + k1*r2 + k2*r4 + k3*r6) / (1 + k4*r2 + k5*r4 + k6*r6)
xd = x*a + 2*p1*x*y + p2*(r2 + 2*x**2) + s1*r2 + s2*r4
yd = y*a + p1*(r2 + 2*y**2) + 2*p2*x*y + s3*r2 + s4*r4
return xd, yd
たとえばDistortionを以下のように確認できる。
k1 = -0.1
k2 = 0.1
k3 = 0
k4 = 0
k5 = 0
k6 = 0
p1 = 0.1
p2 = 0
s1 = 0.1
s2 = 0
s3 = 0
s4 = 0
p = (k1, k2, k3, k4, k5, k6, p1, p2, s1, s2, s3, s4)
#p = (np.random.rand(12) - 0.5) *2
N = 10
x_org = np.arange(N) / N - 0.5
y_org = np.arange(N) / N - 0.5
xx_org, yy_org = np.meshgrid(x_org, y_org)
xy_org = np.vstack([xx_org.reshape(-1), yy_org.reshape(-1)]).T
x_org, y_org = xy_org[:, 0], xy_org[:, 1]
x_dist, y_dist = dist(x_org, y_org, *p)
plt.plot(x_org, y_org, 'o', label='org')
plt.plot(x_dist, y_dist, 'o', label='dist')
plt.legend()
plt.show()
Scipyの最適化でパラメータがもとまるかやってみる。
def func(p):
x_guess, y_guess = dist(x_org, y_org, *p)
ret = np.sum((x_dist - x_guess)**2 + (y_dist - y_guess)**2)
return ret
p0 = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
p0 = (np.random.rand(12) - 0.5) *2
method = 'L-BFGS-B'
#options = {'eps': 1e-9}
#options = {}
res = scipy.optimize.minimize(func, p0, method=method, options=options)
res
全く同じパラメータは推定できないが、ほぼ出力は同じになるモデルパラメータを推定できている。。パラメータの数を減らしたい場合はSparse推定などを導入すれば良いかも。
fun: 5.286153836953203e-09
hess_inv: <12x12 LbfgsInvHessProduct with dtype=float64>
jac: array([ 4.05240082e-06, 9.90981132e-06, 6.36230800e-06, -3.69913377e-06,
-9.63528415e-06, -6.19922193e-06, -2.64730205e-05, 8.60025398e-07,
8.13040017e-06, 1.65263230e-07, -1.08285397e-06, -1.68766498e-06])
message: 'CONVERGENCE: REL_REDUCTION_OF_F_<=_FACTR*EPSMCH'
nfev: 1066
nit: 71
njev: 82
status: 0
success: True
x: array([-3.51057426e-01, -2.62644048e-01, 1.13673239e-01, -2.49998433e-01,
-3.99343543e-01, 1.40800730e-01, 1.00001584e-01, 2.63529806e-06,
9.99789266e-02, 7.84179501e-05, -2.24927009e-05, 8.65079673e-05])
このスクラップは2022/08/29にクローズされました