スチールウールの活動記録

初心者に向けて(私もだけど)電子工作やプログラミングや関連することをいろいろ。

どこでもcatkin_make && ROS_IPとか自動設定

いつもcatkin_makeをするときに、いちいちワークスペースまで移動するのがめんどう、さらに移動し忘れてていらいらするなどがありました。 さらに、ROS_IPも設定し忘れててなどもよくありました。

なので、今回はどこにいてもcatkin_makeができて、読み込んだ時に現在のIPアドレスをROS_IPに設定できるようにしたいと思います。

どこでもcatkin_make

これは関数、aliasを設定することでできるようにします。

catkin_makeをしたときにワークスペースに移動し、catkin_makeが終了したときにコマンドを実行したディレクトリに戻ります(戻ってきているというわけではありませんが…)。オプションをつけても大丈夫です。さらに、develフォルダにあるsetupスクリプトも一緒に読めるようにします。

bashであれば、関数を定義します。

function catkin_make(){(cd ~/catkin_ws && command catkin_make $@) && source ~/catkin_ws/devel/setup.bash;}

zshではaliasに無名関数が使えるようなので、aliasを設定します。

alias catkin_make='(){(cd ~/catkin_ws && \catkin_make $@) && source ~/catkin_ws/devel/setup.zsh}'

これで楽になりますね。

ROS_IP設定

よくROS_IPの設定を忘れてします人にはとても役立つと思います。 有線接続してあれば有線のIPを、無線接続なら無線のIPを、接続がなければlocalhostをROS_IPにします。

私の師がシェル芸の家元なので、簡単なシェル芸を使って設定します。

export MY_WLAN0IP=`ifconfig wlan0 | grep -o -E "([0-9]+\.){3}[0-9]+" | head -n1`
export MY_ETH0IP=`ifconfig eth0 | grep -o -E "([0-9]+\.){3}[0-9]+" | head -n1`
export ROS_MASTER_URI=http://$(echo $MY_ETH0IP $MY_WLAN0IP localhost|cut -d' ' -f1):11311
export ROS_IP=$(echo $MY_ETH0IP $MY_WLAN0IP localhost|cut -d' ' -f1)

これで ROS_IPとROS_MASTER_URIが現在のIPで設定されます。 .bashrcなどに書いておけば読み込む度に設定されるので便利です。

結論

これでいらいらが多少は改善されると思います。よいROSライフを!!!

その他

catkin_makeのオプションで"--pkg PACKAGE_NAME"で特定のパッケージだけmakeできるんですね

IDEとROSの連携

今回は、私が使っているIDEでROSのプログラムを書くやり方を紹介します。

私の環境 * Ubuntu LTS 14.04 * ROS Indigo

Qt Creator

まず、Qt CreatorでROSのC++のプログラムを書くやり方です。 以下のサイトを参考にさせていただきました。

qiita.com

まず、Qt Creatorをインストールします。私はバージョン3.6.1を使っています。

私の場合、Qt Creatorを起動するときはターミナルから起動しないとcatkin_makeができませんでした(これのせいでだいぶ悩んだ…)

あとは参考サイトにあるように、プロジェクトを開く→CMakeLists.txtを開く→ビルドディレクトリをすべてcatkin_ws/buildにする→引数を../src -DCMAKE_INSTALL_PREFIX=../install -DCATKIN_DEVEL_PREFIX=../devel -DCMAKE_BUILD_TYPE=Debugにして、CMakeを実行する。

上記の手順で、Qt CreatorでROSのプログラムが書けると思います。補完がしっかりと効いて便利ですね。

PyCharm

次に、PyCharmでROSのPythonのプログラムを書くやり方です。 私はPyCharm Community Editionを使っています。 以下を参考にしました。 IDEs - ROS Wiki

まず、PyCharmを公式サイトからダウンロードします。ダウンロードしたファイルを解凍したら、binフォルダにあるpycharm.shを起動します。おそらく起動初回時にいろいろでるので、そのままAcceptとかOkを押していきます。

すると、PyCharmが起動できるようになっています(再起動が必要かも)。

私の環境では、~/.local/share/applications/の中にjetbrains-pycharm-ce.desktopというファイルがあります。 このファイルを開き、Execの部分を、Exec="pycharm.shのパス" %fExec=bash -i -c "pycharm.shのパス" %fにします。

私はzshを使っているので、Exec=zsh -i -c "pycharm.shのパス" %fにしました。

