あいぽんプログラマー

Iphoneを持っていますが、主にAndroid開発についての記事を書いています

Opencvを使ってパノラマ写真を作る

Opencvを使ってパノラマ写真を作る

最近画像処理について勉強していて、パノラマ写真ってどうやっているんだろうと思ったので実際にやってみました。

パノラマ写真の作り方

  1. デジカメやスマフォで画像を複数枚撮る。その際に、あまり動かさないで撮る
  2. 撮った画像それぞれの特徴点と特徴量を抽出する
  3. 異なる2枚の特徴点と特徴量を比較し、2枚の画像間のホモグラフィ行列を求める
  4. 求めたホモグラフィ行列を使って2枚の画像を合成する。

実際にやってみる

  • 材料作り
    今回は以下の2枚の写真です。

f:id:goya813:20141130153857j:plain

f:id:goya813:20141130153901j:plain

  • 特徴点、特徴量の抽出
    今回はOpencvに実装されているSift特徴量を使用します。

  • 画像のマッチング
    さきほど抽出した2枚の画像の特徴点と特徴量をマッチングを行いホモグラフィ行列を求めます。マッチングを行った結果が下のようになっています。

f:id:goya813:20141130173409p:plain

  • 画像の合成
    求めたホモグラフィを使って2枚の画像を合成します。合成した結果が下のようになっています。

f:id:goya813:20141130173412p:plain

ソースコード

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/legacy/legacy.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/nonfree/nonfree.hpp>
#include <cv.h>
#include <vector>

int main(int argc, char* argv[])
{
    using cv::imread;
    using cv::Mat;
    using std::vector;
    using cv::imshow;
    using cv::waitKey;
    using cv::Size;
    using cv::Vec3b;

    Mat src[2];
    Mat gray[2];
    Mat result;

    src[0] = imread("2.JPG");
    src[1] = imread("1.JPG");
    cv::cvtColor(src[0], gray[0], CV_BGR2GRAY);
    cv::cvtColor(src[1], gray[1], CV_BGR2GRAY);

    cv::SiftFeatureDetector detector(1000);
    cv::SiftDescriptorExtractor extrator;

    vector<cv::KeyPoint> keypoints[2];
    Mat descriptors[2];
    for (int i = 0; i < 2; i++){
        detector.detect(gray[i], keypoints[i]);
        extrator.compute(gray[i], keypoints[i], descriptors[i]);
    }

    vector<cv::DMatch> matches;
    cv::BruteForceMatcher< cv::L2<float> > matcher;
    matcher.match(descriptors[0], descriptors[1], matches);

    vector<cv::Vec2f> points1(matches.size());
    vector<cv::Vec2f> points2(matches.size());

    for( size_t i = 0 ; i < matches.size() ; ++i )
    {
        points1[i][0] = keypoints[0][matches[i].queryIdx].pt.x;
        points1[i][1] = keypoints[0][matches[i].queryIdx].pt.y;

        points2[i][0] = keypoints[1][matches[i].trainIdx].pt.x;
        points2[i][1] = keypoints[1][matches[i].trainIdx].pt.y;
    }
    
    Mat matchedImg;
    drawMatches(src[0], keypoints[0], src[1], keypoints[1], matches, matchedImg);
    imshow("draw img", matchedImg);
    waitKey();

    Mat homo = cv::findHomography(points1, points2, CV_RANSAC);
    cv::warpPerspective(src[0], result, homo, Size(static_cast<int>(src[0].cols * 1.5), static_cast<int>(src[0].rows * 1.1)));
    waitKey();
    for (int y = 0; y < src[0].rows; y++){
        for (int x = 0; x < src[0].cols; x++){
            result.at<Vec3b>(y, x) = src[1].at<Vec3b>(y, x);
        }
    }

    imshow("result img", result);
    waitKey(0);

    return (0);
}

Written with StackEdit.

UbuntuでMoverioの開発を行う

UbuntuでMoverioの開発を行う

