上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
以前、書いた投稿でSURFで二枚の画像での対応付けを行いました。

PythonからOpenCVのSURFを使う | 詠み人知らずの備忘録



SURFで抽出した対応する座標を用いれば、画像同士を合成することができます。
以下に参考にしたサイトです。


2枚の画像のモザイキング | Miyabiarts.net
前に紹介した「OpenCVを用いた特徴点対応付け」を応用することで複数の画像をモザイキングすることができます。 今回は、OpenCVを用いて下に示す2枚の画像をモザイキングして、1枚の大きな画像を作ります。 今回の例では、2枚の画像が大体半分程度重なり合ってないと上手くいかないです。 あと、画像合成の関係上、1枚目の画像に対して2枚目の画像が左側になるように撮影しないと正しい結果が得られませんので気をつけてください。



Panorama – Image Stitching in OpenCV | ramsrigoutham
he code snippet shown below is for simple image stitching of two images in OpenCV . It can easily be modified to stitch multiple images together and create a Panorama. OpenCV also has a stitching module which helps in achieving this task and which is more robust than this. The code presented here will help in understanding the major steps involved in image stitching algorithm. I am using OpenCV 2.4.3 and Visual studio 2010. This code is based on the openCV tutorial available here.



SURFを実行しても、surf結果画像のように完璧に対応点を抽出できません。 いくつか、誤検出が発生してしまいます。


surf結果画像
surf.png


そのため、誤検出を取り除く処理が必要になります。
RANSACが有名な方法のようです。

画像を合成する際に移動および回転などをさせるために射影変換を行いますが、OpenCVのfindhomographyでは、CV_RANSACを第3引数にすることにより、対応点をRANSACでふるいにかけてくれるようです。

ソース

途中まではSURFを求めるまでは前回までと同じソースを使用しています。
その座標を用いてHomography行列を求め合成しています。

# -*- coding: shift_jis -*-
# matching features of two images
import cv2
import sys
import scipy as sp
import numpy

if len(sys.argv) < 3:
    print 'usage: %s img1 img2' % sys.argv[0]
    sys.exit(1)

img1_path = sys.argv[1]
img2_path = sys.argv[2]

img1 = cv2.imread(img1_path, cv2.CV_LOAD_IMAGE_GRAYSCALE)
img2 = cv2.imread(img2_path, cv2.CV_LOAD_IMAGE_GRAYSCALE)

detector = cv2.FeatureDetector_create("SURF")
descriptor = cv2.DescriptorExtractor_create("BRIEF")
matcher = cv2.DescriptorMatcher_create("BruteForce-Hamming")

# detect keypoints
kp1 = detector.detect(img1)
kp2 = detector.detect(img2)

print '#keypoints in image1: %d, image2: %d' % (len(kp1), len(kp2))

# descriptors
k1, d1 = descriptor.compute(img1, kp1)
k2, d2 = descriptor.compute(img2, kp2)

print '#keypoints in image1: %d, image2: %d' % (len(d1), len(d2))

# match the keypoints
matches = matcher.match(d1, d2)

# visualize the matches
print '#matches:', len(matches)
dist = [m.distance for m in matches]

print 'distance: min: %.3f' % min(dist)
print 'distance: mean: %.3f' % (sum(dist) / len(dist))
print 'distance: max: %.3f' % max(dist)

# threshold: half the mean
thres_dist = (sum(dist) / len(dist)) * 0.9

# keep only the reasonable matches
sel_matches = [m for m in matches if m.distance < thres_dist]

print '#selected matches:', len(sel_matches)

point1 = [[k1[m.queryIdx].pt[0], k1[m.queryIdx].pt[1]] for m in sel_matches]
point2 = [[k2[m.trainIdx].pt[0], k2[m.trainIdx].pt[1]] for m in sel_matches]

point1 = numpy.array(point1)
point2 = numpy.array(point2)

H, Hstatus = cv2.findHomography(point2,point1,cv2.RANSAC)

# 移動量を算出
x=0
y=0
cnt=0
for i,v in enumerate(Hstatus):
    if v==1:
        x += point1[i][0]-point2[i][0]
        y += point1[i][1]-point2[i][1]
        cnt += 1

# カラー画像として改めて読み込む
img1 = cv2.imread(img1_path)
img2 = cv2.imread(img2_path)

x = abs(int(round(x/cnt)))
y = abs(int(round(y/cnt)))

# sizeを取得
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]

dst = cv2.warpPerspective(img2,H,(w2+x,h2+y))

for i in xrange(w1):
    for j in xrange(h1):
        dst[j,i] = img1[j,i]

cv2.imshow("result", dst)
cv2.waitKey()



結果

入力画像
wall1.jpg


wall2.jpg


2枚目画像のHomography行列と演算結果
homography1.png


結果画像
homography2.png


2枚目画像のHomography行列と演算結果を見て分かるかもしれませんが、気づいたことを何点か・・・

このプログラムでは、1枚目の画像に合わせるように2枚目の画像を射影変換して合わせているため、 画像の左右の対応関係が逆だったりすると合成がうまくいかなかったり。
1枚目の画像より上部にある2枚目の画像が反映されていなかったりとあります。
#それは、理論というよりもプログラム上の問題かもしれませんが

ただ、複数枚つなげていくと誤差が積み重なっていきそうではあります。



関連記事
スポンサーサイト
コメント
コメントの投稿
Contributor
Comment
トラックバック URL
URL
このエントリーの固定リンク
トラックバック
FC2カウンター
プロフィール

Author:詠み人知らず
プログラム好きな名もなき凡人がお送りしています。(得意とは言っていない
最近の興味はPython、C#、Matlab(Octave)、画像処理、AR(拡張現実)、統計などなど・・・

気分で思いついたことを書くため話題に一貫性がないかもしれません。

カレンダー
08 | 2017/03 | 09
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -
最新記事
タグクラウドとサーチ

カテゴリ
最新コメント
最新トラックバック
月別アーカイブ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。