これでPyCharmでimport rospyとやってもエラーが出ないと思います。

結論

プログラム書くの楽になった。

ぶっちゃけ、慣れたらVimで書けばいいと思います。

多項式曲線フィッティング

黄色い本として有名な パターン認識機械学習(通称:PRML) を勉強しているので、できたらとりあえずブログにメモしていきたいと思います。細かくかかないと僕はわすれてしまうので無駄に書いていきたいと思います。

多項式曲線

1.1の例としてでてくる多項式曲線フィッティングをやったので書いておきます。
これは一般的には最小二乗法と呼ばれるものです。
N個の観測値 {x} からそれぞれに対応する {t} をもとに {w} のパラメータを求めて、できるだけデータ集合に当てはまる曲線を作ろうという話です。
まず以下の多項式を使ってデータのフィッティングを行います。

$$ y(x,\mathbf{w})=w_0+w_1x+w_2x^{2}+...+w_Mx^{M} = \sum_{j=0}^{M}w_jx^{j} $$

{M}多項式の次数で、係数 {w_0,...,w_M} をまとめて {\mathbf{w}} というベクトルとします。

{\mathbf{w}} は、関数 {y(x,\mathbf{w})}と訓練データの誤差関数を最小化すれば求められます。

\begin{equation} E(\mathbf{w})=\frac{1}{2}\sum_{n=1}^N{y(x_n,\mathbf{w})-t_n}^2 \end{equation}

これを最小化するには {\mathbf{w}} をそれぞれ偏微分して、0にすればできます。

例えば、M=3の場合、 {\mathbf{w}}は {{w_0,w_1,w_2,w_3}}の集合になります。
そして、(1)の式は

$$ y(x,\mathbf{w})=w_0+w_1x+w_2x^{2}+w_3x^{3} $$

になり,(2)の式を展開すると、

$$ \frac{1}{2}\sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n}^{2} $$ となります。

これを {\mathbf{w}} のそれぞれで偏微分します。

\begin{align} \frac{\partial}{\partial w_0}\left(\frac{1}{2}\sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n}^{2}\right) \\ = \sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n} \\ \frac{\partial}{\partial w_1}\left(\frac{1}{2}\sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n}^{2}\right) \\ =\sum_{n=1}^{N}x_n{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n} \\ \frac{\partial}{\partial w_2}\left(\frac{1}{2}\sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n}^{2}\right) \\ =\sum_{n=1}^{N}x_n^{2}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n} \\ \frac{\partial}{\partial w_3}\left(\frac{1}{2}\sum_{n=1}^{N}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n}^{2}\right) \\ =\sum_{n=1}^{N}x_n^{3}{(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})-t_n} \\ \end{align}

式を変形すると、

\begin{align} \sum_{n=1}^{N}(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3}) &= \sum_{n=1}^{N}t_n \\ \sum_{n=1}^{N}x_n(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})&=\sum_{n=1}^{N}{x_nt_n} \\ \sum_{n=1}^{N}x_n^{2}(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})&=\sum_{n=1}^{N}{x_n^{2}t_n} \\ \sum_{n=1}^{N}x_n^{3}(w_0+w_1x_n+w_2x_n^{2}+w_3x_n^{3})&=\sum_{n=1}^{N}{x_n^{3}t_n} \\ \end{align}

となります。

さらにまとめると、

\begin{align} \sum_{j=0}^M\left(\left(\sum_{n=1}^Nx_n^j\right) w_j\right)&=\sum_{n=1}^N{t_n} \\ \sum_{j=0}^M\left(\left(\sum_{n=1}^Nx_nx_n^j\right) w_j\right)&=\sum_{n=1}^N{x_nt_n} \\ \sum_{j=0}^M\left(\left(\sum_{n=1}^Nx_n^2x_n^j\right) w_j\right)&=\sum_{n=1}^N{x_n^2t_n} \\ \sum_{j=0}^M\left(\left(\sum_{n=1}^Nx_n^3x_n^j\right) w_j\right)&=\sum_{n=1}^N{x_n^3t_n} \\ \end{align}

ここで

\begin{align} A_i &= \sum_{n=1}^N x_n^{(i+j)} \\ T_i &= \sum_{n=1}^N x_n^it_n \end{align}

とすると、{w_i}において

\begin{align} \sum_{j=0}^MA_{ij}w_j &= T_i \end{align}

となります。

M=3のとき