こんにちは@goya813です。
最近新しく販売されたMoverio BT-200でのAndroidを開発することになったのでブログを書きました!

UbuntuでMoverioの開発をするためには以下の工程が必要です。
1. Moverioのファームウェアをアップデート
2. USBドライバーの導入

Moverioのファームウェアをアップデート

1. 公式の開発者向けサイトデベロッパー登録を行う
2. 登録が終わったら上記のサイトにログインし、「技術情報」->「開発者用システムソフトウェア適用手順書」の手順書通りに設定を行う。

USBドライバーの導入

  1. Moverio上で「USBデバッグ」を設定する
    • Moverioを起動し、「設定」->「開発者向けオプション」->「USBデバッグ」にチェック
      ※開発者向けオプションがない場合は「タブレット情報」->「ビルド番号」を連打すると表示されるようになります。
  2. 「/etc/udev/rules.d/51-android.rules」のファイルに
SUBSYSTEM=="usb",ATTR{idVendor}=="04B8",MODE="0666",GROUP="plugdev"

と追記する
3. AndroidSDKのフォルダの直下にadd-onsというフォルダがあるので、その中に適当なフォルダを作る

例:SDKフォルダ/add-ons/my_add_ons
  1. 作ったフォルダの中に「manifest.ini」というファイルを作り中身を以下の通りにする。
name=Epson Moverio
vendor=Epson
description=Moverio usb driver
api=17
revision=1
usb-vendor=0x04B8

apiのところはインストール済みAPI Levelを適当に設定します。
5. 4つのコマンドを入力します

sudo addgroup --system androiddev
sudo adduser "username" androiddev

"username"には自身のパソコンのユーザー名を入力します。

adb kill-server
adb start-server

adbにパスを通していない場合は 「SDKフォルダ/platform-tools/」に移動して行う。

ICTの煽りの力関係

初めに

こんにちは、@goya813です。

この記事はICT Advent Calenderの22日目の記事です。

今回はICTといえば煽りということらしいので、僕なりに考えたICTの煽りの力関係について書きたいと思います。 この記事はあくまで僕の考えですので実際に合っているかはわかりません。

4人の紹介

ICTで煽りあっている代表の人は以下
- marin72_com
- higumachan725
- maruuusa83
- orisano
の4人です。
では次からこの4人の煽りの力関係について説明したいと思います。

煽り力ランキング

では初めに僕が考える4人の煽り力ランキングは

  1. @orisano
  2. @higumachan725
  3. @marin72_com
  4. @maruuusa83

となっています。
次に4位から順に何故この順位なのかを説明していきたいと思います。

@maruuusa83

@maruuusa83は基本的にあまり煽らないが、煽るときは徹底的に煽るという
性質を持っているため今回の4人に選ばれた。しかしながら、最近は影を潜めているのか
煽りをあまり見なくなったため、残念ながら4位という結果になった。

@marin72_com

@marin72_comは他の3人とは違い無自覚で煽るという性質がある。もちろん
意識的に煽っている場合もあるが、その場合はあまり破壊力はないが、無自覚で煽るときの
破壊力は1位である@orisanoも肝を冷やすレベルである。

@higumachan725

@higumachan725は煽りの数でいったら断トツで1位である。しかし、その煽りは
数うちゃ当たる作戦の場合が多いため、一発一発の破壊力がとても弱いため、
2位という惜しい結果となった。

@orisano

@orisanoは煽りの数では@higumachan725に負けるが@higumachan725と違い
一発一発的確に煽るという恐ろしい煽り力を持っているため堂々の1位となった。
余談だが、煽りの範囲はTwitterには広がっており、クラスメイトからは秒速のふぁぼ師と呼ばれているという噂もある。

最後に

今回のランキングではこのような順位となってしまったが、
こんなランキングは違う!と思う人は、是非自分のところまで連絡をくれると嬉しいです。

明日は@nikollsonと@natrium11321の2人が書いてくれます。