LoginSignup
11
13

More than 5 years have passed since last update.

opencv3でパノラマ画像を作成する

Last updated at Posted at 2017-09-30

はじめに

去年の12月に大学のアドベントカレンダーにパノラマ画像を作成する方法を書きました。
当時はOpenCV2系で開発していましたが、OpenCV3でも取り組んでみようと思いやってみました。
前回はSURFとホモグラフィを組み合わせて行いましたが、今回はstitchingにて取り組んでみました。

開発環境

  • MacBook Pro(Retina, 13-inch, Early 2015)
  • macOS Sierra
  • Xcode9.0
  • OpenCV3.3

方法

OpenCVにはStitcherクラスが用意されており、これを用いいることで簡易に複数枚の画像からパノラマ画像を合成することが出来ます。
しかしながら、処理時間は少しかかってしまうところが難点ですね。

  1. 原画像の読み込み
  2. 複数の画像からなる配列を作成
  3. Stitcherクラスのインスタントstatusを作成
  4. status.stitch()関数にて、画像配列から合成画像を作成

今回は、以下の3枚の画像を合成し、一枚の画像を出力したいと思います。

A B C
1.png 2.png 3.png

接写気味で撮影したBRAVIAのリモコンです。
業務で高さ9cmほどに設置したカメラから3枚画像を撮影し、合成する必要があるためこのケースに近いかたちで写真を撮影しました。
(画像の解像度は450×600です。)

panorama.cpp
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/stitching.hpp"
#include <iostream>

int main(int argc, const char * argv[]) {

    // load image
    cv::UMat Source1;
    cv::imread("A.png", CV_LOAD_IMAGE_COLOR).copyTo(Source1);

    // load image check
    if (Source1.empty()) {
        std::cout << "Failed to open Source image1" << std::endl;
    }

    // load image
    cv::UMat Source2;
    cv::imread("B.png", CV_LOAD_IMAGE_COLOR).copyTo(Source2);

    // load image check
    if (Source2.empty()) {
        std::cout << "Failed to open Source image2" << std::endl;
    }

    // load image
    cv::UMat Source3;
    cv::imread("C.png", CV_LOAD_IMAGE_COLOR).copyTo(Source3);

    // load image check
    if (Source3.empty()) {
        std::cout << "Failed to open Source image2" << std::endl;
    }

    // Create image array
    std::vector<cv::UMat> Sources;
    Sources.push_back(Source1);
    Sources.push_back(Source2);
    Sources.push_back(Source3);

    // Create Panorama image
    cv::Stitcher stitcher = cv::Stitcher::createDefault();
    // output image
    cv::UMat destination;
    // image synthesis
    cv::Stitcher::Status status = stitcher.stitch(Sources, destination);
    if (status != cv::Stitcher::OK) {
        std::cout << "failed to stitch images" << std::endl;
    }
    // Export image
    cv::imwrite("output.png", destination);
}

UMatにて処理を行いましたが、Matでも行えます。

結果

以下が出力画像になります。
destination.png
概ね綺麗に画像合成出来ているかと思います。
画像が両端に行くに連れ歪んでいることは、撮影対象物とカメラとの距離が変わってしまっているからだと思います。
実行時間は、3.718秒でした。この程度であれば、自分の用途としては許容範囲内かと思っています。
Stitcherクラスを用いて、比較的簡単に画像合成ができることがわかりました。
次回はAKAZE等を用いて画像合成を行ってみたいと思います。

参考文献

High level stitching API (Stitcher class)

11
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
13