質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

5362閲覧

python3.xとopencv3を用いた画像のスティッチング処理について

checkJ

総合スコア31

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/12/12 09:12

編集2018/12/12 10:27

#概要
2枚の画像を読み込み、特徴点で対応をとってつなぎ合わせるスティッチング処理のプログラムについて
スティッチングされた一枚の画像の作成はできています。
一枚に合成される前の、ホモグラフィ変換された画像を出力したいのです。
#処理の流れ

1.視差のある画像を2枚読み込む
2.読み込んだ画像の特徴検出(KAZE)
3.検出結果から対応点を探索、画像をホモグラフィ変換
4.変換された画像を合成して一枚の画像として出力

#困っているポイント
上記の3.の段階で、合成する前のホモグラフィ変換された画像を出力したい。

参考させていただいたサイト様
パノラマ画像作ったよ

#コード全文

python

1import cv2 2import numpy as np 3import numpy.linalg as LA 4import os 5import winsound 6import time 7 8 9# 画像読み込み 10img1_path = "test2.jpg" 11img2_path = "test1.jpg" 12img1 = cv2.imread(img1_path) 13img2 = cv2.imread(img2_path) 14 15 16# KAZE特徴検出器 17detector = cv2.AKAZE_create() 18kp1, des1 = detector.detectAndCompute(img1, None) 19kp2, des2 = detector.detectAndCompute(img2, None) 20print(len(kp1)) 21print(len(kp2)) 22 23 24# BFマッチング 25bf = cv2.BFMatcher(cv2.NORM_HAMMING) 26matches = bf.match(des1, des2) 27 28 29# トレーニングおよびクエリ特徴量のインデックスをリスト化 30dist = [m.distance for m in matches] 31thres_dist = (sum(dist) / len(dist)) * 0.9 32sel_matches = [m for m in matches if m.distance < thres_dist] 33point1 = [[kp1[m.queryIdx].pt[0], kp1[m.queryIdx].pt[1]] for m in sel_matches] 34point2 = [[kp2[m.trainIdx].pt[0], kp2[m.trainIdx].pt[1]] for m in sel_matches] 35point1 = np.array(point1) 36point2 = np.array(point2) 37 38 39# ホモグラフィ変換 40H, Hstatus = cv2.findHomography(point1,point2,cv2.RANSAC) 41 42def conv_uv(u, v, H): 43 ud, vd, nm = np.dot(H, np.array([u, v, 1])) 44 ud, vd = ud/nm, vd/nm 45 return ud, vd 46 47def calc_w(u, v, w, h): 48 return min([v, u, h-v, w-u]) 49 50def calc_w_h(w, h, H): 51 52 lt_u, lt_v = conv_uv(0, 0, H) 53 rt_u, rt_v = conv_uv(w, 0, H) 54 lb_u, lb_v = conv_uv(0, h, H) 55 rb_u, rb_v = conv_uv(w, h, H) 56 57 min_v = min([lt_v, rt_v, 0]) 58 max_v = max([lb_v, rb_v, h]) 59 min_u = min([lt_u, rt_u, 0]) 60 max_u = max([lb_u, rb_u, w]) 61 62 is_w = int(round(max_u - min_u)) 63 is_h = int(round(max_v - min_v)) 64 return is_w, is_h, -int(min_v) 65 66i1_h, i1_w = img1.shape[0], img1.shape[1] 67i2_h, i2_w = img2.shape[0], img2.shape[1] 68 69H = np.array(H) 70iH = LA.inv(H) 71 72is_w, is_h, offset = calc_w_h(i2_w, i2_h, iH) 73 74simg = np.zeros((is_h, is_w, 3), np.uint8) 75 76 77for v1 in range(i1_h): 78 for u1 in range(i1_w): 79 simg[v1+offset, u1] = img1[v1, u1] 80 81for v1 in range(-offset, is_h-offset): 82 for u1 in range(is_w): 83 i2_p = 0 84 u2, v2 = conv_uv(u1, v1, H) 85 86 if (u2 > 0 and u2 < i2_w) and (v2 > 0 and v2 < i2_h): 87 u2_, v2_ = float(int(u2)), float(int(v2)) 88 wu, wv = u2 - u2_, v2 - v2_ 89 p1 = img2[int(v2_), int(u2_)] 90 if int(u2_) > i2_w-2 or int(v2_) > i2_h-2: 91 92 i2_p = p1 93 else: 94 95 p2 = img2[int(v2_), int(u2_)+1] 96 p3 = img2[int(v2_)+1, int(u2_)] 97 p4 = img2[int(v2_)+1, int(u2_)+1] 98 i2_p = (1-wu)*(1-wv)*p1+wu*(1-wv)*p2+(1-wu)*wv*p3+wu*wv*p4 99 100 if simg[v1+offset, u1].all(): 101 w1, w2 = float(calc_w(v1+offset, u1, i1_w, i1_h)), float(calc_w(v2, u2, i2_w, i2_h)) 102 if (w1 == 0 and w2 == 0) or w1*w2 < 0: 103 pass 104 else: 105 wt1, wt2 = w1/(w1+w2), w2/(w1+w2) 106 p = wt1*simg[v1+offset, u1] + wt2*i2_p 107 simg[v1+offset, u1] = p 108 else: 109 simg[v1+offset, u1] = i2_p 110 111#出力 112cv2.imwrite("stitch_image.jpg", simg) 113 114

おそらく、i2_pに変形後の画像が格納されていると考えているのですが、うまく出力までできていない現状です。
コードもほとんど引用で恐縮ですが、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

以下のサイト様を参考に解決しました。
画像から特徴量を抽出し、透視変換行列を導出して画像を変形する

このプログラムの特徴量検出器をKAZEに変更して、片側のホモグラフィ変換画像を出力することに成功しました。
この質問自体は、明日まで放置します。
もし、他にスマートな方法などあれば、指摘をお願いいたします。

解決済みとして処理します。
皆様ありがとうございました。

投稿2018/12/12 11:54

編集2018/12/13 04:07
checkJ

総合スコア31

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問