ビルトインを使用できる(または独自に作成できる)場合は、これが部分的な解決策として私が考えていることです。
まず、画像を反転して、人物が白になり、背景が黒になるようにします。すべての行の合計を見つけます。
data = sum(im);
これにより、各行のオンピクセル数を示すノイズの多いデータが得られます。プロットすると、山は人であり、谷はそれらの間の領域です。しかし、多くの誤ったピークがあります。これを修正するには、次のような畳み込みを使用します。
data2 = conv(data,ones(1,50)/50,'same');
50のサイズはかなりうまくいくようでした。画像ごとに異なる場合がありますが、すべて上記のようになっている場合は、50が機能するはずです。
これで、人々がいるピーク(特に人々の最高点)を示すクリーンなデータセットが得られるはずです。これらのピークを見つけるために、単一のforループを実行できます。ただし、谷を越えるまでは、次のピークを探し始めないでください。それが役立つ場合は、導関数を使用して、導関数がゼロを通過する場所を見つけることができます(これらは山と谷です)。
deriv = (data2(2:end)-data(1:end-1));
しかし、導関数には常に文字通りのゼロ点があるとは限らないことがわかりました。そのため、代わりに符号の変更を探す必要があります。
ピークを自動的に見つけるためにダウンロードできるパブリック関数もあります。
それで、あなたのピークがいくつかのベクトルピークに保存されているとしましょう。これで人のxの位置がわかったので、列を分離して最初の非ゼロ(人の頭のてっぺんとyの位置)を見つけ、それを合計列サイズから引いて高さを求めます。したがって、最初のピークについては、次のようになります。
x = peaks[1];
y = find(im(:,x),1,'first');
height = size(im,1)-y;
私はそれらの線に沿った何かがあなたのために働くかもしれないと思います。あなたはまだいくらかの反復をする必要がありますが、全部ではありません。