2011年7月30日土曜日

cvWrite, cvRead

プロジェクトに昔のファイルが入ってるから、使いまわしで分かるように書いておく。

int write_data(char *filename, Mat a_mat)
{     
        // ファイルを開く

CvFileStorage *fs;
        fs = cvOpenFileStorage (filename, 0, CV_STORAGE_WRITE);
if(! fs ){
cout<<"can not open "<<filename<<endl;
return 0;
}

        // Mat -> CvMat
CvMat a = a_mat;
     
        // 書き込む
cvWrite (fs, "a", &a);

        // ファイルを閉じる
cvReleaseFileStorage (&fs);
}


int read_data(char *filename)
{
        CvFileStorage *fs;
CvFileNode *param;
// (2)パラメータファイルの読み込み
fs = cvOpenFileStorage (filename, 0, CV_STORAGE_READ);
if(!fs){
cout <<"can not open "<< filename << endl;
return 0;
}

CvMat *a;

param = cvGetFileNodeByName (fs, NULL, "a"); 
        a = (CvMat *) cvRead (fs, param);
cvReleaseFileStorage (&fs);

        // CvMat → Mat
Mat a_mat;
a_mat = Mat(a);

        // あとでdoubleでメモリにアクセスする場合のために,要素の型変換を行う
        a.convertTo(a, CV_64F);

        return 1;
}

2011年7月28日木曜日

シェルを開いて処理する

system関数というのを使う。

system("wgnuplot -persist setting.plt");
のように。

2011年7月16日土曜日

OpenCV ライブラリの読み込み

これをインクルードしておくと便利っぽい。



// ヘッダーファイル
#include <opencv2/opencv.hpp>

// バージョン取得
#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_core"            CV_VERSION_STR CV_EXT_STR)
#pragma comment(lib, "opencv_highgui"        CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_imgproc"  CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_calib3d"  CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_gpu"   CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_video"   CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_objdetect"  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_ffmpeg"  CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_ts"   CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_contrib"  CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_ml"   CV_VERSION_STR CV_EXT_STR)
//#pragma comment(lib, "opencv_legacy"  CV_VERSION_STR CV_EXT_STR)

using namespace cv;



参考:
http://www.nakaguchi.org/index.php?OpenCV/Tips

2011年7月13日水曜日

画素値へのアクセス




int ch = img.channels(); // =3
//std::cout << "step:" << hsv_img.step << ", size:" << w*ch << std::endl;
int width = hsv_img.cols, height = hsv_img.rows;


hue-value gradation image





(2a) 
for(int y=0; y<height; ++y) {
     for(int x=0; x<width; ++x) {
          int a = hsv_img.step*y+(x*ch);
          hsv_img.data[a+0] = (x*180/width);
          hsv_img.data[a+1] = 255;
          hsv_img.data[a+2] = ((height-y)*255/height);
     }
}

(2b) 
for(int y=0; y<height; ++y) {
     uchar *p = hsv_img.ptr(y);
     for(int x=0; x<width; ++x) {
          p[x*ch+0] = (x*180/width);
          p[x*ch+1] = 255;
          p[x*ch+2] = ((height-y)*255/height);
     }
}


(2c) 
for(int y=0; y<height; ++y) {
     uchar *p = hsv_img.ptr(y);
     for(int x=0; x<width; ++x) {
          p[x*ch+0] = (x*180/width);
          p[x*ch+1] = 255;
          p[x*ch+2] = ((height-y)*255/height);
     }
}

(2d) 
for(int y=0; y<height; ++y) {
     for(int x=0; x<width; ++x) {
          Vec3b &p = hsv_img.at<Vec3b>(y,x);
          p[0] = (x*180/width);
          p[1] = 255;
          p[2] = ((height-y)*255/height);
     }
}


(2e) 
Mat_<Vec3b>& ref_img = (Mat_<Vec3b>&)hsv_img;
for(int y=0; y<height; ++y) {
     for(int x=0; x<width; ++x) {
          ref_img(y, x)[0] = (x*180/width);
          ref_img(y, x)[1] = 255;
          ref_img(y, x)[2] = ((height-y)*255/height);
     }
}