\begin{align} \sum_{j=0}^MA_{0j}w_j &= T_0 \\ \sum_{j=0}^MA_{1j}w_j &= T_1 \\ \sum_{j=0}^MA_{2j}w_j &= T_2 \\ \sum_{j=0}^MA_{3j}w_j &= T_3 \\ \end{align}

なので、

\begin{align} A_{00}w_0+A_{01}w_1+A_{02}w_2+A_{03}w_3 &= T_0 \\ A_{10}w_0+A_{11}w_1+A_{12}w_2+A_{13}w_3 &= T_1 \\ A_{20}w_0+A_{21}w_1+A_{22}w_2+A_{23}w_3 &= T_2 \\ A_{30}w_0+A_{31}w_1+A_{32}w_2+A_{33}w_3 &= T_3 \\ \end{align}

行列表現にすると、

\begin{align} \left[ \begin{array}{rrrr} A_{00} & A_{01} & A_{02} & A_{03} \\ A_{10} & A_{11} & A_{12} & A_{13} \\ A_{20} & A_{21} & A_{22} & A_{23} \\ A_{30} & A_{31} & A_{32} & A_{33} \\ \end{array} \right] \left[ \begin{array}{r} w_0 \\ w_1 \\ w_2 \\ w_3 \\ \end{array} \right] &= \left[ \begin{array}{r} T_0 \\ T_1 \\ T_2 \\ T_3 \\ \end{array} \right] \end{align}

となります。wを求めるには、

\begin{align} \left[ \begin{array}{r} w_0 \\ w_1 \\ w_2 \\ w_3 \\ \end{array} \right] &= \left[ \begin{array}{rrrr} A_{00} & A_{01} & A_{02} & A_{03} \\ A_{10} & A_{11} & A_{12} & A_{13} \\ A_{20} & A_{21} & A_{22} & A_{23} \\ A_{30} & A_{31} & A_{32} & A_{33} \\ \end{array} \right]^{-1} \left[ \begin{array}{r} T_0 \\ T_1 \\ T_2 \\ T_3 \\ \end{array} \right] \end{align}

つまり、AとTで方程式を解けば求めることができます。

実装

行列などが簡単に計算できて、グラフも出力できるPythonを使います。

# coding:utf-8
import numpy as np
import matplotlib.pyplot as plt

def calc_y(x, w):
    return np.array([np.sum([w[i] * (x[n] ** i) for i in xrange(w.size)]) for n in xrange(x.size)])

# wを計算
def estimate(x, t, M):
    A = np.array([[(x ** (i + j)).sum() for j in xrange(M + 1)] for i in xrange(M + 1)])
    T = np.array([(x ** (i) * t).sum() for i in xrange(M + 1)])
    return np.linalg.solve(A, T)


if __name__ == '__main__':
    # 多項式の次数
    M = 3
    
    # データ点を10個作る
    x_data = np.linspace(0, 1, 10)
    # 分散0.2のノイズを与える
    t_data = np.sin(2 * np.pi * x_data) + np.random.normal(0, 0.2, x_data.size)

    x_true = np.linspace(0, 1, 500)
    y_true = np.sin(2 * np.pi * x_true)

    w = estimate(x_data, t_data, M)
    y_data = calc_y(x_true, w)

    plt.plot(x_data, t_data, 'o')
    plt.plot(x_true, y_true, 'g')
    plt.plot(x_true, y_data, 'r')

    plt.show()

f:id:bhjkkk:20160207062654p:plain

緑が正しいsin波形、赤がデータ点によってフィッティングしたものです。

うまくフィッティングができていると思います。

罰金項

罰金項を付け加えることで、係数が大きな値になることをある程度防ぐことができるようになります。
罰金項で最も単純な物は、係数を2乗して和をとったもので、誤差関数が

$$ \tilde{E}(\mathbf{w})=\frac{1}{2}\sum_{n=1}^N{y(x_n,\mathbf{w})-t_n}^2+\frac{\lambda}{2}|\mathbf{w}|^2 $$

となります。

{|\mathbf{w}|^2\equiv\mathbf{w}^{\mathbf{T}}\mathbf{w}=w_0^2+w_1^2+...+w_M^2} で、{\lambda}正則化項と二乗誤差の和の項との相対的な重要度の調節をします。
これを加えて{\mathbf{w}}を計算するには、同じように{\tilde{E}(\mathbf{w})}偏微分して0になるようにします。

