はじめに
Jetsonを用いた産業用カメラGenie Nanoの制御とopencvへの応用について記載します。
背景
様々な環境下でカメラを使用する場合にWeb Cameraでは適さない環境が多くあります。その点、Genie Nanoは屋外環境にも対応した堅牢な筐体設計のため、設置場所を選ばずに映像データの出力が可能になります。
Jetsonを用いて一般的なWebCamera(logicool C270n ,C920n)から得た画像をPython with OpenCVで制御するページはよく見かけますが、今回は、Genie Nano(産業用カメラ)から得た画像をC++ with OpenCVで制御する方法を紹介します。
環境
参考2にもありますが、以下のソフトウエアが必要になります。
なお、Jetson環境では、特に、OpenCVとBoost librariesのみをインストールすれば問題なく動きました。
- GigE-V framework for linux
- ffmpeg
- OpenCV
- Boost libraries
クラス図
- DalsaGlabberからDalsaCameraオブジェクトが宣言され、利用されている。
- DalsaCameraクラスからDALSA_CAMERAオブジェクト及びEncoderオブジェクトが宣言され、利用されている。
ソフトウエア実装について
(参考2)については、非常にわかりやすくコーディングされているため、コードを読めばだいたいわかる。少し複雑なのは、以下の場所なのでそこだけ少し補足する。
int DalsaCamera::getNextImage(cv::Mat *img)
{
// Check for camera state
if(!isOpened())
{
cerr << "open camera before calling get_next_image";
return 1;
}
// Cache frames to the map until the next one is acquired
uint64_t next_timestamp = 0;
while(!next_timestamp)
{
// Acquire next image and cache into map
GEV_BUFFER_OBJECT *nextImage = nextAcquiredImage();
uint64_t acquired_t = combineTimestamps(nextImage->timestamp_lo, nextImage->timestamp_hi);
_reorderingMap[acquired_t] = nextImage;
// Check for _tNextFrameMicroseconds within a microsecond tolerance to account for rounding error
for(uint64_t t=_tNextFrameMicroseconds-2; t<=_tNextFrameMicroseconds+2; t++)
{
if(_reorderingMap.find(t) != _reorderingMap.end())
{
next_timestamp = t;
break;
}
}
}
// Get the next frame
GEV_BUFFER_OBJECT *imgGev = _reorderingMap[next_timestamp];
_reorderingMap.erase(next_timestamp);
logImg(imgGev);
//TODO: handle a reset of next frame
_tNextFrameMicroseconds = next_timestamp + periodMicroseconds();
// Debayer the image
cv::Mat imgCv = cv::Mat(height(), width(), CV_8UC1, imgGev->address);
cv::Mat rgb8BitMat(height(), width(), CV_8UC3);
cv::cvtColor(imgCv, rgb8BitMat, CV_BayerBG2RGB);
*img = rgb8BitMat;
// Release Image Buffer
GevReleaseImage(handle, imgGev);
imgCv.release();
return 0;
}
- std::mapで_reorderingMapを定義し、次回のフレーム取得タイミングをkeyに生のイメージを取得している(前後2msについても対象とし、検索している。)。
- 生のbayerイメージを最終的にはRGBに変換して、第一引数のポインターにGEV_BUFFER_OBJECT*を戻している。
使い方
あとは、環境が整っていれば以下のコマンドでdalsaGrabberを動作させることができる。./dalsaGrabber
でコマンドヘルプを参照できる。
git clone https://github.com/Segiori/dalsa-grabber.git
make
./dalsaGrabber monitor
結果
参考
(参考1)Dalsa Genie Nano正式
今回用いたCameraはGenie Nano C1280 Colorになります。
(参考2)A simple frame grabbing app using the Dalsa GigE-V framework
Aaron Fishmanさんが作成したコードをjetson(64bit)用にリビルド
(Thanks to Aaron Fishman)
(参考3)Bayerパターンの生データを使って効率良く画像処理を行う
Bayerパターンの説明
(参考4)std::mapのまとめ
std::mapがまとめられている。わかりやすい。