更新履歴(初版のみ・2026年11月01日公開)
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.23851414)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「GigE Vision・USB3 Visionカメラの取りこぼし ── 原因の切り分けとWindows側の設定」合同会社小村ソフト. https://doi.org/10.5281/zenodo.23851414 https://comcomponent.com/blog/gige-usb3-vision-camera-frame-drops-windows/
- DOI(最新版)
- 10.5281/zenodo.23851414
- DOI(この版)
- 10.5281/zenodo.23851416
検査装置で産業用カメラの画像がときどき抜ける、SDKのビューアーでは「不完全な画像」や「再送要求」の数が少しずつ増えていく。この記事では Windows で GigE Vision や USB3 Vision のカメラを使うときの取りこぼしについて、起きた場所の分け方と Windows 側で見直す設定を説明します。
画像の取りこぼし(フレームドロップ)はカメラからアプリまでの経路のどこかで起きます。どこで起きたかは、SDKのストリーム統計、Windowsのアダプター統計、アプリが受け取った画像の番号を突き合わせると分けられます。場所ごとに効く設定が違うので、先に数えて場所を絞り、それから設定を1つずつ変えて比べます。
この記事は Windows 10/11 の PC に GigE Vision または USB3 Vision のカメラをつなぎ、メーカーのSDK(GenICam 準拠のもの)で画像を受け取る構成を対象にします。手順と設定はカメラメーカーと Microsoft の資料に基づくもので、特定の機種で測った結果を載せたものではありません。設定項目の名前や推奨値はメーカー・機種・ドライバーごとに違うので、お使いの製品の資料と合わせて読んでください。
画像がアプリに届くまでの経路
カメラが撮った画像は、カメラの中、伝送路、PCの受信側、SDKのバッファを通ってアプリに届きます。GigE Vision では伝送路が LAN ケーブルとスイッチで、PC で受けるのは NIC です。USB3 Vision では伝送路が USB ケーブルとハブで、PC で受けるのはホストコントローラーです。
flowchart TB
accTitle: カメラからアプリまでの画像の経路
accDescr: カメラの画像が、GigE VisionではスイッチとNIC、USB3 VisionではハブとUSBホストコントローラーを通り、ドライバーとSDKのバッファを経てアプリに届く流れを示す。
CAM["カメラ(撮影と送信)"]
CAM --> G1["LANケーブル・スイッチ"]
CAM --> U1["USBケーブル・ハブ"]
G1 --> G2["NIC"]
U1 --> U2["USBホストコントローラー"]
G2 --> DRV["ドライバー"]
U2 --> DRV
DRV --> BUF["SDKの受信バッファ"]
BUF --> APP["アプリの画像処理"]
図1: 画像はカメラ、伝送路、NICかホストコントローラー、ドライバー、SDKのバッファを通ってアプリに届く。
それぞれの場所で、取りこぼしは違う形で現れます。
- カメラの中で撮れなかった画像は、PCの設定をどう変えても戻りません。たとえば、トリガーの間隔が露光と送信にかかる時間より短いと、撮れない画像が出ることがあります。機種によってはカメラ側で取りこぼしを数えているので、カメラのマニュアルで確かめます。
- 伝送路で欠けた場合、GigE Vision ではパケットの再送で埋められることがあります。埋められなければ、その画像は不完全な画像として扱われます。
- NIC では、受信バッファが一杯になると届いたパケットが捨てられます。Microsoft は、受信バッファが小さいとパケットが捨てられ性能が落ちると説明しています1。
- SDKのバッファがすべてアプリに使われていると、次の画像を入れる場所がありません。
- アプリが「最新の画像だけを受け取る」設定なら、古い画像は設計どおりに捨てられます。
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全13件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
欠けた場所を統計で分ける
設定を変える前に、どこで欠けているかを数えます。数を見ずに設定を変えると、効いたかどうかも、ほかの場所に問題が移っただけかどうかも判断できません。
SDKのストリーム統計
カメラメーカーのSDKは受信の統計をカウンタとして持っています。Basler の pylon Viewer では、カメラを選んでストリームのパラメーターの「Statistics」を開くと見られます2。pylon の API には送った再送要求の数を表す Statistic_Resend_Request_Count のようなカウンタがあります3。
名前はSDKごとに違いますが、たいてい次のような数を持っています。
- 受け取った画像の数
- パケットが欠けたまま届いた、不完全な画像の数
- 再送を要求したパケットの数
- バッファが足りずに捨てた画像の数
どのカウンタが何を数えているかは、使っているSDKの資料で確かめてください。
画像の番号の飛び
GigE Vision の画像データにはブロックIDという番号が付いています4。SDKはこの番号や、カメラが付けたフレームの番号をアプリに渡します。アプリが受け取った番号が飛んでいれば、アプリに届く前のどこかで画像が欠けています。番号の幅や、取得を始め直したときに番号がどう戻るかはSDKと機種によるので、資料で確かめます。
Windowsのアダプター統計
GigE Vision では、NIC が捨てたパケットの数を Windows の側からも見られます。Get-NetAdapterStatistics はブロードキャスト、マルチキャスト、破棄、エラーの数を返します5。カメラ用の NIC の名前を指定して、全項目を表示します。
Get-NetAdapterStatistics -Name "Camera1" | Format-List -Property *
受信で捨てた数(ReceivedDiscardedPackets など)が、取りこぼしと同じ時間帯に増えていれば、NIC で捨てられています。
flowchart TB
accTitle: 取りこぼしの場所を分ける手順
accDescr: アプリが受け取った画像の番号の飛びとSDKの統計とWindowsのアダプター統計から、取りこぼしが伝送路、PCの受信側、アプリ側、カメラ側のどこで起きたかを分ける手順を示す。
A["画像の番号が飛んでいるか"]
A -->|"飛んでいる"| B["SDKの統計でどの数が増えたか"]
A -->|"飛んでいない"| F["カメラの撮影条件を見る"]
B -->|"再送要求・不完全な画像"| C["NICの破棄の数も増えたか"]
B -->|"バッファ不足で捨てた数"| E["アプリの処理とバッファの数を見直す"]
B -->|"どれも増えていない"| L["最新だけを受け取る設定か見る"]
C -->|"増えた"| D1["NICの設定を見直す"]
C -->|"増えていない"| D2["伝送路(帯域・スイッチ)を見直す"]
図2: 画像の番号、SDKの統計、NICの破棄の数を順に見て、取りこぼしの場所を絞る。
番号が飛んでいないのにトリガーの数より画像が少ないときは、カメラがその分を撮っていない可能性があります。番号が飛んでいるのにSDKの統計のどれも増えていないときは、SDKが最新の画像だけを渡す設定になっていないかを確かめます(後の「SDKのバッファの数と受け取り方」)。
NIC の破棄の数が増えていなくても、スイッチの中でパケットが捨てられていることがあります。図2の分け方は目安なので、場所を決めるときは次の節の帯域の計算と合わせて見ます。
GigE Visionの帯域と再送
送る量と帯域
1 Gbps のリンクで運べるのは、計算上 1 秒に 125 MB(1,000,000,000 ÷ 8 バイト)です。実際には Ethernet・IP・UDP・GigE Vision のヘッダーがパケットごとに付くので、画像に使える量はこれより少なくなります。
カメラが送る量は、幅 × 高さ × 1画素のバイト数 × フレームレートで計算できます。たとえば 1920 × 1200 画素、Mono8(1画素1バイト)、50 fps なら、1920 × 1200 × 1 × 50 = 115,200,000 バイト、つまり毎秒約 115 MB です。1 Gbps のリンクに計算上は収まりますが、ヘッダーの分を考えると余裕はほとんどありません。
同じカメラを2台スイッチにつなぎ、PCとはスイッチから1本のリンクで結ぶと、2台で毎秒約 230 MB を1本のリンクに流すことになります。これは 1 Gbps のリンクに収まらないので、NIC の設定をどう変えても取りこぼしは止まりません。Basler は、カメラごとに NIC のポートを分ければ各カメラがリンクの帯域を使えるが、スイッチを使うとカメラ同士が PC への1本のリンクを分け合うと説明しています6。
flowchart TB
accTitle: スイッチ経由で2台のカメラが帯域を分け合う構成
accDescr: 2台のカメラがそれぞれ毎秒約115MBを送り、スイッチからPCのNICへの1本のリンクで合計約230MBになり、1Gbpsのリンクに収まらないことを示す。
C1["カメラ1(毎秒約115MB)"] --> SW["スイッチ"]
C2["カメラ2(毎秒約115MB)"] --> SW
SW -->|"合計 毎秒約230MB"| NIC["PCのNIC(1Gbps)"]
NIC -.-> NOTE["125MBを超えるので設定では直らない"]
図3: スイッチからPCへのリンクは1本なので、2台の送る量の合計がそのリンクに収まる必要がある。
収まらないときは、フレームレートを下げる、ROI(画像の一部だけを切り出して送る範囲)を狭める、カメラごとに NIC のポートを分ける、10GigE などの速いリンクに替える、のどれかで送る量か運べる量を変えます。
パケットの間隔と送信の開始時刻
複数のカメラに同じトリガーを入れると、各カメラが同時に送り始めます。スイッチや NIC のバッファがこの重なりを受けきれないと、パケットが捨てられます。Basler はこの場合にパケットの間隔(Inter-Packet Delay)を広げることと、フレームの送信開始を遅らせる設定(Frame Transmission Delay)を使うことを挙げています2。
flowchart TB
accTitle: 複数のカメラが同時に送るときのパケットの重なり
accDescr: 同じトリガーで2台のカメラが同時に送るとスイッチやNICのバッファがあふれてパケットが捨てられ、パケットの間隔を広げるか送信開始をずらすと重なりが減る代わりに最大フレームレートが下がることを示す。
A["同じトリガーで2台が同時に送る"] --> B["スイッチで送信が重なる"]
B --> C["スイッチやNICのバッファがあふれる"]
C --> D["パケットが捨てられる"]
A -.-> E["パケットの間隔を広げる・送信開始をずらす"]
E -.-> F["重なりが減る"]
F -.-> G["最大フレームレートは下がる"]
図4: 同時に送り始めたカメラのパケットが重なるとバッファがあふれるので、間隔や開始時刻をずらして重なりを減らす。
パケットの間隔を広げると、1枚の画像を送り終えるまでの時間が延びます。そのため、間隔は必要なフレームレートが出る範囲で広げます。間隔を最大にすると、カメラが出せる最大のフレームレートが下がります2。
パケットの大きさとJumbo Packet
GigE Vision の画像はパケットに分けて送られます。パケットが大きいほどヘッダーの割合が減り、PC が処理するパケットの数も減ります。Basler は NIC の Jumbo Frames を最大にし、カメラのパケットの大きさを NIC の値以下にすることを勧めています。切り分けのときは、NIC とカメラの両方を 1500 にして始めると確実だとも書いています2。
大きなパケットは、カメラ・スイッチ・NIC のすべてが同じ大きさに対応していないと通りません。スイッチの対応はスイッチの仕様書で確かめます6。
再送で埋められる範囲
GigE Vision は画像を UDP で送ります。制御には GVCP という UDP のプロトコルを使い、PC から欠けたパケットの再送を要求できます7。Basler のフィルタードライバーは、パケットが届かないまま PacketTimeout の時間が過ぎると再送を要求し、続けて欠けた複数のパケットは1つの要求にまとめます3。
sequenceDiagram
accTitle: GigE Visionのパケット再送の流れ
accDescr: カメラが送ったパケットの一部が途中で失われ、PCのドライバーが待ち時間を過ぎてから再送を要求し、間に合えば画像がそろい、間に合わなければ不完全な画像になる流れを示す。
participant C as カメラ
participant P as PCのドライバー
C->>P: パケット1、2
C--xP: パケット3(途中で失われる)
C->>P: パケット4
Note over P: 待ち時間を過ぎてもパケット3が届かない
P->>C: パケット3の再送要求
C->>P: パケット3を再送
Note over P: 間に合えば画像がそろい、間に合わなければ不完全な画像になる
図5: 欠けたパケットはドライバーが再送を要求して埋めるが、間に合わなければその画像は不完全な画像になる。
再送したパケットも同じリンクを通ります。帯域が足りずにパケットが捨てられているときは、再送の分だけさらに帯域を使います。再送要求の数が増え続けているなら、再送の設定を変える前に、前の節の帯域の計算に戻ります。
WindowsのNIC設定を変える
変更前の値を記録する
NIC の詳細設定を変えると、多くの項目はアダプターを再起動しないと反映されません。Set-NetAdapterAdvancedProperty は、-NoRestart を付けない限り、変更後にアダプターを再起動します8。再起動の間はカメラとの通信が切れるので、装置を止めてから作業します。
先に、今の値をすべてファイルに残します。元に戻すときはこのファイルを見ます。
Get-NetAdapterAdvancedProperty -Name "Camera1" |
Select-Object DisplayName, DisplayValue, RegistryKeyword, RegistryValue |
Export-Csv -Path .\Camera1-advanced-before.csv -NoTypeInformation -Encoding UTF8
画面の表示名(DisplayName)はドライバーごとに違います。Windows はよく使う項目に共通のキーワードを決めていて、名前が * で始まります9。キーワードで探すと、表示名が違うドライバーでも同じ項目を見つけられます。設定できる範囲もここで確かめます。
Get-NetAdapterAdvancedProperty -Name "Camera1" -RegistryKeyword "*JumboPacket", "*ReceiveBuffers", "*InterruptModeration" |
Select-Object DisplayName, DisplayValue, RegistryKeyword, ValidRegistryValues, NumericParameterMinValue, NumericParameterMaxValue
受信に関わる3つの項目
カメラ用の NIC で見直す項目は、主に次の3つです。
| キーワード | 画面の名前の例 | 中身 | カメラメーカーの勧め |
|---|---|---|---|
*JumboPacket |
Jumbo Packet | 送受信できる最大のフレームの大きさ。既定は1514バイトで、上限はNICによる10 | 最大にする2 |
*ReceiveBuffers |
Receive Buffers、Receive Descriptors | 受信に使う記述子の数。小さいと負荷が高いときに受信バッファが尽きる10 | 最大にする2 |
*InterruptModeration |
Interrupt Moderation | 割り込みをまとめて減らす機能の有効・無効11 | 無効にするか、最も弱くする2 |
Microsoft も受信の多い使い方では受信バッファを最大にすることを勧めています。Interrupt Moderation を切ると遅延は減りますが、CPU の使用量が増えるという引き換えがあります1。
1項目を変えるときは、確かめた範囲の中の値を指定します。次の例は受信バッファを変えるもので、2048 は例です。お使いの NIC の ValidRegistryValues か最大値に合わせてください。
Set-NetAdapterAdvancedProperty -Name "Camera1" -RegistryKeyword "*ReceiveBuffers" -RegistryValue 2048
各項目の意味と、変えたときの得失は「Windows NIC詳細設定ガイド」に詳しく書いています。
flowchart TB
accTitle: NICの設定を1項目ずつ変えて比べる手順
accDescr: 変更前の値を記録し、1項目だけ変え、同じ条件で取りこぼしを数え、減ったら残し、減らなければ元に戻して次の項目に進む繰り返しを示す。
R["変更前の値をCSVに残す"] --> S["1項目だけ変える"]
S --> M["同じ条件・同じ時間で取りこぼしを数える"]
M --> J["取りこぼしが減ったか"]
J -->|"減った"| K["その値を残す"]
J -->|"減らない"| B["元の値に戻す"]
K --> N["次の項目へ"]
B --> N
N --> S
図6: 設定は1項目ずつ変え、取りこぼしの数を比べて残すか戻すかを決める。
メーカーのドライバーとNICに結び付けるプロトコル
カメラメーカーは GigE Vision の受信を軽くするドライバーと、NIC を一括で設定するツールを用意していることがあります。Basler は pylon のフィルタードライバーと GigE Configurator を組み合わせて使うことを勧めています6。
Basler は手で設定する場合、カメラ用の NIC のプロパティで pylon のドライバーと IPv4 以外のプロトコルとサービスのチェックを外すとしています6。外す前に、その NIC をカメラ以外の通信に使っていないかを確かめます。
ファイアウォール
Basler は、ファイアウォールが有効だとイベント通知が届かなかったり、画像の受信が不安定になったりすると説明しています。そのうえで、カメラ用の接続ではファイアウォールを切ることを勧め、残す場合はアプリごとに受信の規則を足す方法などを挙げています6。社内の方針でファイアウォールを残す場合は、規則を足す方法を取ります。規則の作り方は「Windowsファイアウォールと業務アプリ」にまとめています。
電源の設定
Microsoft はマイクロ秒単位の遅延が問題になるネットワーク向けに、BIOS を高パフォーマンスにして C ステートを無効にすることと、OS の電源プランを高パフォーマンスにすることを挙げています1。どちらも消費電力と引き換えです。ここまでの項目を見直しても取りこぼしが残るときに、検査専用の PC で試します。
USB3 Visionの帯域と接続
ホストコントローラーを分ける
USB3 Vision は画像をUSBのバルク転送のエンドポイントで送ります12。Windows はバルク転送に帯域を保証して割り当てないので、1つのホストコントローラーにつながった機器は、その帯域を分け合います13。同じコントローラーの下にほかのカメラや外付けディスクがあると、カメラが使える帯域が減ります。
Basler は USB 3.0 のポートにつなぐことを強く勧め、これまでに問題なく使えたホストコントローラーのチップとして Renesas、Fresco Logic、ASMedia を挙げています14。コントローラーごとの最大帯域を測ったアプリケーションノートも出しています15。
どのポートがどのコントローラーにつながっているかは、デバイスマネージャーの「表示」メニューで「デバイス (接続別)」を選ぶと、ツリーで確かめられます。カメラが複数あるときは、カメラごとにコントローラーを分けるか、PCIe の USB 拡張カードを足します。
flowchart TB
accTitle: USBホストコントローラーとカメラのつなぎ方
accDescr: 1つのホストコントローラーにハブを介してカメラと外付けディスクがつながると帯域を分け合い、カメラごとにコントローラーを分けると各カメラがその帯域を使えることを示す。
subgraph shared ["分け合う構成"]
HC1["コントローラー1"] --> HUB["ハブ"]
HUB --> CA["カメラA"]
HUB --> DISK["外付けディスク"]
end
subgraph split ["分ける構成"]
HC2["コントローラー2"] --> CB["カメラB"]
HC3["コントローラー3(拡張カード)"] --> CC["カメラC"]
end
shared ~~~ split
図7: 同じコントローラーの下の機器は帯域を分け合うので、カメラごとにコントローラーを分ける。
ケーブルが長すぎるときや、規格に合わない延長をしているときも、転送が不安定になることがあります。メーカーが指定するケーブルを使い、つなぎ直しても直らないときはケーブルを替えて比べます。
セレクティブサスペンド
USBのセレクティブサスペンドは使っていない機器のポートを個別に止めて電力を減らす機能です。Microsoft は既定で有効にしており、ドライバー開発者向けの資料で無効にしないよう強く勧めています16。
一方で JAI は、動作していた USB3 カメラが急に画像を送らなくなり、フレームレートが 0 fps になる症状について、Windows が USB3 のカードを省電力の状態に切り替えたことが原因の可能性があるとしています。そのうえで、電源プランの詳細設定にある「USB設定」でセレクティブサスペンドを無効にする手順を挙げています17。試すときは、検査専用の PC で、使っている電源プランの「USBのセレクティブサスペンドの設定」を電源接続時・バッテリー時とも無効にします。変える前と後で、止まるまでの時間や取りこぼしの数を記録して比べます。効果が見られなければ元に戻します。
アプリの受信バッファと処理
SDKのバッファの数と受け取り方
SDKは画像を入れるバッファをいくつか用意し、受信した画像を順に入れてアプリに渡します。Basler の pylon ではバッファの数を MaxNumBuffer で決めます18。
受け取り方も選べます。pylon の OneByOne はすべての画像を順に渡し、バッファがあふれたときだけ画像を捨てます19。LatestImageOnly は最新の画像だけを残し、古い画像は捨てます18。表示用には LatestImageOnly が向いていますが、検査で全数を処理したいなら OneByOne のように全部を渡す方式にします。全数を処理したいのに最新だけを受け取る設定になっていると、ほかの場所をどれだけ直しても、アプリの中で画像が捨てられ続けます。
flowchart TB
accTitle: pylonの2つの受け取り方の違い
accDescr: 受信した画像を、OneByOneはすべて順に渡してバッファがあふれたときだけ捨て、LatestImageOnlyは最新だけを残して古い画像を捨てることを示す。
R["受信した画像"] --> S{"受け取り方"}
S -->|"OneByOne"| O["すべてを順に渡す"]
S -->|"LatestImageOnly"| L["最新だけを残す"]
O -.-> O2["バッファがあふれたときだけ捨てる"]
L -.-> L2["古い画像は捨てる"]
図8: 検査で全数を処理するなら、すべてを順に渡す受け取り方にする。
受け取る処理と検査の処理を分ける
画像が届いたときに呼ばれる処理(コールバック)の中で検査まで行うと、その間はバッファがアプリに使われたままになります。検査に時間がかかる画像が続くと、空いたバッファがなくなり、次の画像を入れる場所がなくなります。
受け取る処理では画像を写して検査用のキューに入れるだけにし、SDKのバッファをすぐ返します。検査は別のスレッドで行います。キューが一杯で入れられなかったときは、その数を数えて記録します。こうすると、処理が追いつかずに捨てた画像が、ほかの原因の取りこぼしと分けて見えるようになります。
flowchart TB
accTitle: 受け取る処理と検査の処理を分ける構成
accDescr: SDKのコールバックが画像を写してキューに入れ、すぐバッファを返し、キューが一杯なら捨てた数を数え、別のスレッドがキューから取り出して検査する構成を示す。
SDK["SDKのコールバック"] --> CP["画像を写す"]
CP --> RET["SDKのバッファを返す"]
CP --> Q{"キューに空きがあるか"}
Q -->|"ある"| QUEUE["検査用のキュー"]
Q -->|"ない"| CNT["捨てた数を数える"]
QUEUE --> W["検査スレッド"]
図9: 受け取る処理は画像を写してバッファを返すだけにし、検査は別のスレッドで行う。
次のC#のコードはこの構成の骨組みです。SDKのコールバックから OnFrameReceived を呼ぶ想定で、SDK固有の呼び出しは省いています。番号の飛びと、キューが一杯で捨てた数を別々に数えます。
using System;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
public sealed record CapturedFrame(ulong FrameId, byte[] Pixels);
public sealed class FramePipeline
{
private readonly Channel<CapturedFrame> _queue =
Channel.CreateBounded<CapturedFrame>(new BoundedChannelOptions(capacity: 8)
{
SingleReader = true,
SingleWriter = true,
FullMode = BoundedChannelFullMode.Wait,
});
private ulong? _lastFrameId;
private long _missingCount; // 番号が飛んだ数(アプリに届く前に欠けた画像)
private long _queueFullCount; // キューが一杯で捨てた数(検査が追いつかなかった画像)
// SDKのコールバックから呼ぶ。ここでは検査をしない。
public void OnFrameReceived(ulong frameId, ReadOnlySpan<byte> pixels)
{
if (_lastFrameId is ulong last && frameId > last + 1)
{
Interlocked.Add(ref _missingCount, (long)(frameId - last - 1));
}
_lastFrameId = frameId;
// 写してから戻れば、呼び出し元はSDKのバッファをすぐ返せる。
var frame = new CapturedFrame(frameId, pixels.ToArray());
if (!_queue.Writer.TryWrite(frame))
{
Interlocked.Increment(ref _queueFullCount);
}
}
public async Task RunInspectionAsync(Func<CapturedFrame, Task> inspect, CancellationToken cancellationToken)
{
await foreach (var frame in _queue.Reader.ReadAllAsync(cancellationToken))
{
await inspect(frame);
}
}
public (long Missing, long QueueFull) ReadCounters() =>
(Interlocked.Read(ref _missingCount), Interlocked.Read(ref _queueFullCount));
}
BoundedChannelFullMode.Wait の有界チャネルでは、一杯のときに TryWrite が false を返すので、コールバックは待たずに戻ります。番号が戻ったとき(取得を始め直したときなど)は飛びとして数えません。画像を毎回 ToArray で写すと、そのたびにメモリを確保します。フレームレートが高く、ガベージコレクションの停止が気になる場合は、ArrayPool<byte> などで確保したバッファを使い回します。
キューの容量(例では8)は、検査の時間がばらついても吸収できる枚数にします。検査の平均時間がフレームの間隔より長いなら、キューをいくら大きくしてもいつかは一杯になります。その場合は検査を並列にするか、検査の処理を速くする必要があります。
設定を変えて比べる手順
取りこぼしは数分では出ず、数時間に一度だけ出ることもあります。比べるときは、条件と時間をそろえて数えます。
- 本番と同じカメラの設定(解像度、画素形式、フレームレート、トリガー)で、決めた時間だけ画像を取得します。SDKの統計、NIC の破棄の数、アプリの番号の飛びとキューで捨てた数を、始めと終わりに記録します。
- 画素数・1画素のバイト数・フレームレートから送る量を計算し、リンクやホストコントローラーの帯域に収まるかを確かめます。収まらなければ、設定を変える前に構成を見直します。
- 統計から絞った場所に対応する設定を、1項目だけ変えます。NIC の設定を変える前には、今の値を CSV に残します。
- 手順1と同じ条件・同じ時間で取得し、同じ数を記録します。
- 取りこぼしが減っていれば値を残し、減っていなければ元に戻して次の項目に進みます。
flowchart TB
accTitle: 取りこぼし対策を比べる手順
accDescr: 本番と同じ条件で基準の数を記録し、帯域を計算し、収まらなければ構成を見直し、収まれば1項目だけ変えて同じ条件で数え、結果で残すか戻すかを決める手順を示す。
A["本番と同じ条件で基準の数を記録"] --> B["送る量と帯域を計算"]
B --> C["帯域に収まるか"]
C -->|"収まらない"| D["構成を見直す(送る量か経路を変える)"]
C -->|"収まる"| E["統計で絞った場所の設定を1項目変える"]
D --> A
E --> F["同じ条件・同じ時間で数える"]
F --> G["残すか元に戻すかを決める"]
図10: 帯域に収まることを確かめてから、設定を1項目ずつ変えて同じ条件で比べる。
1回の取得で取りこぼしが出なかったことは、その設定で出ないことの証明にはなりません。間隔をあけて出る症状なら、変更の前後で取得の時間を十分に長くし、何回か繰り返して比べます。
関連記事
- Windows NIC詳細設定ガイド - RSS/LSO/EEE/Wake on LAN
- TCP再送で産業用カメラ通信が止まる原因と切り分け
- 産業用カメラ長期稼働クラッシュ調査 - ハンドルリーク編
- WindowsアプリでUSB機器を扱う方法
- Windowsファイアウォールと業務アプリ
参考リンク
-
Microsoft Learn, Network Adapter Performance Tuning in Windows Server. 受信バッファ、Interrupt Moderation、低遅延のための電源設定の説明。 ↩ ↩2 ↩3
-
Basler, How to troubleshoot lost packets or frames while using GigE cameras. NIC とカメラの設定による取りこぼし対策。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7
-
Basler, PLStream (pylon .NET API). フィルタードライバーの再送と統計のパラメーター。 ↩ ↩2
-
Wireshark, Display Filter Reference: GigE Vision Streaming Protocol. GVSP のブロックIDとパケットIDのフィールド。 ↩
-
Microsoft Learn, Get-NetAdapterStatistics. ネットワークアダプターの破棄とエラーを含む統計の取得。 ↩
-
Basler, Network Configuration (GigE Cameras). NIC の設定、ファイアウォール、複数カメラの構成。 ↩ ↩2 ↩3 ↩4 ↩5
-
Wireshark, Display Filter Reference: GigE Vision Control Protocol. GVCP のフィールドと再送コマンドへの対応。 ↩
-
Microsoft Learn, Set-NetAdapterAdvancedProperty.
-NoRestartとアダプターの再起動。 ↩ -
Microsoft Learn, Standardized INF Keywords for Network Devices.
*で始まる共通のキーワード。 ↩ -
Microsoft Learn, Keywords That Can Be Edited.
*JumboPacketと*ReceiveBuffersの定義。 ↩ ↩2 -
Microsoft Learn, Enumeration Keywords.
*InterruptModerationの定義。 ↩ -
Pleora Technologies, USB3 Vision. USB3 Vision のストリーミングがバルクのエンドポイントを使うこと。 ↩
-
Microsoft Learn, USB Bandwidth Allocation. バルク転送には保証された帯域が割り当てられず、性能がほかの機器の帯域の割り当てに左右されること。 ↩
-
Basler, Hardware Installation (USB 3.0 Cameras). USB 3.0 のポートとホストコントローラーのチップ。 ↩
-
Basler, Maximum Bandwidth Measurements of USB 3.0 Host Controllers. ホストコントローラーごとの最大帯域の測定。 ↩
-
Microsoft Learn, USB Selective Suspend. セレクティブサスペンドの仕組みと、無効にしないよう勧める記述。 ↩
-
JAI, USB3 cameras show 0 fps/black screen after few minutes of acquisition. USB3 カメラが 0 fps になる症状の原因の可能性と、電源プランでセレクティブサスペンドを無効にする手順。 ↩
-
Basler, pypylon Performance Optimization.
MaxNumBufferとLatestImageOnly。 ↩ ↩2 -
Basler, pypylon Image Acquisition.
OneByOneで画像を捨てる条件。 ↩
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
USBメモリの「安全な取り外し」は、今も必要なのか? ── 「クイック取り外し」と書き込みキャッシュから考える
USBの安全な取り外しが必要かを、クイック取り外しと高パフォーマンスの違いから判断します。書き込みキャッシュの仕組み、設定確認、取り外しの手順、「使用中」で外せない場合の対処と完了確認を説明します。
CPU使用率は低いのに音が途切れるのはなぜ? ── バッファと締め切りから考える
CPU使用率は低いのに音が途切れる理由を、バッファと補充の締め切りから説明します。対象環境、条件を一つずつ変える手順、WPR・WPAによる記録と確認、改善を原因の確定と混同しない判断基準をまとめます。
回線は速いのにRDPが重いのはなぜ? ── 入力・描画・通信を分けて調べる
回線は速いのにRDPの入力やスクロールが遅いときの切り分け手順です。入力待ち・画面処理・通信を区別し、症状別の比較、性能カウンターの測定範囲、設定を戻した確認、調査の引き継ぎを説明します。
ネットは使えるのに「インターネットなし」?── WindowsのNCSI・DNS・プロキシ・VPNを切り分ける
ネットは使えるのにWindowsが「インターネットなし」と表示する理由を、NCSIの接続判定から解説します。DNS・プロキシ・VPN・認証Wi-Fiを、設定変更前の確認コマンドとイベントログで切り分けます。
Windowsの名前解決の順序 ── hosts・DNSキャッシュ・LLMNR/mDNS・DoH
「名前解決できない」「一部のPCだけ繋がらない」は、hosts・DNSキャッシュ・DNSサーバー・LLMNR/mDNSのどの層が答えたかで結果が変わります。Windowsの名前解決の順序とDoHが変えるものを仕組みから整理し、層ごとに切り分ける手順を解説します。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
不具合調査 / 長期稼働テーマ
再現しにくい不具合、通信停止、長期稼働障害、失敗パス検証を整理するトピックです。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
不具合調査・原因解析
画像の取りこぼしはカメラ・伝送路・Windowsの受信・SDKのバッファ・アプリの処理のどこで起きたかを統計で分ける調査になるので、不具合調査・原因解析として進めやすい題材です。
Windowsアプリ開発
受信と画像処理を分けるスレッド構成や、取りこぼしを数えて記録する作りは、検査アプリの設計から見直すと入れやすくなります。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- GigE Visionカメラの画像がときどき欠けるとき、最初に何を見ればよいですか?
- SDKのストリーム統計と、アプリが受け取った画像の番号の飛びを見ます。パケットの再送要求や不完全な画像が増えていれば伝送路かPCの受信側、バッファ不足で捨てた数が増えていればアプリ側の処理を疑います。カウンタの名前はSDKごとに違うので、使っているSDKの資料で対応を確かめます。
- NICのJumbo PacketやReceive Buffersは最大にすればよいですか?
- BaslerなどのカメラメーカーはJumbo Packetと受信バッファを大きくし、Interrupt Moderationを弱めることを勧めています。ただしJumbo Packetはカメラ・スイッチ・NICのすべてが同じ大きさに対応している必要があります。変更前の値を記録し、1項目ずつ変えて、取りこぼしの数を同じ条件で比べます。
- USB3 Visionカメラが数分で止まったり、フレームが落ちたりします。
- 同じホストコントローラーにほかの機器やハブがつながっていないか、ケーブルとポートが規格どおりかを先に確かめます。USBのセレクティブサスペンドを無効にする手順を挙げるカメラメーカーもあります。Microsoftはドライバー開発者向けに無効化を勧めていないので、検査専用のPCで試して効果を記録します。
- 設定をいくら変えても取りこぼしが減りません。
- カメラが送る量が経路の帯域を超えていると、設定では直りません。画素数・1画素のバイト数・フレームレートから必要な帯域を計算し、1本のリンクやホストコントローラーに収まるかを確かめます。収まらなければ、フレームレートやROIを下げるか、カメラごとにNICやコントローラーを分けます。