(2f) 
vector<Mat> planes;
split(hsv_img, planes);
MatIterator_<uchar> it_h = planes[0].begin<uchar>();
MatIterator_<uchar> it_s = planes[1].begin<uchar>();
MatIterator_<uchar> it_v = planes[2].begin<uchar>();
for(int c=0; it_h!=planes[0].end<uchar>(); ++it_h, ++it_s, ++it_v, ++c) {
     *it_h = ((c%width)*180/width);
     *it_s = 255;
     *it_v = ((height-c/width)*255/height);
}
merge(planes, hsv_img);



(2g)(when no-gap)
MatIterator_<Vec3b> it = hsv_img.begin<Vec3b>();
for(int c=0; it!=hsv_img.end<Vec3b>(); ++it,++c) {
     int x=c%width;
     int y=c/width;
     (*it)[0] = (x*180/width);
     (*it)[1] = 255;
     (*it)[2] = ((height-y)*255/height);
}



(2a)~(2e)までの速度はそれほど変わらない。



参考:
http://opencv.jp/opencv2-x-samples/access_pixel_value

2011年7月10日日曜日

OpenCV カメラの指定

Point Greyのカメラ(Micron Tracker)のデバドラとライブラリなどをインストールしたら、OpenCVでUSBカメラの読み込みができなくなった。




今までの設定は以下のとおり。




VideoCapture cap;

cap.open(0);







原因を探すために、デバッグでたどってみた。

エラーは

cap_dshow.cppの中の







//NOW LETS DEAL WITH GETTING THE RIGHT SIZE

hr = VD->streamConf->GetFormat(&VD->pAmMediaType);




カメラのフォーマットがとってこれないってとこ。

Point GreyのカメラはFlyCapでフォーマットを初期設定しないといけないから止まったのかな。

参考:http://nonnon-in-a-well.blogspot.com/2011/05/micron-tracker2.html







順に見てみると、デバイス(カメラ)をリストアップして、deviceIDでどのデバイス(カメラ)を読むか決めている。

それで、読もうとしていたのが"Point Grey Camera"だった。







//FIND VIDEO DEVICE AND ADD TO GRAPH//

//gets the device specified by the second argument.

hr = getDevice(&VD->pVideoInputFilter, deviceID, VD->wDeviceName, VD->nDeviceName);








ここのdeviceIDが0だったわけだね。

Point Greyをインストールしたせいで、デバイスのリストアップの順序が変わったらしい。

それで、deviceIDを1にしたら問題なく読み込めた。




VideoCapture cap;

cap.open(1);

2011年7月9日土曜日

OpenCV 動画の保存・読み込み

動画の保存と読み込みについて。

<環境>
Windows 7にWin7Codecsをインストールした状態
保存形式(拡張子): 「*.avi」


圧縮形式とメモリ量、速度について。



-----
Intel IYUV形式のAVI: 保存、読み込み両方OK。メモリは大きい。
-----
Xvid MPEG-4 Codec: 保存可能。それなりに早い。メモリはかなり小さい。読み込みもOK。
Lagarith Lossless Codec: 保存可能。それなりに早い。メモリは普通。読み込みもOK。
x264vfw - H.264/MPEG-4 AVC codec: 保存可能。それなりに早い。メモリは小さい。読み込みもOK。
Cinepack Codec by Radius: 保存、読み込み両方OK。ただし、圧縮に時間がかかる。
-----
Microsoft Video 1:保存OK。メモリは普通。読み込み失敗。
無圧縮:保存はできるけど、読み込みでメモリの開始位置か、チャネルが間違っているように思う。
色が分離しちゃってるから。
-----
Microsoft RLE: 保存ができない。
ffshow: 保存できない。
-----

OpenCV USBカメラ

OpenCV 2.3.1。

USBカメラの読込も初期化時点でstatic変数のせいで、動画が読み込めない(2.2では問題なく動いてる)。

参考:
http://nonnon-in-a-well.blogspot.com/2011/07/opencv.html
http://nonnon-in-a-well.blogspot.com/2011/07/opencv-videowriter.html

