📷 acA1300-30gc でROIを変えると撮影が止まる?と思ったら、中古個体が壊れていた話
― BaslerCameraSample のカラー対応テストが通らなかった原因を追う ―
Basler カメラを .NET で扱うためのサンプルとして BaslerCameraSample をメンテナンスしています。
今回 カラー対応を追加する過程で単体テストを拡充し、acA1300-30gcを用いてデバッグしていたところ、下図のように ROI(Height/OffsetY)変更設定だけがどうしても成功しない現象に遭遇しました。(!となっているテストは未サポートのパラメータに関するテストです。)
状況としては以下のとおり、
-
Widthの変更は成功するが、Heightを変えると 1 枚目の取得後に接続断 - 自分のコードだけでなく、pylon Viewer でも同じ動作
最初はacA1300-30gc 固有の ROI バグかと疑ったのですが、
同じ機種をもう一台用意して試してみたところ、そちらはまったく問題なく動作しました。
そして、最終的には「中古で買った一台目が壊れていた」という結論になりました。
それだけのことですが、**“機種の仕様と決めつける前に、個体不良を疑う”**という学びが得られたので、
本記事で調査の内容をまとめておきます。
同じ acA1300-30gc を使用している方や、ROI が正しく動かない方の参考になれば幸いです。
🎯 調査背景
今回の調査は次の作業中に発生しました。
- BaslerCameraSample の acA1300-30gc カラー対応
- 単体テストの整備(ROI テスト含む)
- Width ROI のテストは問題なく通過
- しかし Height ROI のテスト「だけ」が 必ず失敗
再現条件をよく調べるため pylon Viewer 単体で確認したところ、
アプリではなくカメラ側でストリームが停止していることが判明。
1フレームだけ画像を取得して、カメラが切断されてしまう現象が発生しました。
このため、ROI の詳細な調査を開始しました。
🔍 Height ROI の調査結果:954 未満で必ず落ちる
まず Height の単体調査。Inc=2であることに注意して少しづつ値を変えます。
調査方法:
- pylon Viewerを用いてカメラ接続
- Auto Gain/Exposure: OFF
- CenterX/Y: OFF
- OffsetX/Y: 0
-
Height = 964から 2 ずつ減らす - 連続撮影が安定する値 / 1フレーム後に落ちる値を記録
結果は次のとおり:
| Height | 挙動 |
|---|---|
| 964 | OK |
| 962 | OK |
| 960 | OK |
| 958 | OK |
| 956 | OK |
| 954 | OK(ここが境界) |
| 952 | ❌(1 フレーム後に必ず落ちる) |
| 950 以下 | ❌ |
✔ 結論
"この" acA1300-30gc では、Height ROI は 954 未満にすると必ず撮影が停止する。
954というのは中途半端な数字であり不思議な挙動ですが、本個体では 954行が内部読み出しブロックの下限になっていると推測しました(Inc=2は満たすが内部制約で破綻)
これは pylon Viewer 単体で再現するため、アプリ側で改善はできません。
🔍 OffsetY も調査した結果:6 以上で落ちる
Height の次に、OffsetY の挙動も調べました。こちらもInc=2であることに注意。
条件:
- pylon Viewerを用いてカメラ接続
- Height: 954(動作する最大値)
- OffsetY: 0, 2, 4, ..., 10
- 連続撮影が安定する値 / 1フレーム後に落ちる値を記録
結果:
| OffsetY | 挙動 |
|---|---|
| 0 | OK |
| 2 | OK |
| 4 | OK |
| 6 | ❌(1フレームも取得できず即落ち) |
| 8 | ❌ |
| 10 | ❌ |
✔ 結論
つまりこの個体では、
- Height を 954 未満にするだけで NG
- Height=954 でも、OffsetY を 6 以上にすると NG
という、かなり不自然な挙動になっていました。
考察(推測)
この結果から、まずはCCDが原因ではないかと考えました。
というのも、acA1300-30gc は 古い CCD(Sony ICX445)モデルで、
CMOS 世代の ace のように ROI が柔軟ではありません。
-
Height.Inc = 2として UI では設定できてしまう - しかし内部の 読み出しブロック(readout block) は 実質 954 ライン以上じゃないと動作しない
-
OffsetYも 読み出しブロック の境界を破ると内部バッファが破綻する
そのため、
設定としては受け付けられるが、内部処理が成立せずストリームが止まる → pylon が切断扱い
という挙動になります。
ここまで来ると、
acA1300-30gc という「機種固有の制約」なのか、それともこの「中古個体だけの不具合」なのか?
を切り分ける必要が出てきます。
追加調査:もう一台 acA1300-30gc を用意して比較
そこで、もう一台 acA1300-30gc を用意して、
まったく同じ条件・手順で試してみました。
結果
2 台目(別個体)の acA1300-30gc では、
- Height を 954 未満にしても 普通に連続撮影可能
- OffsetY を 6 以上にしても問題なく動作
- 最初の個体で再現していた「1フレームで止まる」現象は一切発生しない
という結果になりました。
つまり、
- 最初に使っていた acA1300-30gc(中古で購入した個体)が壊れていた
- 機種全体の仕様やファームのバグではなかった
という結論になりました。
単体テストも以下の通り、全部通っています。今までの苦労はいったい何だったのでしょうか。
どこが壊れていたのか?(推測)
センサー内部の詳細までは分かりませんが、
挙動から推測できるのは次のような状態です。
- 縦方向の読み出し(Vertical Shift)に関わる回路の一部が壊れている
- 特定の行数(Height)や開始位置(OffsetY)以降の画素を扱えない
- その結果、ROI を小さくしたり位置をずらすと読み出しが破綻し、GigE のストリームが停止してしまう
CCD 世代のカメラでは、垂直方向の読み出しだけ壊れるというトラブルは現実に起こります。
今回のように「Width は動くのに Height と OffsetY だけおかしい」という症状は、
まさにその典型パターンと言えます。
教訓
教訓1:中古のカメラは壊れていることがある
当たり前ですが、中古機や稼働時間の長いカメラは壊れることがあります。
使い続けていたものが壊れたことに気づくのは比較的容易ですが、中古機では最初から壊れているかもしれません。
今回、一台目だけを見ていたら、
- acA1300-30gc は Height を小さくするとダメなんだ
- OffsetY も 0/2/4 しか使えないんだ
と機種全体の仕様として誤解していた可能性があります。
教訓2:新しいカメラを使うときは単体テストを試すべき
もう一つ大きかったのは、
- BaslerCameraSample に単体テストを用意していたおかげで、中古で買ったカメラの異常にすぐ気づけた
という点です。
実務でも
- カメラを差し替えたとき
- 別の現場用に中古個体を追加購入したとき
などに、「同じコードでテストを流すだけで検品になる」という運用ができそうです。
🏁 まとめ
- acA1300-30gc で ROI を変えると撮影が止まる現象に遭遇した
- 最初は機種固有のバグを疑ったが、同じ機種をもう一台用意して比較することで、
「中古で買った一台目が壊れていた」ことが分かった - pylon Viewer 単体でも再現するかどうか、別個体でも試すかどうかは重要
- カメラ制御コード側では、機種固有の挙動を決めつけるのではなく、
- GenICam の Min/Max/Increment を尊重する
- 単体テストで ROI 設定〜画像取得までをカバーすることで、「壊れた中古個体」を含めて早期に検知できる
中古の産業用カメラを活用している方は、
こうした切り分け手順を一度どこかで通っておくと、後々かなり楽になると思います。
また、次回以降は単体テストから固定値を減らして、様々な機種に対応できる工夫や、カラー画像の取得方法について紹介していきます。
👨💻 筆者について
@MilleVision
産業用カメラ・画像処理システムの開発に関する情報を発信中。
pylon SDK × C# の活用シリーズを連載しています。
🛠 サンプルコード完全版のご案内
Qiita記事のサンプルをまとめた C#プロジェクト(単体テスト付き) を BOOTH で配布しています。
acA1300-30gcで動作確認済みです。(重要)
- 撮影・露光・ゲイン・フレームレート・ROI・イベント駆動撮影など主要機能を網羅
- WPFへの実装もフォロー
- 単体テスト同梱で動作確認や学習がスムーズ
- 記事更新に合わせてアップデート予定