まず、{\displaystyle \frac{\lambda}{2}|\mathbf{w}|^2}に注目します。
M=3のときを考えると、

\begin{align} \frac{\lambda}{2}(w_0^2+w_1^2+w_2^2+w_3^2) \end{align}

です。これを偏微分すると

\begin{align} \frac{\partial}{\partial w_0}&\left(\frac{\lambda}{2}(w_0^2+w_1^2+w_2^2+w_3^2)\right) \\ &=\lambda w_0 \\ \frac{\partial}{\partial w_1}&\left(\frac{\lambda}{2}(w_0^2+w_1^2+w_2^2+w_3^2)\right) \\ &=\lambda w_1 \\ \frac{\partial}{\partial w_2}&\left(\frac{\lambda}{2}(w_0^2+w_1^2+w_2^2+w_3^2)\right) \\ &=\lambda w_2 \\ \frac{\partial}{\partial w_3}&\left(\frac{\lambda}{2}(w_0^2+w_1^2+w_2^2+w_3^2)\right) \\ &=\lambda w_3 \\ \end{align}

になります。つまり、上記の {A_{ij}}{i=j} のときに罰金項の偏微分の値が足されるので、

$$ A_{ij} = \begin{cases} \displaystyle \lambda+\sum_{n=1}^N x_n^{(i+j)} & (i=j) \\ \displaystyle \sum_{n=1}^N x_n^{(i+j)} & (i!=j) \end{cases} $$

となります。

Pythonのコードに以下の関数を追加します。
PRMLには {\ln{\lambda}=-18} とあるので、{\lambda=\mathrm{e}^{-18}} にします。

# 罰金項ありでwを計算
def estimate_la(x, t, M):
    la = np.exp(-18)
    A = np.array([[(x ** (i + j)).sum() if i != j else la + (x ** (i + j)).sum() for j in xrange(M + 1)] for i in
                  xrange(M + 1)])
    T = np.array([(x ** (i) * t).sum() for i in xrange(M + 1)])
    return np.linalg.solve(A, T)

f:id:bhjkkk:20160207090155p:plain

緑が正しい線、赤がただの二乗誤差関数による線、青が罰金項を付け加えた線です。

M=9でやっていますが、過学習が抑えられていい感じになってますね。

WindowsでOpenCV3.1をCMakeを使ってインストールする

前にOpenCV3.0を、配布されているexeを使ってインストールして使いました。今回はCMakeを使ってインストールし、さらにエクストラモジュールもインストールしてみます。

必要ファイルのダウンロード

OpenCVの公式サイトにある OpenCV for Linux/Mac をダウンロードします。

そして、OpenCVのエクストラモジュールをダウンロードします。

github.com

ここにアクセスし、右上にある Download ZIP をクリックすると、ダウンロードが始まると思います。

今回はCMakeを使うのでインストールしときます。

CMake

ダウンロードしてきたファイルを2つとも解凍します。 CMakeを起動し、Where is source code に解凍したOpenCVのフォルダを指定し、 Where to build the binaries にOpenCVフォルダのパス+/build を指定します。(例:/path/to/opencv-3.1.0/build)

指定したらConfigureを押します。すると、設定項目がたくさん出てきます。

CMAKE_INSTALL_PREFIXを変えると、そこにOpenCVがインストールされます。ここをC:/opencv310に変更します。

OPENCV_EXTRA_MODULES_PATHにさっきダウンロードして解凍したエクストラモジュールの中にあるmodulesフォルダのパスを入れます。

(Pythonがインストールされている人はここでBUILD_opencv_python2にチェックが入っていると、OpenCVをビルドするときにデバッグモードで失敗してしまいます。デバッグモードでOpenCVを使う人は外しておきましょう)

もう一度Configureを押します。すると設定が反映されます。 設定に問題がなければGenerateを押します。

インストール

buildフォルダの中にOpenCV.slnができていると思います。ダブルクリックするとVisual Studioが開きます。

Visual StudioのソリューションエクスプローラにあるCMakeTargetsの中にあるINSTALLを右クリックしてスタートアッププロジェクトに設定をクリックします。 これでデバッグ・リリースモードでビルドすればC:/opencv310にOpenCVがインストールされると思います。

インストールが終わったら環境変数のpathに、c:/opencv310/x64/vc12/binを追加します。

これでOpenCVが使えるようになると思います。

BoostとQt5とOpenCVを組み合わせてCMake

前回、簡単にCMakeの使い方を書きましたが、今回はライブラリを組み合わせたいと思います。