USBカメラの場合はDirectShowを使っているみたいで、

CoInitialize(NULL);


VideoCapture cap(filename);
または
cap.open(filename);

の前に追加。


終了時は

CoUninitialize();

を追加。

OpenCV 動画読込

2.2と2.3で動画(AVI?)関連のコードが変わってる。

ノートPC(2.2)で動くのに、デスクトップ(2.3.1)で動かない。
aviファイルを読み込む際に、

char *filename = "*.avi";
VideoCapture cap;
cap.open(filename);

とするわけだけど、ファイルを開けない。
なんでかなぁ、ということでソースをたどってみた。

こちらもどうやら、動画のライブラリの読み込みができていないせいで、

AVIFileInit();


AVIFileExit();


を追加する。
参考:http://nonnon-in-a-well.blogspot.com/2011/07/opencv-videowriter.html

2011年7月7日木曜日

OpenCV VideoWriter

動画の保存のためのクラス。


VideoWriter vw(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true);
または、
vw.open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true);
でファイルを開く。

その後、
vw.write(Mat &frame);
でファイルの書き込み。
終了は自動でしてくれる。



注意:
スレッドで繰り返し動画の保存をしようとしている時のこと。

ビデオの初期化部分でAVI用のライブラリを読み込む。
それがstaticな関数で読み込んでて、一度読み込むとフラグが立つ。
フラグもstatic。
そのため、次にファイルを開くときに、フラグが立っているため、ライブラリを読み込めない。
→ cap_vfw.cpp の static void icvInitCapture_VFW()

そこで、動画保存用にファイルを開く前にライブラリを読み込むことにした。

AVIFileInit();
VideoWriter(filename, CV_FOURCC_PROMPT, fps, size, true);
・・・

そして終了時に

AVIFileExit();

を追加。
これで繰り返し保存ができる。
追加のヘッダとライブラリは、下記ファイル。

#include <vfw.h>
vfw32.lib

2011年7月6日水曜日

Boost thread mutex

mutexのロックについて

boost::mutex m_mtx;

このm_mtxを共有している部分でロックをかける。

{ }で囲った範囲内でロックがかかり、{ }を出るとロックが自動的に解除される


何もない地の部分で{ }を使ってもいい。

{
     boost::mutex_scoped_lock lock(m_mtx);
     ・・・
}
または、解除方法として
lock.unlock();
という方法もある。

2011年7月4日月曜日

VC++ MFC

<AppEx>というクラスを使うには、

stdafx.hの中で
#include <afxcontrolbars.h>     // MFC におけるリボンとコントロール バーのサポート
を入れておく必要がある。


<タブコントロール>
タブの変更時の関数内。

void CLaserEndoscopeDlg::OnTcnSelchangeTabFunctions(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
int        sel;
sel = m_xcTab.GetCurSel();
    m_tabFunc.ShowWindow(sel == 0 ? SW_SHOW : SW_HIDE);
    m_tabConfig.ShowWindow(sel == 1 ? SW_SHOW : SW_HIDE);

if (pResult) *pResult = 0;
}

関数を生成したときには、最後に
*pResult = 0;
が自動的に記入されているが、
if (pResult)
を前につけないと、初期化の際にエラーになるので注意。
(Vistaではエラーにならなくて、Windows 7でエラーになった。)

2011年7月3日日曜日

Polaris marker

マーカの土台部分。
ねじは、インチねじで、No.4で並目(UNC; Coarse)。下穴は2.2mmくらいで。
ちなみに、UNFっていうのもあって、こっちは細目(Fine)。下穴は2.3mmくらいで。

2011年7月1日金曜日

VC++ アプリケーションの起動エラー

環境はVisual Studio 2008。
それでプログラムがコンパイルは通っても起動しない。
調べてみて、原因ぽいのが
Microsoft Visual C++ 2005 SP1 再頒布可能パッケージ (x86)。
入れなおし。
リンク:http://www.microsoft.com/downloads/details.aspx?FamilyID=200b2fd9-ae1a-4a14-984d-389c36f85647&displaylang=ja




参考
http://d.hatena.ne.jp/piy/20081130/1228020473