前回のpylonネタの続き、pylon Viewerでは良くわからなかったので、
Basler提供のサンプルソフトで、Chunk dataの取り方を調べてみました。
インストールフォルダ下を探していくと、sampleフォルダが有ります。
このうちC#には、”Basler.Pylon”と”PylonC.NET”の二種類が有りましたが、
今回は後者を開いて動かしてみました。(両者どう違うのかまでは未確認)
PylonC.NETSamplesの中身
ソリューションを開くと、11種類のサンプルプロジェクトが準備されています、
個人的にですが、VisualStudio2005形式なのは有り難いですね。
まずSimpleGrabで基本的な使い方を見ると、ざっくり下記の流れになるようです。
1.PylonC.NETへの参照追加
using System; using System.Collections.Generic; using PylonC.NET;
2.初期化
/* Before using any pylon methods, the pylon runtime must be initialized. */
Pylon.Initialize();
3.接続されたカメラ検出→カメラが何も認識されなければエラー中断
/* Enumerate all camera devices. You must call PylonEnumerateDevices() before creating a device. */ numDevices = Pylon.EnumerateDevices(); if (0 == numDevices) { throw new Exception("No devices found."); }
4.カメラオープン(複数有る場合は先頭のもの)
/* Get a handle for the first device found. */ hDev = Pylon.CreateDeviceByIndex(0); /* Before using the device, it must be opened. Open it for configuring parameters and for grabbing images. */ Pylon.DeviceOpen(hDev, Pylon.cPylonAccessModeControl | Pylon.cPylonAccessModeStream);
5.カメラを使って所望の処理を行う
6.後片付け
/* Clean up. Close and release the pylon device. */ Pylon.DeviceClose(hDev); Pylon.DestroyDevice(hDev); /* Shut down the pylon runtime system. Don't call any pylon method after calling Pylon.Terminate(). */ Pylon.Terminate();
Chunk dataを取り出す
次にサンプルのChunksを見てみます、上記流れの5.に該当する部分のみ抜粋。
まず初期設定、ChunkModeActiveをtrueに→ChunkSelectorでFramecounterを選択、
→ChunkEnableをtrueに、という順番で設定していくようです。
/* Before enabling individual chunks, the chunk mode in general must be activated. */ isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ChunkModeActive"); if (!isAvail) { throw new Exception("The device doesn't support the chunk mode."); } /* Activate the chunk mode. */ Pylon.DeviceSetBooleanFeature(hDev, "ChunkModeActive", true); /* Enable some individual chunks... */ /* ... The frame counter chunk feature. */ /* Is the chunk feature available? */ isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "EnumEntry_ChunkSelector_Framecounter"); if (isAvail) { /* Select the frame counter chunk feature. */ Pylon.DeviceFeatureFromString(hDev, "ChunkSelector", "Framecounter"); /* Can the chunk feature be activated? */ isAvail = Pylon.DeviceFeatureIsWritable(hDev, "ChunkEnable"); if (isAvail) { /* Activate the chunk feature. */ Pylon.DeviceSetBooleanFeature(hDev, "ChunkEnable", true); } }
次にChunkParserを設定します、こいつがChunk dataをバラしてくれるみたい。
/* The data block containing the image chunk and the other chunks has a self-descriptive layout. A chunk parser is used to extract the appended chunk data from the grabbed image frame. Create a chunk parser. */ hChunkParser = Pylon.DeviceCreateChunkParser(hDev); if (!hChunkParser.IsValid) { /* The transport layer doesn't provide a chunk parser. */ throw new Exception("No chunk parser available."); }
画像取込後、取り込んだ画像にChunk dataが付加されているかを判定します、
以下は判定部分だけ抜粋、付加されていた場合の処理はelse以下に続きます。
/* Check to see if we really got image data plus chunk data. */ if (grabResult.PayloadType != EPylonPayloadType.PayloadType_ChunkData) { Console.WriteLine("Received a buffer not containing chunk data?"); } else
実際のChunk dataを取り出す処理です。(上記のelse以降に記述されている)
ChunkParserが設定されていれば、各Chunk dataは通常のパラメータと同様に、
Pylon.DeviceGetIntegerFeature等で値を取得出来るようですね、簡単。
ここではChunkFramecounterとChunkWidth、ChunkHeightの3つを読んでいますが、
ChunkWidthとChunkHeightは初期設定しなくても読めるのかな?、謎が残りました。
/* Retrieve the frame counter value. */ /* ... Check the availability. */ isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkFramecounter"); Console.WriteLine("Frame {0} {1} a frame counter chunk.", nGrabs, isAvail ? "contains" : "doesn't contain"); if (isAvail) { /* ... Get the value. */ long counter; counter = Pylon.DeviceGetIntegerFeature(hDev, "ChunkFramecounter"); Console.WriteLine("Frame counter of frame {0}: {1}.", nGrabs, counter); } /* Retrieve the chunk width value. */ /* ... Check the availability. */ isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkWidth"); Console.WriteLine("Frame {0} {1} a frame width chunk.", nGrabs, isAvail ? "contains" : "doesn't contain"); if (isAvail) { /* ... Get the value. */ chunkWidth = Pylon.DeviceGetIntegerFeature(hDev, "ChunkWidth"); Console.WriteLine("Width of frame {0}: {1}.", nGrabs, chunkWidth); } /* Retrieve the chunk height value. */ /* ... Check the availability. */ isAvail = Pylon.DeviceFeatureIsAvailable(hDev, "ChunkHeight"); Console.WriteLine("Frame {0} {1} a frame height chunk.", nGrabs, isAvail ? "contains" : "doesn't contain"); if (isAvail) { /* ... Get the value. */ chunkHeight = Pylon.DeviceGetIntegerFeature(hDev, "ChunkHeight"); Console.WriteLine("Height of frame {0}: {1}.", nGrabs, chunkHeight); }
但しChunk dataのCRC checksumだけは例外で、専用処理が要るようです、
bool hasCRC; /* Check the CRC checksum. */ hasCRC = Pylon.ChunkParserHasCRC(hChunkParser); if (hasCRC) { bool isOk = Pylon.ChunkParserCheckCRC(hChunkParser); Console.WriteLine("Frame {0} contains a CRC checksum. The checksum {1} ok.", nGrabs, isOk ? "is" : "is not"); }
まだ完全では無いけど、おおまかな流れは判りましたので、今回はここまで。