使うライブラリ

使うライブラリはBoost1.57.0、Qt5.4、OpenCV3.1です。Visual Studioで使おうとすると設定はとてもめんどいです。なのでCMakeを使いましょう。
(QThreadを使わないでBoostのThreadを使う理由は、QThreadがよくわからないです…)

今回使うファイル

今回はいくつかファイルがあるのでGitHubを参照してください。

ソース

FIND_PACKAGEでライブラリを見つけ、TARGET_LINK_LIBRARIESで、プログラムにリンクします。 QT5_WRAP_UIでqtのuiファイルをリンク、QT5_ADD_RESOURCESでqtのresourcesファイルをリンクします。 Windowsで使うときはADD_EXECUTABLEにWIN32、TARGET_LINK_LIBRARIESにQt5::WinMainを追加します。

実行すると、ウィンドウが出てきて、カメラから画像が取得できると思います。

CMakeの使い方

メモ程度な感じで簡単な使い方を…
私の環境のCMakeのバージョンは3.2.1です。

CMakeとは

Cmakeというのはクロスプラットフォームで使えるビルド自動化のためのフリーソフトウェアです。
同じプログラムをビルドするとき、WindowsでならVisual Studioでビルド、LinuxなどではMakefileを書いてMakeします。しかし、色んなOSでビルドする場合、Visual Studioの設定をして、Makefileも書かなければなりません。しかも他の人が使う場合、設定が微妙に違う可能性があります(インクルードパス、ライブラリパスなど)。それを自動的に生成してくれるのがCMakeです。

CMakeLists.txt

CMakeLists.txtに書くことによってCMakeの設定を書きます。

とりあえず、簡単に書いてみます。

project---
        |
        |---src
        |     |
        |     |---main.cpp
        |
        |-CMakeLists.txt

このようなディレクトリ構成になってるとします。

下記の通りにmain.cppとCMakeLists.txtを書きます。

main.cpp

#include <iostream>

