0

DigitalMicrograph の文字列変数の場合、「find」関数を使用して特定のパターンの位置を見つけることができます。

Number find( String str, String sub_str )

同じことをしたいのですが、画像データを使用します。たとえば、次のようにイメージを作成できます

image img := exprsize(1024, icol);

見つけたいパターンは

image pattern := exprsize( 15, icol+64 );

上記のケースでは、データに対するパターンのオフセットが列番号 64 にあることがわかっています。実際のケースでは、そのような単純なパターン (つまり、直線) はありません。「for」ループを使用した残忍なアプローチは確かに機能しますが、データ サイズが大きくなると、非常に遅くなります。誰もがより良い/エレガントな提案をしていますか? 1D画像の方が簡単かもしれませんが、2D画像はどうですか?

どうもありがとう!

4

3 に答える 3

2

数値データと完全に一致するものを効果的に探している場合、イメージ式を適切に使用することが解決への最も効率的な方法である可能性があります。あなたの例に大まかに続いて、ソースデータとターゲットパターンを設定することから始めます。

Image sourceData := RealImage("Source data", 4, 4096);
sourceData = Random();

Image targetPattern := RealImage("Target pattern", 4, 15);
targetPattern = sourceData.Index(icol + 1733, 0);

次に、単一の画像表現を使用して慎重に配置された検索バッファーを準備します。

Number targetSize = targetPattern.ImageGetDimensionSize(0);
Number searchBufferW = sourceData.ImageGetDimensionSize(0) - targetSize;
Image searchBuffer := RealImage("Search buffer", 4, searchBufferW, targetSize);
searchBuffer = sourceData.Index(icol + irow, 0);

これにより、ソース データの一致する可能性のあるすべてのサブセットが 2D 画像の垂直列に配置されます。最後に、ターゲット パターンに一致するものが存在する場合は、それを見つけるために少し画像計算を行います。

searchBuffer = Abs(searchBuffer - targetPattern.Index(irow, 0));
Image projectionVector := targetPattern.ImageClone();
projectionVector = 1.0;
Image searchResult := projectionVector.MatrixMultiply(searchBuffer);

Number posX, posY;
Number wasFound = (searchResult.Min(posX, posY) == 0);
String resultMsg = (wasFound) ? "Pattern found at " + posX : "Pattern not found";
OKDialog(resultMsg);

最初の行は、ターゲット パターンに一致する検索バッファー列のすべてのピクセルで正確なゼロを生成します。検索バッファーを垂直方向に合計し、Min() 関数を使用してゼロを見つけると、一致の検索が高速化されます。

MatrixMultiply() を使用して急速な垂直合計射影を行うことに注意してください。これは、実数型 (4 バイト浮動小数点) のソース データに対してのみ機能します。ただし、任意の数値データ型に対してかなり迅速な結果が得られる、迅速なデータ プロジェクションに対するもう少し複雑なアプローチがあります。

1D データ セット内の 1D パターンについて示されていますが、このアプローチはおそらく、多次元検索バッファーと ImageDataSlice オブジェクトを使用したより高度なインデックス付けを使用することで、2D および 3D データ セット内の 1D および 2D パターンに拡張できます。別の質問の件名。

于 2016-01-17T21:23:00.263 に答える