[解決済み] OpenCVのリマップ機能はどのように使うのですか?
質問
remap()の最も単純なテストケースは次のとおりです。
import cv2
import numpy as np
inimg = np.arange(2*2).reshape(2,2).astype(np.float32)
inmap = np.array([[0,0],[0,1],[1,0],[1,1]]).astype(np.float32)
outmap = np.array([[10,10],[10,20],[20,10],[20,20]]).astype(np.float32)
outimg = cv2.remap(inimg,inmap,outmap,cv2.INTER_LINEAR)
print "inimg:",inimg
print "inmap:",inmap
print "outmap:",outmap
print "outimg:", outimg
で、これがその出力です。
inimg: [[ 0. 1.]
[ 2. 3.]]
inmap: [[ 0. 0.]
[ 0. 1.]
[ 1. 0.]
[ 1. 1.]]
outmap: [[ 10. 10.]
[ 10. 20.]
[ 20. 10.]
[ 20. 20.]]
outimg: [[ 0. 0.]
[ 0. 0.]
[ 0. 0.]
[ 0. 0.]]
ご覧の通り、outimgは0,0を出力し、正しい形にもなっていません。 私は、0から3の範囲で補間された20x20または10x10の画像を期待しています。
ドキュメントをすべて読みました。そして、remap() は img のすべての値を新しい位置に配置し、空いたスペースは補間するとあります。 私はそれをやっているのですが、うまくいきません。 なぜでしょうか? ほとんどの例はC++のためのものです。 Pythonでは壊れているのでしょうか?
どのように解決するのですか?
これは単純にドキュメントを誤解しているだけで、あなたを責めるつもりはありません---私も理解するのに何度か失敗しました。ドキュメントは明確ですが、この関数はおそらくあなたが期待するような働きはしません。 反対 最初に予想した方向と違う。
何
remap()
はありません。
は、ソース画像の座標を取得し、ポイントを変換し、そして補間します。何
remap()
が行います。
は,出力画像の各画素について,以下のようなルックアップを行います.
どこから来たか
を元画像に挿入し、補間した値を割り当てる。補間するためには、各ピクセルで元画像の周辺の値を見る必要があるので、このように動作させる必要があります。拡大します(少し繰り返すかもしれませんが、誤解のないようにお願いします)。
からの
remap()
ドキュメント
:
マップ1 - のどちらかの最初のマップは
(x,y)
点または単にx
という型を持つ値です。CV_16SC2
,CV_32FC1
またはCV_32FC2
. 参照convertMaps()
は、浮動小数点表現を固定小数点に変換して高速化する方法の詳細について説明します。マップ2 - の2番目のマップは
y
という型を持つ値です。CV_16UC1
,CV_32FC1
またはなし(空のマップの場合map1
は(x,y)
ポイント)にそれぞれ対応しています。
に関するこちらの文言は
map1
を使用しています。
第一
の地図..." は、混乱することがあります。これらは、あなたの画像がマッピングされる場所の座標であることを忘れないでください。
から
...点がマッピングされている
から
src
で
map_x(x, y), map_y(x, y)
に配置し、さらに
dst
で
x, y
. そして、それらはワープさせたい画像と同じ形であるべきです。
へ
. ドキュメントに示されている式に注意してください。
dst(x,y) = src(map_x(x,y),map_y(x,y))
ここで
map_x(x, y)
は上を見ている
map_x
で与えられる行と列で
x, y
. そして、その画素で画像値が評価される。のマッピングされた座標を調べているのです。
x, y
で
src
に代入し、その値を
x, y
で
dst
. これをじっと見ていると、何となく分かってくる。ピクセルで
(0, 0)
を見ると、新しい目的地の画像では
map_x
と
map_y
で補間された値を指定します.
(0, 0)
に近い値を見ることで、デスティネーションイメージの これは、ある種の基本的な理由です。
remap()
はこのように動作します。
あるピクセルがどこから来たのか
を使用して、隣接するピクセルを取得し、補間します。
小さな、工夫された例
img = np.uint8(np.random.rand(8, 8)*255)
#array([[230, 45, 153, 233, 172, 153, 46, 29],
# [172, 209, 186, 30, 197, 30, 251, 200],
# [175, 253, 207, 71, 252, 60, 155, 124],
# [114, 154, 121, 153, 159, 224, 146, 61],
# [ 6, 251, 253, 123, 200, 230, 36, 85],
# [ 10, 215, 38, 5, 119, 87, 8, 249],
# [ 2, 2, 242, 119, 114, 98, 182, 219],
# [168, 91, 224, 73, 159, 55, 254, 214]], dtype=uint8)
map_y = np.array([[0, 1], [2, 3]], dtype=np.float32)
map_x = np.array([[5, 6], [7, 10]], dtype=np.float32)
mapped_img = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR)
#array([[153, 251],
# [124, 0]], dtype=uint8)
では、ここで何が起こっているのか?この場合、行列を調べるのが一番簡単です。
map_y
=====
0 1
2 3
map_x
=====
5 6
7 10
つまり、(0, 0)にある出力画像は、(1, 2)にある入力画像と同じ値を持つことになります。
map_y(0, 0), map_x(0, 0) = 0, 5
であり、0行5列の元画像は153である。なお、デスティネーションイメージでは
mapped_img[0, 0] = 153
. 地図座標が正確な整数であるため、ここでは補間は行われない。また、境界外インデックス (
map_x[1, 1] = 10
これは画像の幅よりも大きな値です)。
0
というのは、アウトオブバウンドのときです。
完全なユースケース例
以下は、グランドトゥルースのホモグラフィーを使用し、ピクセル位置を手動でワープさせながら、本格的なコード例です。
remap()
で、変換された点から画像を写す。ここで、私のホモグラフィーの変換は
true_dst
から
src
. このように、好きな数の点の集合を作り、ホモグラフィーを使って変換することで、その点が元画像のどこに位置するかを計算するのです。すると
remap()
を使い、元画像からそれらの点を探し出し、目的画像にマッピングする。
import numpy as np
import cv2
# read images
true_dst = cv2.imread("img1.png")
src = cv2.imread("img2.png")
# ground truth homography from true_dst to src
H = np.array([
[8.7976964e-01, 3.1245438e-01, -3.9430589e+01],
[-1.8389418e-01, 9.3847198e-01, 1.5315784e+02],
[1.9641425e-04, -1.6015275e-05, 1.0000000e+00]])
# create indices of the destination image and linearize them
h, w = true_dst.shape[:2]
indy, indx = np.indices((h, w), dtype=np.float32)
lin_homg_ind = np.array([indx.ravel(), indy.ravel(), np.ones_like(indx).ravel()])
# warp the coordinates of src to those of true_dst
map_ind = H.dot(lin_homg_ind)
map_x, map_y = map_ind[:-1]/map_ind[-1] # ensure homogeneity
map_x = map_x.reshape(h, w).astype(np.float32)
map_y = map_y.reshape(h, w).astype(np.float32)
# remap!
dst = cv2.remap(src, map_x, map_y, cv2.INTER_LINEAR)
blended = cv2.addWeighted(true_dst, 0.5, dst, 0.5, 0)
cv2.imshow('blended.png', blended)
cv2.waitKey()
の画像とグランドトゥルースホモグラフィ。 オックスフォード大学 視覚幾何学研究室 .
関連
-
[解決済み】RuntimeWarning: 割り算で無効な値が発生しました。
-
[解決済み】ValueError: xとyは同じサイズでなければならない
-
[解決済み] 関数デコレータを作成し、それらを連鎖させるには?
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] 関数内でグローバル変数を使用する
-
[解決済み] 辞書を値で並べ替えるにはどうしたらいいですか?
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
python call matlab メソッドの詳細
-
Python機械学習Githubが8.9Kstarsに達したモデルインタープリタLIME
-
python implement mysql add delete check change サンプルコード
-
Pythonショートビデオクローラーチュートリアル
-
Python LeNetネットワークの説明とpytorchでの実装
-
[解決済み] [Solved] sklearn error ValueError: 入力に NaN、infinity または dtype('float64') に対して大きすぎる値が含まれている。
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み】なぜ「LinAlgError: Grangercausalitytestsから「Singular matrix」と表示されるのはなぜですか?
-
[解決済み】Python elifの構文が無効です【終了しました