オブジェクトのソート、分類、および選択

イントロダクション

オブジェクトのソート、分類、および選択は、しばしば機械ビジョン検査の重要な部分となる一般的なプログラミングタスクの3つの種類です。たとえば、検出されたオブジェクトをY座標でソートする方法、計算された特徴に基づいて正しいオブジェクトを決定する方法、または最大面積の領域を選択する方法などが考えられます。Aurora Vision Studioでは、設計上、それだけを行うフィルターは存在しません。代わりに、最大の柔軟性を確保するために、これらのタスクは次の2つのステップに分かれています:

  1. まず、興味の対象となるオブジェクトの特徴を記述する値(特徴)の配列を作成する必要があります。
  2. 次に、オブジェクトの配列と対応する値の配列の両方を適切なソート、分類、または選択フィルターに渡す必要があります。

このアプローチにより、プロジェクトごとに非常に具体的で、元のソフトウェアの作成者が予測していない基準も含め、任意の基準を使用できます。

配列の要素のソート

配列内のオブジェクトを座標の1つか他の計算された特徴によってソートする方法について考えてみましょう。 OCR用の文字の手動ソートの例でこれを示します。以下は、検出された文字領域のオーバーレイを持つ入力画像です:

順番がばらばらかもしれないセグメント化された文字。

この文字領域の配列を RecognizeCharacters フィルターに inCharacterSorting 入力を None に設定して渡した後、正しく認識された結果は "MAEPXEL" となりますが、順不同です。

次に、入力領域を質量中心のX座標でソートする以下のサンプルプログラム断片があります:

OCRに渡す前に左から右に領域をソート。

最終的な結果は "EXAMPLE" であり、正しく並んでいます。

配列の要素の分類

オブジェクトの分類の例はすでに最初のプログラム例で示されており、最初のプログラム:シンプルなブロブ解析の記事で、ブロブが専用のフィルター、ClassifyRegions によって長さの特徴で分類されました。 分類は、複数のオブジェクトを処理する多くのプログラムで共通のステップであり、Classify の一般的なフィルターグループが、さまざまな基準でオブジェクトを分類できます。 オブジェクトの分類の一般的なスキームは次のとおりです:

  1. オブジェクトを検出する – たとえば、テンプレートマッチングまたはセグメンテーション(ThresholdToRegion + SplitRegionIntoBlobs)を使用します。
  2. いくつかの特徴を計算する – たとえば、面積、伸長、平均輝度など。
  3. オブジェクトを分類する – Classify フィルターの1つを使用します。

ClassifyByRange フィルターの使用方法の一般的なアイデアは次のとおりです:

ClassifyByRange フィルターの使用例。

以下に、4つの要素があります:

  • 分類されるオブジェクトは、inArray 入力に接続されています。
  • オブジェクトに対応する値は、inValues 入力に接続されています。
  • inMinimum および inMaximum 入力は、値の許容範囲を定義します。
  • 3つの出力には、それぞれの値が範囲内にあるオブジェクト、範囲未満のオブジェクト、範囲を超えるオブジェクトを含む3つの配列が含まれています。

分類に使用できる他のフィルターには、ClassifyByPredicate (関連する実数値の代わりに関連するブール値(True / False)がある場合)、およびClassifyByCase (関連する実数値の代わりに対応するオブジェクトが属するクラスのインデックスがある場合)があります。

配列から要素を選択する

選択は、主に配列ではなく単一の値を生成することを意図しているため、ソートや分類とは異なります。 メーターの針の方向を見つける例を考えてみましょう:

メーターの針の方向を見つけるタスク。

ScanExactlyNStripes フィルターで円周(赤)に沿って検出された2つのセグメント(青)があります。 この段階では2つのセグメントの配列がありますが、どちらが小さいか、どちらが大きいかはわかりません。この情報は方向(緑)を決定するために必要です。

この問題を解決するには、SegmentLength フィルターを使用してセグメントの長さの配列を計算し、次にGetSortedElements フィルターを使用して適切な要素を取得します。このフィルターは、最初の出力には小さい要素を、2番目の出力には大きい要素を生成します(下の画像を参照)。 代替として、2つの別々のフィルター、GetMinimumElementGetMaximumElement を使用することもできます。

小さいセグメントと大きいセグメントを選択するための解決策。

複数の個々のオブジェクトから1つのオブジェクトを選択する

配列ではなく複数の個々のオブジェクトから選択する場合があります。 たとえば、あるチェックボックスがチェックされているかどうかに応じて、HMIで表示する2つの画像から1つを選択したい場合があります。そのような場合は、2つのオブジェクトを入力として受け取り、inCondition 入力によって選択されるオブジェクトを出力する ChooseByPredicate フィルターを使用することが推奨されます。

警告: 効率のために、ChooseByPredicate フィルターは、2つの入力オブジェクトを長い計算なしに取得できる場合にのみ使用する必要があります。 1つの値を計算するための2つの代替方法がある場合は、バリアントマクロフィルター を代わりに使用する必要があります。

ChooseByPredicate フィルターは、C/C++ プログラミング言語の三項演算子 (?:) に非常に似ています。

ループ内でのオブジェクトの選択

さらなるケースとして、異なるイテレーションで表示されるオブジェクトから1つのオブジェクトを選択することが挙げられます。配列と同様に、ここでも関連する基準が必要です。これは実数、ブール値、または条件値の状態となります。利用可能なフィルターは以下の通りです:

  • LoopMaximum – 関連する値が最も高かったオブジェクトを選択します。
  • LoopMinimum – 関連する値が最も低かったオブジェクトを選択します。
  • LastMarkedObject – 関連するブール値がTrueである最も新しいオブジェクトを選択します。
  • LastNotNil – 実際に存在した(Nilと異なる)最も新しいオブジェクトを選択します。