int main()
{
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(sample)
ADD_EXECUTABLE(${PROJECT_NAME} src/main.cpp)

それではCMakeを起動します。
Windowsではcmakeをダウンロードしたもの。Linuxではcmake-guiをインストールすれば下の画面と同じになると思います。

"Where is the source code"に"projectフォルダのパスを、"Where to build the binaries"にprojectフォルダのパス+/build と入力してください。

そして"Configure"ボタンを押し、エラーがでなければ"Generate"ボタンを押します。
すると、buildフォルダの中に、WindowsならVisual Studioのプロジェクトファイルが、LinuxならMakefileが出来上がってると思います。

ビルドすればプログラムをビルドできるはずです。

ファイルが複数ある場合

上記はファイルが1つでしたが、プログラムを作るときはファイルが複数あると思います。

project---
        |
        |---src
        |     |
        |     |---main.cpp
        |     |
        |     |---test.h
        |     |
        |     |---test.cpp
        |
        |-CMakeLists.txt

main.cpp

#include "test.h"

int main()
{
    Hello();
    return 0;
}

test.h

#pragma once

#include <iostream>

void Hello();

test.cpp

#include "test.h"

void Hello()
{
    std::cout << "Hello, World!" << std::endl;
}

この場合、CMakeLists.txtを以下のようにします。

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

PROJECT(sample)

SET(PROJECT_HERS
  src/test.h
)

SET(PROJECT_SRCS
  src/test.cpp
  src/main.cpp
)

ADD_EXECUTABLE(${PROJECT_NAME}
  ${PROJECT_HERS}
  ${PROJECT_SRCS}
)

こうすることでファイルがリンクされます。
ただし、ADD_EXECUTABLEはプロジェクトにつき一回しかできません。 SETによって、"PROJECT_SRCS"にソースファイルを、"PROJECT_HERS"にヘッダーファイルをセットしています。

CMakeの使いみち

これぐらいのプログラムならCMake使わなくてもいいですが、ライブラリなどを使うときにCMakeはとても便利に使えます。
ライブラリを使うときのやり方はそのうち…

OpenCV3.0を使ってみた

今回はOpenCV3.0をWindowsにインストールして使ってみたので、導入手順でも書きます。

インストール

まず最初に、OpenCVの公式サイトにいってOpenCV3.0をダウンロードします。

OpenCV | OpenCV

解凍して、お好きなディレクトリに移動してください。

Visual Studioで使えるようにする

私の使っている環境がVisual Studio 2013なので、これに合わせて説明します。

OpenCV3.0をWindows用のインストーラだと、staticlibフォルダに基本的にいつも使っているライブラリがあります。

なので、今回はスタティックライブラリを使います。

Visual Studioを開き、プロジェクトのプロパティを開きます。

  • 構成プロパティ→C/C++→全般の追加のインクルードディレクトリにOpenCV3.0のincludeをフォルダを追加
    (ex. C:\opencv\build\include)

  • 構成プロパティ→リンカー→全般の追加のライブラリディレクトリにOpenCV3.0のstaticlibのフォルダを追加
    (ex. C:\opencv\build\x86\vc12\staticlib) ←32bitで使う場合

  • 構成プロパティ→C/C++→コード生成のランタイムライブラリを

    • Debugなら マルチスレッドデバッグ
    • Releaseなら マルチスレッド
      に変更する

ライブラリのリンクのために、ヘッダーを作る。

#include "opencv2\opencv.hpp"

#pragma comment(lib,"comctl32.lib")
#pragma comment(lib,"vfw32.lib")

#define CV_VERSION_STR CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)

#ifdef _DEBUG
#define CV_EXT_STR "d.lib"
#else
#define CV_EXT_STR ".lib"
#endif

#pragma comment(lib,"opencv_calib3d" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_features2d" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_flann" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_core" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_hal"CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_highgui"CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_imgcodecs"CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_imgproc"CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_ml" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_objdetect" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_photo" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_shape" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_stitching" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_superres" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_ts" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_video" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_videoio" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"opencv_videostab" CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib,"IlmImf"CV_EXT_STR)
#pragma comment(lib,"ippicvmt.lib")
#pragma comment(lib,"libjasper"CV_EXT_STR)
#pragma comment(lib,"libjpeg"CV_EXT_STR)
#pragma comment(lib,"libpng"CV_EXT_STR)
#pragma comment(lib,"libtiff"CV_EXT_STR)
#pragma comment(lib,"libwebp"CV_EXT_STR)
#pragma comment(lib,"zlib"CV_EXT_STR)

以下のプログラムが実行できれば完了

#include <opencv2/opencv.hpp>
#include <opencv_lib.hpp>

int main()
{
    cv::Mat img(cv::Size(640, 480), CV_8UC3, cv::Scalar(0, 255, 0));
    cv::imshow("test", img);
    cv::waitKey();

    return 0;
}

ラベリング

OpenCV3.0からラベリングの関数が追加されたそうです。 公式のサンプルのconnected_components.cppを参考に実行してみたいと思います。

#include <opencv2/opencv.hpp>
#include <opencv_lib.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

int main()
{
    //ラベリングをしたい画像を読み込む
    Mat img = imread("labeling_img.jpg");

    //画像の読み込み失敗した場合
    if (img.empty())
    {
        cout << "Could not read input image file" << endl;
        return -1;
    }

    //グレースケール・2値化用
    Mat gray, bin;

    //グレースケールに変換
    cvtColor(img, gray, CV_BGR2GRAY);

    //2値化
    threshold(gray, bin, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    //ラベリング結果用
    Mat labelImage(img.size(), CV_32S);

    //nLabelsはラベリング数、関数の8は8近傍(4なら4近傍)
    int nLabels = connectedComponents(bin, labelImage, 8);

    //ラベリング色分け用
    vector<Vec3b> colors(nLabels);

    //背景は黒にする
    colors[0] = Vec3b(0, 0, 0);

    //ランダムに色を入れていく
    for (int label = 1; label < nLabels; label++)
    {
        colors[label] = Vec3b((rand() & 255), (rand() & 255), (rand() & 255));
    }

    //ラベリング結果用
    Mat dst(img.size(), CV_8UC3);

    //色をつけていく
    for (int r = 0; r < dst.rows; r++)
    {
        for (int c = 0; c < dst.cols; c++)
        {
            int label = labelImage.at<int>(r, c);
            Vec3b &pixel = dst.at<Vec3b>(r, c);
            pixel = colors[label];
        }
    }

    //元画像表示
    imshow("img", img);

    //結果画像表示
    imshow("Connected Components", dst);

    //入力待ち
    waitKey();

    return 0;
}

今回ラベリングする画像

f:id:bhjkkk:20151126215600j:plain

ラベリング結果

f:id:bhjkkk:20151126215846j:plain

簡単にできますね。