ニースキャッチ。私の意見では、np.interp
のように、0.1
と0.9
という値が与えられています。
レッツ・プロットピラミッド(49:51正方画素範囲に補間):
import numpy as np
import cv2
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
prvs = np.zeros((100,80), dtype=np.float32)
prvs[50:51, 50:51] = 1
lin = np.linspace(49,51,200)
grid_x,grid_y = np.meshgrid(lin,lin)
grid_x = grid_x.astype(np.float32)
grid_y = grid_y.astype(np.float32)
prvs_zoommapped = cv2.remap(prvs, grid_x, grid_y, interpolation=cv2.INTER_LINEAR)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_surface(grid_x,grid_y,prvs_zoommapped,cmap='viridis')
plt.show()
お知らせ何でもオフ? 200x200のプロットグリッドでは、ピラミッド上に非常に目に見えるステップがあります。私たちの結果の断面を見てみましょう:
fig,ax = plt.subplots()
ax.plot(prvs_zoommapped[100,:],'x-')
ax.grid('on')
plt.show()
あなたが見ることができるように、結果は区分的定数関数である、すなわち、出力の大きな離散化誤差があります。正確には、結果に0.03125 == 1/32
という手順があります。
疑問に思うのは、cv2.remap
はサブピクセルの操作ではなく、あるグリッドから別のグリッドへの大規模なマッピングに使用することです。もう1つの選択肢は、性能向上のために内部精度が犠牲にされていることです。いずれにせよ、あなたは狂っていません。正確な(双)線形補間の結果として、0.1
と0.9
が表示されるはずです。
他のタスクのためにopenCVにコミットしていない場合は、このマッピング、つまりscipy.interpolate
のさまざまなビット、つまりits parts made for 2d interpolationのさまざまなビットを使用してこのマッピングを実行できます。通常のグリッド上の特殊な線形補間の場合は、scipy.interpolate.RegularGridInterpolator
などが適切です。
あるいはさらに良い(しかし、私はまだこのサブモジュールを使用していない):あなたが探している正確に何のようscipy.ndimage.map_coordinates
は思える:
ピラミッドの例に適用
from scipy import ndimage
ndimage.map_coordinates(prvs, [[50.1, 49.1], [50, 50]], order=1)
# output: array([ 0.89999998, 0.1 ], dtype=float32)
:
import numpy as np
import cv2
from scipy import ndimage
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
prvs = np.zeros((100,80), dtype=np.float32)
prvs[50:51, 50:51] = 1
lin = np.linspace(49,51,200)
grid_x,grid_y = np.meshgrid(lin,lin)
prvs_zoommapped = ndimage.map_coordinates(prvs, [grid_x, grid_y], order=1)
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.plot_surface(grid_x,grid_y,prvs_zoommapped,cmap='viridis')
plt.show()
さらに優れています。
ありがとうございました。 ndimage.map_coordinatesは期待通りに動作します。 既に述べたように、補間エラーはパフォーマンスの最適化と関係があるようです。http://answers.opencv.org/question/123197/how-to-increase-warpperspective-or-warpaffine-precision/ –
@JulianSも参照してください。私はそれがうれしいですし、リンクのおかげで、右のようです。 –
ちょっとフォローアップ:私はOpenCVを再コンパイルし、imgproc.hppのINTER_BITSを5から10に変更しました(上記のリンクに示唆されているように)。今、エラーは0.00391に下がります。エラーは1/2^Nで、Nは整数です。ただし、INTER_BITS = 5の場合は1/2^4、INTER_BITS = 10の場合は1/2^8です。だからちょうど1/2 ^(INTER_BITS - 1)ではありません。しかし、ちょうど誰かがOpenCVの精度を少し上げたいと思って、別のライブラリに変更できない場合、私はそれが役に立つかもしれないと思った。 –