私は手のバイナリイメージ(以下のような)を持っているプロジェクトに取り組んでおり、機械学習アルゴリズムをトレーニングするために境界のみを抽出したいと考えています。
私はこれをリアルタイムで実装しており、境界内に多くのエラー輪郭が存在する可能性があるため、opencvで輪郭抽出手法を使用するとプログラムの速度が低下します。
形態学的なクローズ操作とそれに続く単純なエッジ検出を使用してみましたが、それでも外側の境界内に多くの情報が見つかります。
私はkinectセンサーを使用して手を追跡しているため、これらのエラー値は前処理技術を使用して修正することはできません。
この問題を解決するために私が書いた関数は次のとおりです。
Mat CvHandRegion::sampleBoundaryPoints(Mat input)
{
Mat sampledOut;
sampledOut.create(input.rows, input.cols, CV_8U);
sampledOut.setTo(0);
for( int x = 0; x < input.cols; x += C_SAMPLING_STEP)
{
for( int y = 0; y < input.rows; y += C_SAMPLING_STEP)
{
if(input.at<uchar>(y,x) == 255)
{
sampledOut.at<uchar>(y,x) = 255;
break;
}
}
}
for( int x = 0; x < input.cols; x += C_SAMPLING_STEP)
{
for( int y = input.rows-1; y > 0; y -= C_SAMPLING_STEP)
{
if(input.at<uchar>(y,x) == 255)
{
sampledOut.at<uchar>(y,x) = 255;
break;
}
}
}
for( int y = 0; y < input.rows; y += C_SAMPLING_STEP)
{
for( int x = 0; x < input.cols; x += C_SAMPLING_STEP)
{
if(input.at<uchar>(y,x) == 255)
{
sampledOut.at<uchar>(y,x) = 255;
break;
}
}
}
for( int y = 0; y < input.rows; y += C_SAMPLING_STEP)
{
for( int x = input.cols-1; x > 0; x -= C_SAMPLING_STEP)
{
if(input.at<uchar>(y,x) == 255)
{
sampledOut.at<uchar>(y,x) = 255;
break;
}
}
}
return sampledOut;
}
ここで、C_SAMPLING_STEPは4に保たれます。そして、基本的にすべての側から到達し、0から255への変更が検出されたらループを終了するという考え方です。
より効率的で堅牢な方法は他にありますか?
更新:Size(5,5)のMORPH_ELLIPSEを使用して、形態学的な終了操作に異なる半径を使用してみました。出力は次のとおりです。
とサイズ(7,7)
とサイズ(9,9)
これである程度問題は解決しますが、データのノイズがかなり変化するため(手のポーズによって)、どのサイズを使用すればよいかわかりません。