バイラテラルフィルタ

ガウシアンフィルタなどのフィルタでは、ノイズをできるだけ除去しようとすると、輪郭もボケてしまうという欠点がありました。
この欠点を解決しようとした処理アルゴリズムがバイラテラルフィルタ(bilateral filter)です。

 

バイラテラルフィルタは処理前の画像データの配列をf(i, j)、処理後の画像データの配列をg(i, j)とすると

 

 

となります。

 

ただし、がカーネルのサイズ、σがガウシアンフィルタを制御、σが輝度差を制御しています。

と言われても、何だか式が難しくて良く分かりません。

 

でも、分母分子に出てくる最初のexpの部分はガウシアンフィルタで見たことがあるな~

という事に気が付けば、突破口が開けます。

 

2つ目のexpの部分が良く分からないので、とりあえず取っちゃってみて、

 

 

とすると、分母の部分がガウシアンフィルタと少し違うけど、Σの範囲が-W~Wなので、(2W+1)×(2W+1)のカーネルサイズのガウシアンフィルタになっています。

 

結局、分母はカーネルの値の合計なので、やっぱりガウシアンフィルタそのものだという事に気が付きます。

 

ここで、ガウシアンフィルタを使って、どうやれば輪郭をぼやかさず、ノイズだけを除去できるか?を考えると、カーネルの中心の輝度値と差の少ないところだけをガウシアンフィルタで平滑化すればいいのではないか?という発想が浮かびます。

 

例えば次のような画像において、

 

四角で囲まれた部分を拡大し注目すると、5x5のガウシアンフィルタの場合、中心の輝度値に近い部分を重み「1」、輝度差が大きい部分は重みが「0」になるようにして、

 

 

一般的な5x5のガウシアンフィルタの係数↓、

 

 

に重みをかけると、それぞれのカーネルの値は

 

カーネルの合計の169で割る カーネルの合計の209で割る

 

となります。

このようにして、場所、場所のカーネルの値を画像に合わせて変えて行くと、輪郭を残しつつノイズだけを除去できそうな感じがします。

 

しかし、輪郭付近の重みは「1」にするべきか?「0」にするべきか?少し悩みます。

そこで、カーネルの中心の輝度値との差に基づいて、重みを「0.3」や「0.8」のようなグレーゾーンを設けるために、輝度差を横軸にした正規分布を用いてみます。

 

正規分布のグラフはこんな感じ↓

 

になっていて、中心の0付近ほど値が大きく、外側(+方向、-方向)へ行くに従って値が小さくなります。

この性質を使ってカーネルの中心の輝度値との差「f(i, j)- f(i + m, j + n) 」を横軸にとった正規分布の式は

 

 

となり、これを重みに使うと、「1」「0」だった重みが、輝度差が小さいと重みが大きく、輝度差が大きいと重みが小さくなるように、なだらかに変化します。

 

この正規分布を重みとしたのが、まさにバイラテラルフィルタなのです。

つまりバイラテラルフィルタは

 

正規分布の重み付きガウシアンフィルタ

 

なのです。

 

ここで、最初に示したバイラテラルフィルタの式を見てみると、

分子は(2W+1)×(2W+1)サイズのカーネルの範囲内の輝度値に、ガウシアンフィルタの係数をかけ、さらにカーネルの中心との輝度差を用いた正規分布の値を掛け合わせた値、

分母はカーネルの合計値で、カーネルの合計値が1になるように調整しています。

 

Wはカーネルの大きさ、σは通常のガウシアンフィルタの係数と同じ。

σの値が、カーネルの中心の輝度値との差をどの程度許容するか?を制御している事が分かります。

そのため、σの値を大きくしていくと、ただのガウシアンフィルタの処理に近づき、輪郭もぼやけてしまいます。逆にσの値を小さくし過ぎると、ノイズ除去効果が弱くなります。

 

そこで、実際にはエッジを保持しつつノイズをできるだけ除去したい場合は、1回のバイラテラルフィルタでσ1、σの値を調整しようとするよりも、バイラテラルフィルタを何回か繰り返した方が効果的です。

 

原画 1回目 2回目
3回目 4回目 5回目

 

このように、バイラテラルフィルタはガウシアンフィルタのカーネルに輝度差に基づいて重みを付けている訳ですが、この、×××に基づいて重みを付ける処理という考え方は、処理を安定させるポイントになったりします。

 

例えばロバスト推定法なんかも近い感じ。

 

画像処理アルゴリズムへ戻る

OpenCV2.3.1の入手、ダウンロード、インストール、環境設定

2012.5現在、OpenCVの最新バージョンはVer2.4です。
こちらのインストール方法についてはOpenCV2.4の入手、ダウンロード、インストール、環境設定を参照願います。


OpenCV2.3.1の入手、ダウンロード先

OpenCVの入手は下記ページよりダウンロードして下さい。

http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.3.1/

 

上記リンク先へ行き、OpenCV-2.3.1-win-superpack.exeをクリックしてファイルをダウンロードして下さい。

 

OpenCV2.3.1のインストール方法

ダウンロードしたファイル(OpenCV-2.3.1-win-superpack.exe)をダブルクリックすると、ファイルの解凍が始まるので、ここでは c:\ に解凍する事にします。(慣れている人はどこでも構いません。)
Extract to:の部分に  c:\ と入力して下さい。

 

 

ファイルを解凍すると、主な構成は下記のようになっています。

c:\opencv
┣ 3rdparty
┣ android
┣ build
┃┣ common
┃┣ gpu
┃┣ include
┃┣ python
┃┣ x64
┃┃ ┣mingw
┃┃ ┣vc9
┃┃ ┗vc10
┃┗ x86
┃  ┣mingw
┃  ┣vc9
┃  ┗vc10
┃   ┣bin
┃   ┣lib
┃   ┗staticlib
┣ data
┣ doc
┣ include
┣ module
┗ samples

 

次にダウンロードしたdllファイルをPCから使えるようにPathの設定というのを行います。

 

Pathの設定はWindowsのスタートボタンをクリック → コンピュータ右クリックプ ロパティをクリックします。

 

 

開いたウィンドウの システムの詳細設定 をク リックします。

 

 

次に詳細設定タブの環境変数のボ タンをクリックします。

 

 

次にシステム環境変数のPathを選択し、編集をクリックします。

 

 

変数値のテキストボックスの最後の部分に、OpenCVのdllファイルのあるフォルダを指定します。

 

;C:\opencv\build\x86\vc10\bin

 

※もともとあった文字は消さないようにご注意ください。
最初の ; (セミコロン)を付けるのもお忘れなく。
PATHの設定後、PCを再起動して下さい。(ログオフ⇒ログインでも可)

 

上記の設定は32bitOSでVisual Studio2010を使う場合の設定です。
使用する環境に合わせてディレクトリを指定して下さい。

 

32bit、Visual Studio2008の場合 C:\opencv\build\x86\vc9\bin
32bit、Visual Studio2010の場合 C:\opencv\build\x86\vc10\bin
64bit、Visual Studio2008の場合 C:\opencv\build\x64\vc9\bin
64bit、Visual Studio2010の場合 C:\opencv\build\x64\vc10\bin

 

64bitOSを使っていても32bitでプログラムする場合は x86 フォルダ内のbinディレクトリを指定して下さい。
64bitを使う場合は、VisualStudioのプラットフォームをx64にして下さい。

 

TBBの入手、ダウンロード

OpenCV2.3.1のバイナリ版(コンパイルされているdll)を使う場合は、TBB(Intel Threading Building Blocks)という並列処理用のライブラリが必要となります。
OpenCVをダウンロードすると \opencv\build\common\tbb のフォルダにTBBのdllが入っているのですが、debug版が不足してます。

 

そのため、TBBのライブラリを入手します。

 

入手先
http://threadingbuildingblocks.org/

上記リンクのページへ行き、上側のメニューのDownloads⇒ページ中央部のStable Releaseと移動し、最新のバージョンのTBBをクリックします。(2012年1月現在、tbb40_20111130oss

 

次にWindows版のDownloadボタンをクリックし、ファイルをダウンロードします。
Windows版の場合、tbb40_20111130oss_win.zip

 

ダウンロードしたファイルを解凍すると下記のようなフォルダ構成になっています。
\tbb40_20111130oss_win\tbb40_20111130oss
┣ bin
┃┣ ia32
┃┃ ┣vc8
┃┃ ┣vc9
┃┃ ┗vc10
┃┗ intel64
┣ doc
┣ examples
┣ include
┗ lib

 

そこで、今回は32bitOSでVisualStudio2010を使う事を想定しているので、
フォルダ(\tbb40_20111130oss_win\tbb40_20111130oss\bin\ia32\vc10)内にあるdllファイル

 

tbb.dll、tbb_debug.dll、tbb_preview.dll、tbb_preview_debug.dll、tbbmalloc.dll、tbbmalloc_debug.dll、tbbmalloc_proxy.dll、tbbmalloc_proxy_debug.dll

 

を全てOpenCVのbinフォルダ(C:\opencv\build\x86\vc10\bin)へコピーして下さい。
32bit/64bit、VisualStudioのバージョンによりフォルダが異なるので、環境に合わせてフォルダを選択して下さい。

 

これで、OpenCVの設定は完了です。

 

VisualStudio2010での使用方法

使用するのはVisualStudio C++ 2010 Express以上のエディションで大丈夫です。

 

VisualStudio2010を起動し、新しいプロジェクトをクリックし、左側のメニューのWin32を選択した状態でWin32コンソールアプリケーションをクリックします。

 

 

適当な名前(上図ではOpenCV2.3.1Sample)を付け、保存する場所を指定し、OKボタンをクリックします。

 

すると下記のようなソースコードが表示されます。

 

// OpenCV2.3.1Sample.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
	return 0;
}

 

次にOpenCVのヘッダファイルが、今回作成したプロジェクトから参照できるように設定を行います。

 

プロジェクトの名前の部分を右クリックし、プロパティを選択します。

 

 

表示されたウィンドウ右上の構成を全ての構成にし、構成のプロパティ⇒C/C++⇒全般を選択して、OpenCV2のフォルダのあるディレクトリ(C:\opencv\build\include)を追加のインクルードディレクトリに指定します。

 

 

以上の設定を行い、ソース部分を下記のようにすると、ガウシアンフィルタ処理を行う簡単なサンプルプログラムが実行できると思います。

 


// OpenCV2.3.1Sample.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//プロジェクトのプロパティ⇒C/C++⇒全般 の追加のインクルードディレクトリに
// opencv2のあるフォルダ『C:\OpenCV\include』などを追加のこと
#include "opencv2\opencv.hpp"

#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_core231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_imgproc231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_highgui231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_objdetect231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_contrib231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_features2d231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_flann231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_gpu231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_haartraining_engined.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_legacy231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_ts231d.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_video231d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_core231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_imgproc231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_highgui231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_objdetect231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_contrib231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_features2d231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_flann231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_gpu231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_haartraining_engined.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_legacy231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_ts231.lib")
    #pragma comment(lib,"C:\\opencv\\build\\x86\\vc10\\lib\\opencv_video231.lib")
#endif

int _tmain(int argc, _TCHAR* argv[])
{

    //画像データの読込
    IplImage* src_img = cvLoadImage("C:\\opencv\\samples\\c\\lena.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
    if (src_img == NULL){
        return 0;
    }

    //表示ウィンドウの作成
    cvNamedWindow("src");
    cvNamedWindow("dst");

    //処理後画像データの確保
    IplImage* dst_img = cvCreateImage(cvGetSize(src_img), src_img->depth, src_img->nChannels);

    //画像処理例(ガウシアンフィルタ)
    cvSmooth(src_img, dst_img, CV_GAUSSIAN, 9);

    //画像の表示
    cvShowImage ("src", src_img);
    cvShowImage ("dst", dst_img);

    //キー入力待ち
    cvWaitKey (0);

    //全てのウィンドウの削除
    cvDestroyAllWindows();

    //画像データの解放
    cvReleaseImage(&src_img);
    cvReleaseImage(&dst_img);

    return 0;
}

 

ちなみに、libファイルは全て必要ではなく、おおむね

 

opencv_core231、opencv_imgproc231、opencv_highgui231、opencv_objdetect231

 

の4種類ぐらいである程度動作すると思います。(使用する関数によって必要なlibファイルが決まります。)

 

また、libファイルのファイル名に含まれる数字部分がOpenCVのバージョンを示し、ファイル名の最後についているdの文字がDebug用のlibファイル、dの無いファイルがRelease用のlibファイルとなっています。

 

その他

OpenCV2.3.1においてもCMakeを使って自分でOpenCVをコンパイルする事が可能です。

 

CMakeのソースコードにはOpenCV-2.3.1-win-superpack.exeを解凍したフォルダ(opencv)を指定して下さい。

 

OpenCV2.3の場合の説明ですが、詳細は下記ページを参照下さい。

 

https://imagingsolution.net/program/opencv/opencv2-3/opencv2-3-downlaod-install/#compile-opencv

 

基本的にOpenCVなどのライブラリを使う場合は、ライブラリの3点セット(*.dll、*.lib、*.h)をいかに使うか?がポイントになります。

 

余裕のある方は下記ページも参考にしてみて下さい。

ライブラリの使用方法、VisualStudioの設定方法

 

これを覚えておくと、OpenCVがバージョンアップした場合や他のライブラリを使う場合など、応用ができると思います。
 

OpenCVへ戻る

 

OpenCV 2 プログラミングブック OpenCV 2.2/2.3対応

OpenCV2.0から登場したC++インターフェースに日本語で初めて?対応した参考書が登場します。

従来のOpenCV プログラミングブックを持っている方も多いかと思いますが、その第3弾です。

 

全くのOpenCV初心者にとっては、少し難しく感じるかも?しれませんが、これまでC言語のOpenCVを使っていた人が、C++インターフェースを使ってみたいという人には、ちょうど良いと思います。
個人的にはcv::Matを画像データに使う事は無いのですが、行列演算に使う分にはC++インターフェースもかなり、便利だと感じました。
ケーススタディもあるので、参考になると思います。

 

 

正誤表はこちらにあるので、読む前にチェックして下さい。
http://book.mycom.co.jp/support/pc/opencv2/#ERRATA

 

【目次】

 

▽Chapter.1 導入 編
1.1 画像処理とコンピュータビジョン
1.2 OpenCV
1.3 OpenCV 2.0
1.4 ライセンス条項

 

▽Chapter.2 スタートアップ 編
1 OpenCV 2.3簡単インストール(Windows編)
1.1 OpenCVの取得
1.2 OpenCVのインストール
1.3 環境変数の設定
1.4 Visual C++ 2010の環境設定
1.5 新規プログラムの作成方法
1.6 サンプルプログラムの実行

2 OpenCVをMacで利用する
2.1 Xcodeのインストール
2.2 MacPortsのインストール
2.3 OpenCVのインストール
2.4 サンプルプログラムによる動作確認
2.5 XcodeでOpenCVを使う

3 Ubuntu 10.04 LTSでOpenCVを利用する
3.1 設定
3.2 luvcviewでキャプチャ
3.3 luvcviewの使い方
3.4 aptパッケージを使ったOpenCVのインストール
3.5 新しいバージョンのOpenCVのインストール

4 C++インタフェース
1 OpenCV 2.0のC++向けインタフェースについて
2 従来のインタフェースとの違い
3 従来のインタフェースとC++インタフェースを混在させる

5 Pythonインタフェース
5.1 Pythonインタフェースのインストール
5.2 Pythonインタフェースを試す

6 GPUによる画像処理
6.1 OpenCVのGPU対応
6.2 OpenCVでGPUを利用した画像処理を行う方法
6.3 インストール
6.4 プログラムの作成
6.5 サンプル

 

▽Chapter.3 リファレンス 編
1 cv::Matの基本処理
1.1 cv::Matを初期化する
1.2 cv::Matのそのほかの処理
1.3 cv::Matの様々なプロパティ
1.4 std::cout への出力
1.5 cv::Matの型(ビット深度)を変換する
1.6 cv::Matをリサイズする
1.7 cv::Matを変形する
1.8 cv::Matの要素をシャッフルする
1.9 cv::Mat_を使う
1.10 cv::Matxを使う
1.11 cv::Vecを使う
1.12 cv::MatとIplImageの相互変換
1.13 cv::MatとCvMatの相互変換
1.14 cv::MatとSTL vectorの相互変換
1.15 cv::Matとcv::Matxの相互変換
1.16 cv::Matとcv::SparseMatの相互変換
1.17 cv::MatとEigen::Matrixの相互変換
1.18 チャンネルの合成と分離
1.19 列/行ごとの合計,平均値,最小,最大値を求める

2 線形代数
2.1 行列要素の四則演算を行う
2.2 行列同士の積を求める
2.3 cv::Vecの内積と外積
2.4 ノルムを求める
2.5 行列式を求める
2.6 行列の転置
2.7 行列の対角成分を取り出す
2.8 行列のトレースを求める
2.9 逆行列/疑似逆行列を求める
2.10 2次元ベクトルの角度と大きさを求める
2.11 角度と大きさから2次元座標を求める
2.12 行列を反転する
2.13 行列要素の最小値・最大値を求める
2.14 2次元点集合間の最適なアフィン変換を推定する
2.15 連立1次方程式を解く

3 画像処理
3.1 画像を単色で塗りつぶす
3.2 色空間を変換する
3.3 画像サイズを変更する
3.4 画像を垂直・水平に反転する
3.5 画像をネガポジ反転する
3.6 画像を2値化する
3.7 画像ピラミッドを作る
3.8 画像を平滑化する(ぼかす)
3.9 点座標集合に外接する図形を求める
3.10 画像の修復・不要オブジェクトを除去する
3.11 直線を検出する
3.12 円を検出する
3.13 楕円フィッティングを行う
3.14 画像のヒストグラムを計算・描画する
3.15 画像の一部を切り抜いて保存する
3.16 画像の一部のみを処理する
3.17 矩形領域のピクセル値をサブピクセル精度で取得する
3.18 顔を検出する
3.19 目を検出する
3.20 複数の矩形をグループ化する
3.21 チャンネルの合成と分離
3.22 画像に境界領域を追加する

4 描画処理
4.1 線分を描く
4.2 矩形を描く
4.3 円を描く
4.4 楕円・円弧を描く
4.5 折れ線を描く
4.6 ポリゴンを描く
4.7 テキストを描く

5 入出力
5.1 画像を表示する
5.2 ファイルから画像を読み込む
5.3 ファイルに画像を書き出す
5.4 カメラ画像をキャプチャする
5.5 画像をメモリ上でエンコード/デコードする
5.6 YAML/XMLを読み込む・書き出す

6 その他の機能
6.1 OpenCVのバージョンを調べる
6.2 処理時間を計測する
6.3 printf風の表記で文字列を出力する
6.4 CV_Assert/CV_DbgAssert
6.5 CPUがサポートする機能(SSEなど)をチェックする

 

▽Chapter.4 ケーススタディ 編
1 画素値の直接操作
1.1 画素単位の操作
1.2 サンプルプログラムと速度比較
1.3 画像のディザリング – 画素値の直接操作事例1
1.4 画像の細線化 – 画素値の直接操作事例2

2 カメラキャリブレーションとステレオ視による距離計測
2.1 カメラキャリブレーション
2.2 ステレオマッチング

3 画像のJPEG圧縮とPSNRの計算
3.1 PSNR
3.2 プログラムと実行結果

4 簡単な笑顔度の算出
4.1 笑顔度の算出方法
4.2 プログラムと実行結果

5 CAPTCHA画像の生成
5.1 解読を困難にするには
5.2 プログラムと実行結果

6 KinectとOpenCVの連携
6.1 Kinectとは
6.2 ドライバ一式のインストール
6.3 プログラムと実行結果

7 ミニチュア風画像処理
7.1 プログラムと実行結果

8 SURF特徴を使ったイメージモザイキング
8.1 イメージモザイキングの流れ
8.2 特徴点抽出
8.3 前フレームとの特徴点の対応付け
8.4 ホモグラフィ行列の推定と画像ワーピング
8.5 画像の重ね合わせ(画像マスク)
8.6 イメージモザイキングプログラムと実行結果

9 機械学習と画像処理
9.1 学習の種類
9.2 混合ガウス分布とEMアルゴリズムを用いたクラスタリング
9.3 OpenCVにおける実装
9.4 オプティカルフローのクラスタリング
9.5 クラスタリング手法の適用
9.6 実行結果

10 顔の子供化
10.1 子供らしく見える顔
10.2 顔の子供化処理

11 Photoshop向けプラグインの作成
11.1 Photoshop プラグインについて
11.2 環境の作成

12 動画ファイルをカメラ入力のように扱う
12.1 動画ファイルの入力
12.2 VideoCaptureのパラメータ

 

OpenCVへ戻る

 

コンピュータビジョン最先端ガイド4

コンピュータビジョン最先端ガイド1,2,3に引き続き第4弾が発売されました。

 

今回の最先端ガイド4では、これまでの1~3のように画像処理アルゴリズ中心の話とは異なり、カメラや照明に関するテーマが中心なので、画像処理アルゴリズムを期待している人は注意して下さい。

 

とは言うのもの、実際の画像処理では、カメラや照明などの撮影方法についても大事だと思います。

 

 

 

【目次】

第1章 画像化プロセスと画像ノイズ

1.はじめに
2.前知識
3.画像化プロセス
4.画像化プロセスと画像ノイズ
5.画像ノイズの計測
6.画像化プロセス・画像ノイズの利用
7.画像ノイズとノルム
8.まとめと今後の課題

第2章 コンピュテーショナルフォトグラフィ理解のための光学入門

1.はじめに
2.レンズ
3.光線の表現とカメラの動き
4.応用例
5.ライトフィールドの特性と解析
6.まとめ

第3章 符号化撮像

1.はじめに
2.ぼけ関数の符号化
3.絞りによる符号化
4.レンズなどを用いた符号化
5.モーションブラー復元のための符号化
6.デコンボリューション
7.おわりに

第4章 光と色の計測と表現ーコンピュータビジョンの観点からー

1.はじめに
2.光源の特性
3.物体表面の特性
4.分光画像情報の獲得
5.人間の感覚系の特性
6.表色のためのカラーオーダーシステム
7.色の数値化と測色原理
8.均等色空間と色差
9.色名による表現
10.カラー画像の表示
11.おわりに

第5章 反射・錯乱の計算とモデル化

1.はじめに
2.光の物理量と伝播
3.反射特性のモデル
4.反射特性の計測
5.散乱特性のモデル
6.散乱特性の計測
7.POV-Ray
8.書籍
9.まとめ

【OpenCV】バイラテラルフィルタ(cvSmooth,CV_BILATERAL)

OpenCVでバイラテラルフィルタを行う場合はcvSmooth関数の第3引数にCV_BILATERALを指定すればよいのですが、OpenCV.jpのページなどを見ても、なぜか、それらしい処理結果になっているサンプルをあまり見かけません。

 

cvSmoothの定義は

 

void cvSmooth(
         const CvArr* src,
         CvArr* dst,
         int smoothtype = CV_GAUSSIAN,
         int param1 = 3,
         int param2 = 0,
         double param3 = 0,
         double param4 = 0
);

 

で、バイラテラルフィルタの場合、

param1 アパーチャサイズ
param2 アパーチャサイズ
param3 空間領域のシグマ
param4 色領域のシグマ

 

ただし、

インプレースモード 非対応
チャンネル数 1,3
srcの深度 8
dstの深度 8

 

となっています。

 

そこで、param3、param4を変えながら、処理結果の比較をしてみました。

 

【入力画像】

 

【処理画像】

cvSmooth(src, dst, CV_BILATERAL, 11, 11, param3, param4);

(param3, param4) = (0, 0) (50, 0) (100, 0)
(0, 50) (50, 50) (100, 50)
 
(0, 100) (50, 100) (100, 100)

 

という事で、今回使用した画像では

cvSmooth(src, dst, CV_BILATERAL, 11, 11, 50, 100);

としたときが、いかにもバイラテラルフィルタっぽいでしょうか?

param4を少し大きめにした方が良さそうです。

逆にparam1, param2の値を大きくすると、処理時間がやたらとかかるので、あまり大きくできません。

 

OpenCVへ戻る

 

USBカメラ比較

最近フルHDサイズのUSBカメラ Logicool C910 (現行モデルはC920)を購入したのですが、このカメラを使ってOpenCV2.3.1で撮影すると、難なくキレイな画像が撮影できました。

(以前のバージョンのOpenCVでは画像サイズ4:3の縛りがあって、撮影できなかったのですが...)

 

このカメラの画像が想像以上にキレイだったので、手持ちのUSBカメラの画像比較してみました。

撮影条件は下の写真のようにほぼ同様の条件にしました。

 

今回比較に用いたUSBカメラは

  • BUFFALO BWC-30L01
  • Logicool Qcam Fusion
  • Logicool C910

の3つ。

 

それぞれカメラの最大画素数で撮影してみました。(写真をクリックすると等倍で表示されます。)

 

  • BUFFALO BWC-30L01  (640×480)

 

  • Logicool Qcam Fusion (1280×960)

 

  • Logicool C910 (2592×1944)
    ※投稿できるファイル容量の限界を超えたため、jpgファイルで公開しています。

 

これまでUSBカメラでの画像を本気で画像処理に使う気はしなかったのですが、ここまでキレイだと、そこそこイケちゃうかも?

 

 

 

国際画像機器展2011

2011.12.7(水)~12.9(金)にパシフィコ横浜にて国際画像機器展2011が開催されます。

国際画像機器展2011

http://www.adcom-media.co.jp/ite/

 

無料ですので、画像処理やカメラ、照明、キャプチャボードなどをお探しの方、まずは事前登録してみては如何でしょうか?

http://www.adcom-media.co.jp/ite/getinv/

 

また、無料のセミナーも開催されています。

http://www.adcom-media.co.jp/ite/seminar/

 

セミナーの内容だけ見ていると、USB3.0、GigE、CoaXPressなどと新しいカメラのインターフェースが登場し、時代が動きつつある感じがします。

 

で、私は、おそらく最終日の9日に説明員で立っているかも?知れないので、お気づきの方はお声をかけて下さい。

 

OpenCV-2.3.2-GPU-demo-pack-win32を試す

久々の投稿ですがSourceforgのOpenCVのページにGPUデモのプログラムが公開されていました。

http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.3.1/

 

バージョンもOpenCV2.3.2 って、まだ公開されていないのに...

 

で早速、このファイルをダウンロードし、試してみました。

私の環境は

OS:Windows7 64bit (ただし、サンプルは32bit動作)

CPU:Core i7 870 (2.93GHz)

GPU:NVIDIA GeForce GTX470

 

で、パフォーマンス評価用のサンプル(demo_performance.exe)を実行した時の結果がこちら↓

CPU msec   GPU msec   SPEEDUP   DESCRIPTION
matchTemplate
480 5 x86.5 src 3000, templ 5, 32F, CCORR
545 21 x24.9  src 3000, templ 25, 32F, CCORR
792 31 x25.4  src 3000, templ 5, 32F, CCORR
minMaxLoc
7  1  x4.81  src 2000, 32F, no mask
28  2  x14.3  src 4000, 32F, no mask
 106  3  x28.2  src 8000, 32F, no mask
 remap   
 8  0  x35.9  src 1000,8UC1
 30  0  x50.6  src 2000,8UC1
 124  2  x59.1  src 4000,8UC1
 12  0  x32.2  src 1000,8UC3
 42  1  x34.6  src 2000,8UC3
 164  4  x34.7  src 4000,8UC3
 11  0  x37.8  src 1000,8UC4
 40  0  x41.4  src 2000,8UC4
 156  3  x43.7  src 4000,8UC4
 29  0  x79.7  src 1000,16SC3
 117  1  x88.8  src 2000,16SC3
 481  4  x98.1  src 4000,16SC3
 dft   
 107  3  x29.2  size 1000, 32FC2, complex-to complex
 402 8  x45.3  size 2000, 32FC2, complex-to complex
 1781  32  x55.4  size 4000, 32FC2, complex-to complex
 cornerHarris
 129  19  x6.55  size 2000, 32F
 499  70  x7.06  size 4000, 32F
 integral
28 15 x1.82  size 4000, 8U
20 9 x2.04  size 4000, 8U
20 9 x2.11  size 4000, 8U
21 9 x2.2  size 4000, 8U
21 9 x2.15  size 4000, 8U
norm
139 5 x27.3 size 2000, 32FC4, NORM_INF
310 8 x35.2 size 3000, 32FC4, NORM_INF
555 14 x38.2 size 4000, 32FC4, NORM_INF
meanShift
304 8 x36.3  size 400, 8UC3 vs 8UC4
1187 29 x40.2  size 800, 8UC3 vs 8UC4
SURF
5179 117 x43.9
BruteForceMatcher
1230 8 x144 match
1257 9 x136 knnMatch, 2
1301 9 x139 knnMatch, 3
1220 9 x135 radiusMatch
magnitude
41 0 x86 size 2000
88 1 x85 size 3000
162 1 x95 size 4000
add
10 0 x20.1 size 2000, 32F
22 1 x21.4 size 3000, 32F
41 1 x23.9 size 4000, 32F
log
25 0 x55.8 size 2000, 32F
54 0 x66.1 size 3000, 32F
97 1 x71.3 size 4000, 32F
exp
25 0 x53 size 2000, 32F
58 0 x73.7 size 3000, 32F
10 1 x74.6 size 4000, 32F
mulSpectrums
24 0 x53 size 2000, 32F
58 0 x73.7 size 3000, 32F
101 1 x74.6 size 4000, 32F
resize
7 0 x33.5 size 1000, 8UC1, up
28 0 x50.4 size 2000, 8UC1, up
64 1 x53.3 size 3000, 8UC1, up
2 0 x26.6 size 1000, 8UC1, down
8 0 x51.6 size 2000, 8UC1, down
18 0 x94.6 size 3000, 8UC1, down
21 2 x8.5 size 1000, 8UC3, up
82 8 x10.2 size 2000, 8UC3, up
187 17 x10.9 size 3000, 8UC3, up
7 0 x13.8 size 1000, 8UC3, down
26 1 x23.8 size 2000, 8UC3, down
58 1 x32.7 size 3000, 8UC3, down
27 1 x17.1 size 1000, 8UC4, up
108 4 x26 size 2000, 8UC4, up
250 9 x27.5 size 3000, 8UC4, up
9 0 x14.6 size 1000, 8UC4, down
32 0 x37.4 size 1000, 8UC4, down
73 1 x52 size 1000, 8UC4, down
9 2 x4.72 size 1000, 32FC1, up
41 6 x6.25 size 2000, 32FC1, up
88 13 x6.45 size 3000, 32FC1, up
2 0 x4.92 size 1000, 32FC1, down
10 0 x12.1 size 2000, 32FC1, down
23 1 x17.2 size 3000, 32FC1, down
cvtColor
29 0 x37.1 size 4000, CV_GRAY2BGRA
82 1 x61.8 size 4000, CV_BGR2YCrCb
105 1 x71.3 size 4000, CV_YCrCb2BGR
123 1 x84.4 size 4000, CV_BGR2XYZ
116 1 x83.7 size 4000, CV_XYZ2BGR
195 2 x72.9 size 4000, CV_BGR2HSV
550 2 x189 size 4000, CV_HSV2BGR
erode 
9 3 x2.65 size 2000
22 7 x3.07 size 3000
39 11 x3.35 size 4000
threshold   
0 0  x1.62 size 1000, 8U, THRESH_BINARY
1 0  x6.15 size 2000, 8U, THRESH_BINARY
3 0  x11.1 size 3000, 8U, THRESH_BINARY
6 0  x11.4 size 4000, 8U, THRESH_BINARY
1 0  x7.49 size 1000, 32F, THRESH_BINARY
6 0  x18.8 size 2000, 32F, THRESH_BINARY
14 0  x19.6 size 3000, 32F, THRESH_BINARY
25 1  x21.9 size 4000, 32F, THRESH_BINARY
pow   
5 0 x32.9 size 1000, 32F
20 0 x57.1 size 2000, 32F
44 0 x58.2 size 3000, 32F
83 1 x55.8 size 4000, 32F
projectPoints
49 2 x23.3 size 1000000
37 2 x16.1 size 714285
26 1 x24.5 size510203
19 0 x20.9 size 364430
12 0 x21.6 size 230307
solvePnPRansac
217 118 x1.84 num_points 5000
392 120 x3.25 num_points 18800
1315 127 x10.3 num_points 70688
4984 160 x31 num_points 265786
GaussianBlur
1  0 x4.26 8UC1, size 1000
6  1 x5.61 8UC1, size 2000
14  2 x6.08 8UC1, size 3000
24  3 x6.36 8UC1, size 4000
5  0 x7.57 8UC4, size 1000
24  2 x10.2 8UC4, size 2000
56  4 x11.8 8UC4, size 3000
100  8 x11.7 8UC4, size 4000
2  0 x5.16 32FC1, size 1000
8  1 x7.39 32FC1, size 2000
17  2 x7.6 32FC1, size 3000
33  3 x8.63 32FC1, size 4000
pryDown
18 5 x3.55 8UC1, size 4000
10 2 x3.62 8UC1, size 3000
4 1 x3.41 8UC1, size 2000
1 0 x2.74 8UC1, size 1000
64 6 x9.52 8UC3, size 4000
38 3 x10 8UC3, size 3000
16 1 x9.26 8UC3, size 2000
4 0 x7.71 8UC3, size 1000
66 7 x8.98 8UC4, size 4000
38 4 x9.14 8UC4, size 3000
17 2 x6.36 8UC4, size 2000
4 0 x7.98 8UC4, size 1000
107 6 x15.6 16SC4, size 4000
60 3 x15.6 16SC4, size 3000
26 1 x14.9 16SC4, size 2000
7 0 x10.2 16SC4, size 1000
29 5 x5.7 32FC1, size 4000
17 3 x5.92 32FC1, size 3000
7 1 x5.65 32FC1, size 2000
1 0 x4.62 32FC1, size 1000
88 6 x13 32FC3, size 4000
52 3 x13.8 32FC3, size 3000
22 1 x12.7 32FC3, size 2000
5 0 x4.92 32FC3, size 1000
122 7 x17 32FC4, size 4000
67 4 x16.9 32FC4, size 3000
30 1 x16.6 32FC4, size 2000
7 0 x14.4 32FC4, size 1000
pyrUp
51 5 x8.97 8UC1, size 2000
12 1 x8.52 8UC1, size 1000
145 8 x17.3 8UC3, size 2000
36 2 x16.5 8UC3, size 1000
198 11 x17.6 8UC4, size 2000
48 2 x16.7 8UC4, size 1000
170 8 x19.6 16SC3, size 2000
44 2 x20.1 16SC3, size 1000
69 5 x12.2 32FC1, size 2000
17 1 x11.4 32FC1, size 1000
205 7 x27.3 32FC3, size 2000
21 1 x26.2 32FC3, size 1000
equalizeHist
2 1 x1.93 size 1000
10 2 x4.78 size 2000
23 3 x6.37 size 3000
Canny
29 3  x9.63
reduce
1 0 x7.79 size 1000, dim = 0
1 0 x10.1 size 1000, dim = 1
6 0 x14.5 size 2000, dim = 0
6 0 x25.2 size 2000, dim = 1
13 0 x17.5 size 3000, dim = 0
13 0 x29.3 size 3000, dim = 1

average GPU speedup: x29.202

 

sizeの表記は、size1000の場合、画像サイズは1000×1000となります。

 

一般的にGPUを使った画像処理ではメモリの転送時間がかかり処理時間トータルでは、あまり高速化されない

と言われる場合も多いので、ソースコードを見てみないと、いまいち結果をそのまま信用できない...

でも、とりあえずは、そこそこ速そうな結果でした

 

ソースコードは こちら

https://code.ros.org/trac/opencv/changeset/6950?utm_source=twitterfeed&utm_medium=twitter

 

OpenCVへ戻る

 

お詫び および お願い

いつもブログをご覧頂きありがとうございます。

 

9月より、これまで使っていたプロバイダを解約しました。

 

それに伴い、本ブログの「問い合わせページ」
https://imagingsolution.net/inquiry/
より問い合わせ頂いた内容は、私の元に届いておりません。

 

大変、恐縮ではありますが、9月以降にお問合せページより
お問合せ頂いた方をいらっしゃいましたら、再度、コメント
頂けるようお願い致します。
                    Akira

OpenCV2.3.1が公開されました。

OpenCV2.3.1のインストール方法については、別途記事にまとめました。
下記を参照願います。
OpenCV2.3.1の入手、ダウンロード、インストール、環境設定


 

本日(2011.8.18)、OpenCV 2.3.1が公開されました。

 

Android版の2.3.1のβ版は比較的前から公開されていましたが、今回はWindows版が公開されました。

 

ただし、OpenCV-2.3.1-win-superpack.exe のコンパイル済み版のみ?

と思っていたら、OpenCV-2.3.1-win-superpack.exeを解凍して出来たopencvというフォルダにソースコードが格納されているので、このフォルダをCMakeのsource codeフォルダに指定すればOKです。

 

入手先

http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.3.1/

変更内容

http://opencv.willowgarage.com/wiki/OpenCV%20Change%20Logs

 

まだ、実際には触っていませんが、まずは報告まで。

 

インストール方法についてはVer2.3.0とフォルダ構成が若干異なりますが、『OpenCV-2.3.0-win-superpack.exe』を使うときとほぼ同じなので、下記、リンク先の記事を参照下さい。

libファイルの2.3.0の部分を2.3.1に読み替えて参照下さい。

 

(参考)

OpenCV2.3の入手、ダウンロード、インストール、環境設定

https://imagingsolution.net/program/opencv/opencv2-3/opencv2-3-downlaod-install/

フラットフィールドコレクション(FFC)

フラットフィールドコレクションとは?

フラットフィールドコレクション(Flat Field Correction【略: FFC】)とは、撮影した画像の輝度値を均一にする補正で、比較的高価な工業用のカメラに搭載され、主にラインセンサカメラには、このフラットフィールドコレクションの機能が搭載されています。

 

そもそも、真っ白な被写体を撮影した時に、なぜ撮影した画像の輝度値が均一にならないのか?と言うと、考えられる要因として

 

  • レンズのシェーディングによる影響
  • 照明の明るさのムラ
  • CCD素子1つ1つの感度のばらつき

 

などが挙げられます。

 

フラットフィールドコレクションを行うと、これらの要因をまとめて補正する事が可能となります。

 

   
フラットフィールドコレクション前 フラットフィールドコレクション後

 

このフラットフィールドコレクションは、カメラのアナログオフセット(足し算/引き算)、アナログゲイン(掛け算/割り算)、デジタルオフセット(足し算/引き算)、デジタルゲイン(掛け算/割り算)を駆使して輝度値が均一になるように補正されます。
多少、実際の補正手順が面倒なので敬遠されがちですが、補正アルゴリズムを理解すると、ある程度、納得できると思います。

 

補正アルゴリズム

カメラにより実際の処理は異なる部分があると思いますが、おおむね以下の流れでフラットフィールドコレクションは行われます。

 

まず、最初にフラットフィールドコレクションによる輝度値の補正により、輝度値が飽和しない(輝度値が255を超えない)ようにするため、画像の最大輝度値が、おおむね255の80%程度(204ぐらい)になるように、実際の撮影する環境(照明、露光時間など)においてアナログゲインを調整します。

 

 

上図を見ても分かるように、画素のよっては入力光量が小さい場合(暗い場合)、出力輝度値が0になってしまう画素がある可能性があります。

 

これを補正するため、入力光量を0にして(レンズにキャプをする)、アナログオフセットで画像の最小輝度値が0にならないように調整します。

 

 

この状態で、カメラの黒レベル補正(FPN)の機能を実行すると、カメラ内部では、黒レベル(輝度値0)において、各画素の輝度値が0になるようデジタルオフセットの値が調整されます。

 

 

次に実際の撮影状態(照明、露光時間など)にして、できるだけ反射や汚れ、ムラの少ない白の被写体を撮影し、カメラの白レベル補正(PRNU)の機能を実行します。

 

すると、上記の撮影状態で全画素が指定した目標輝度値(輝度値を指定できないカメラもある)になるように、カメラ内部では全画素のデジタルゲインの値が調整されます。

 

 

この一連の処理を行う事で、最初に紹介したように、画像全体が均一な輝度値となる画像を得る事が可能となります。

 

また、上記の説明は、以下の順序でゲイン/オフセットの補正が行われる事を前提に説明しています。

 

CCDの電気信号アナログオフセットアナログオゲインデジタルオフセットデジタルゲイン

 

この機能は、主に二値化処理を用いた処理による画像検査などにおいては、効果を発揮します。

ロバスト推定法(Tukey’s biweight)

ロバストとは?

ロバスト(Robust)という言葉を辞書で調べると、「頑健なさま、がっしりした様子」という意味が載っています。

 

画像処理的には、ノイズや影、明るさの変動などの影響を受けにくく、安定した処理結果が得られる、ぐらいの意味として捉えれば良いでしょう。

 

ロバスト推定法

通常の最小二乗法では下図のように、数点の大きな誤差が含まれるだけでも、近似した直線が大きくズレてしまう場合があります。
この誤差の影響をできるだけ受けないようにしたのが、ロバスト推定法です。

 

処理アルゴリズム

まずは最初に、通常の最小二乗法を行います。
(今回は簡単にするため一次式で近似する例で紹介します。)

 

直線の式(y=ax+b)で近似する場合は以下のように行列を用いて解くことができます。

 

この近似した直線から遠く離れたデータを除去するだけでも、大きな誤差のデータの影響を受けなくなりそうですが、ここでは、誤差の大きさに応じて重みを付けるTukeyのBiweight推定法という手法を紹介します。

 

近似データ(Xi、Yi)と近似直線との誤差 d=Yi – (aXi + b) を用いて、誤差が大きければ大きいほど、
最小二乗に与える影響力(重み)が小さくなるように、以下のような式を用いて重み計算します。

 

d < -Wの場合

-W <= d <= Wの場合

W < dの場合

 

ただし、大文字のは誤差の許容範囲を示します。

 

この重みの関数w(d)をグラフで示すと、このようになります。

 

 

上図を見ても分かるように誤差の絶対値がWを超えると重みが0となり、次に行う重み付き最小二乗法では近似に影響を与えなくなり、逆に誤差が0に近づく程、重みが増し、近似への影響が大きくなります。

 

この重み wi を各近似データ(Xi、Yi)に関して計算し、wiを付加した最小二乗法を再度行います。

 

 

こうして求めた近似式(y = a’X + b’)は最初に求めた近似式よりも、測定データに近づきます。
この処理を誤差の許容範囲()を小さくしながら、誤差が少なくなるまで繰り返すことで、より測定データに近づいた近似式を得ることができます。

 

今回の例では一次式について示していますが、他のn次式などについても、同様に行列の各要素に重みを付加することで、ロバスト推定を行うことができます。

 

参考文献

 

使える数学へ戻る

 

最小二乗法の最適化(高速化)

最小二乗法を用いて曲線近似するとき、近似するX座標の値が等間隔に並んでいる場合、奇関数、偶関数の特性を使って最小二乗法を高速に処理することが可能になります。

 

例えば、画像中の線の中心位置や、エッジの位置をサブピクセル単位で求める場合などに有効です。

 

 

以下からは線の輝度値を2次曲線で近似して、線の中心を求める例を示します。

 

X方向の輝度値が最大となる座標付近の輝度値を抜き出し、2次式で近似すると
X座標が180と181との間に最大値がありそうな事が分かります。

 

 

この輝度値を二次式(Y = aX2 + bX + c)で近似する場合、下記の行列の式を解くと二次式が求まります。

 

 

ここで、逆行列の中は奇関数、偶関数の集まりなので、輝度値データのX座標を中心座標(X = 180.5)で割り振ると

 

 

となります。
よって、奇関数、偶関数の特性から、行列の式は

 

 

となり、行列の計算量を減らすことができます。

 

また、近似するデータの個数が固定できるなら、逆行列の部分はあらかじめ計算しておく事ができるので、さらに計算量を減らすことができます。

 

これで、求める線の中心座標は近似曲線の頂点位置、つまり微分の値が0となる座標(Y’ = 0の座標)なので、

線の中心座標 = Xの中心座標 – b / 2a
(今回の例ではXの中心座標 = 180.5)

 

となり、より高速に線の中心座標を求めることができるようになります。

 

この前提条件とした『X座標の値が等間隔に並んでいる場合』という部分ですが、画像処理においては、画素のX座標、Y座標を用いて、輝度値に関して近似する場合が多いので、for文などで、ある関数の総和などを求める場合には、この奇関数・偶関数が使えないか?検討してみると良いと思います。

 

このテクニックは計算量が格段に少なくなるので、効果的な場合が多いと思います。

 

使える数学へ戻る

 

最小二乗法をExcelで解く

エクセルではグラフの機能で近似曲線の追加というのはありますが、任意の式で近似したい場合や、近似式の係数を取得したい場合にはエクセルの近似曲線の機能だけでは物足りない場合があります。
そんなときにエクセルでまじめに最小二乗法で解く方法を紹介します。

 

まずは、最小二乗法を解くとき、逆行列を用いるところまではご理解願います。
詳しくはこちらで紹介しています。

 

最小二乗法
一般式による最小二乗法

 

また、Excelで行列を計算する方法はこちらを参照下さい。

 

行列の積、逆行列、転置行列の計算

 

以下では円の最小二乗法を例にとって説明をしたいと思います。

 

円の最小二乗法を解くときの円の一般式を

 

X2 + Y2 + AX + BY + C = 0

 

としたときの行列の式は

 

 

です。
まず、行列の式に使われているの値を求めます。
はエクセル関数の「SUM」関数を用いればよいので、簡単に求まります。

 

 

まず、行列の式の各値を各セルに書いておきます。
次に逆行列を求めるのですが、エクセル関数に「MINVERSE」というのがあります。

 

逆行列を表示したい複数のセル(下記の例では3×3のセル)を選択します。
次に

 

=MINVERSE(逆行列を求める複数のセル)

 

と入力します。ここでは文字を入力するだけでEnterキーは押さないこと

 

 

 

で、次が最大のポイント!
通常ではEnterキーを押したいところですが、行列の計算では

 

Ctrlキー  + Shiftキー + Enterキー

 

を同時に押します。
これで、逆行列の値が求まります。

 

 

あとは行列の積が計算できれば、求めたいA,B,Cの値を求めることができるのですが、
行列の積の計算にはエクセル関数の「MMULT」という関数を用います。

 

逆行列を計算したときと同様に行列の積の結果を表示したいセル複数のセルを選択し、

 

=MMULT(行列1,行列2)

 

を入力します。ここでも最後はEnterキーだけではなく

 

Ctrlキー  + Shiftキー + Enterキー

 

を押すので注意して下さい。

 

 

これで求めたかった未知数A,B,Cが求まります。

 

 

今回は円の近似なので、A,B,Cの値を用いで円の中心座標(a,b)、円の半径rを求めるには

 

a = -A / 2
b = -B / 2
r = SQRT(a2 + b2 – C)

 

なので、

 

 

となり、円の近似式を求めることができます。

 

このエクセルによる円の最小二乗法のファイルはこちら↓

LSM_Circle.xls

 

また、一般的なn次式による最小二乗法を解いたのファイルはこちら↓

n_LeastSquare.xls

 

使える数学へ戻る

 

CVKaleidoscope

今回はちょっと息抜き。

ネタ的には、よくある話なのですが、OpenCVのアフィン変換のおさらいも含めて、USBカメラを使った万華鏡ソフトを作ってみました。

 

USBカメラから取得した画像から、三角形領域を切り出し、回転、ミラー反転などを行って、万華鏡っぽくしています。

 

ファイルのダウンロードはこちら↓より

CVKaleidoscope230x86.zip

 

【開発環境】

●Visual Studio 2010 C++

●OpenCV2.3 x86 (32bit版)

 

上記の環境があれば、おそらく動作すると思います。

USBカメラは最初に見つけたカメラから640×480サイズで画像を取得しています。

 

【操作方法】

画像上で

Sキーで三角形の回転が開始/停止します。

その他のキーでプログラムが終了します。

 

作ってみると、思いの他、細かいバグにハマって苦労してしまいました...

 

【OpenCV2.3】サンプルプログラム(C言語版)

OpenCV2.3においても、プログラムの作成方法はOpenCV2.2の時とさほど変わりません。

 

ここでは、OpenCV2.3の入手、ダウンロード、インストール、環境設定で紹介している方法でインストールした場合を想定しています。

 

基本的なC言語のプロジェクトファイルの作成方法については

【OpenCV2.2】新規プロジェクトの作成方法(C言語版)

のページを参照して下さい。

このページと異なるのはヘッダファイル(インクルードファイル)のディレクトリの設定方法のみです。

設定方法は

プロジェクトのプロパティで構成プロパティ⇒C/C++⇒全般の追加のインクルードディレクトリに

C:\OpenCV2.3\include

を指定します。

 

簡単なサンプルプログラムは以下の通りです。

// OpenCV23-C-Sample.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"

//プロジェクトのプロパティ⇒C/C++⇒全般 の追加のインクルードディレクトリに
// 『C:\OpenCV2.3\include』を追加のこと
#include "opencv2\\opencv.hpp"
 
#ifdef _DEBUG
    //Debugモードの場合
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_core230d.lib")
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_imgproc230d.lib")
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_highgui230d.lib")
#else
    //Releaseモードの場合
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_core230.lib")
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_imgproc230.lib")
    #pragma comment(lib,"C:\\OpenCV2.3\\lib\\opencv_highgui230.lib")
#endif

int _tmain(int argc, _TCHAR* argv[])
{

    //画像データの読込
    IplImage* src_img = cvLoadImage("C:\\OpenCV2.3\\samples\\c\\lena.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
    if (src_img == NULL){
        return 0;
    }
 
    //表示ウィンドウの作成
    cvNamedWindow("src");
    cvNamedWindow("dst");
 
    //処理後画像データの確保
    IplImage* dst_img = cvCreateImage(cvGetSize(src_img), src_img->depth, src_img->nChannels);
 
    //画像処理例(ガウシアンフィルタ)
    cvSmooth(src_img, dst_img, CV_GAUSSIAN, 9);
 
    //画像の表示
    cvShowImage ("src", src_img);
    cvShowImage ("dst", dst_img);
 
    //キー入力待ち
    cvWaitKey (0);
 
    //全てのウィンドウの削除
    cvDestroyAllWindows();
 
    //画像データの解放
    cvReleaseImage(&src_img);
    cvReleaseImage(&dst_img);
 
	return 0;
}

サンプルプログラムのダウンロードはこちらより
OpenCV23-C-Sample.zip (Visual Studio 2010 C++ Expressで作成しています。)

 

実行例


OpenCVへ戻る