1

私は個人的なブロブ検出アルゴリズムを作成しようとしています。私が知る限り、最初に異なるシグマを持つ異なるガウス カーネルを作成する必要があります (これは を使用していますMat kernel= getGaussianKernel(x,y);)。次に、そのカーネルのラプラシアンを取得し、それを使用して画像をフィルター処理するので、私を作成します。スケールスペース。ここで、スケールスペースの各結果イメージでローカル マキシマを見つける必要があります。しかし、そうする適切な方法を見つけることができないようです....これまでの私のコードは

vector <Point> GetLocalMaxima(const cv::Mat Src,int MatchingSize, int Threshold)
{  
    vector <Point> vMaxLoc(0); 

    if ((MatchingSize % 2 == 0) ) // MatchingSize has to be "odd" and > 0
    {
        return vMaxLoc;
    }

    vMaxLoc.reserve(100); // Reserve place for fast access 
    Mat ProcessImg = Src.clone();
    int W = Src.cols;
    int H = Src.rows;
    int SearchWidth  = W - MatchingSize;
    int SearchHeight = H - MatchingSize;
    int MatchingSquareCenter = MatchingSize/2;


    uchar* pProcess = (uchar *) ProcessImg.data; // The pointer to image Data 

    int Shift = MatchingSquareCenter * ( W + 1);
    int k = 0;

    for(int y=0; y < SearchHeight; ++y)
    { 
        int m = k + Shift;
        for(int x=0;x < SearchWidth ; ++x)
        {
            if (pProcess[m++] >= Threshold)
            {
                Point LocMax;
                Mat mROI(ProcessImg, Rect(x,y,MatchingSize,MatchingSize));
                minMaxLoc(mROI,NULL,NULL,NULL,&LocMax);
                if (LocMax.x == MatchingSquareCenter && LocMax.y == MatchingSquareCenter)
                { 
                    vMaxLoc.push_back(Point( x+LocMax.x,y + LocMax.y )); 
                    // imshow("W1",mROI);cvWaitKey(0); //For gebug              
                }
            }
        }
        k += W;
    }
    return vMaxLoc; 
}

ここのこのスレッドで見つけたもので、最大値がある点のベクトルを返すと思われます。ポイントのベクトルを返しますが、各ポイントのすべての x 座標と y 座標は常に -17891602 です...どうすればいいですか? 私はopencvについて何も知らないので、私のコードを修正する以外の何かで私を導く場合は、参考にしてください。私はただ学んでいます

4

2 に答える 2

0

私はそれを見つけました。問題は、しきい値が高すぎることでした。なぜゼロポイントではなくマイナスポイントが出たのかわかりませんが、しきい値を下げるとうまくいきました

于 2013-03-03T21:45:38.363 に答える
0

ここでの問題は、LocMax ポイントが内部ループ内で宣言され、初期化されないため、毎回ガベージ データが返されることです。リンクした StackOverflow の質問を振り返ると、同様の変数Point maxLoc(0,0)が上部で宣言され、検索ウィンドウの中央を指すように構築されていることがわかります。一度だけ初期化する必要があります。minMaxLoc後続のループ反復では、値が関数の結果に置き換えられます。

要約すると、内側のループで次の行を削除します。

Point LocMax; // delete this

そして、わずかに変更されたバージョンを上部近くに追加します。

vector <Point> vMaxLoc(0); // This was your original first line 
Point LocMax(0,0);  // your new second line

とにかく、それで始められるはずです。

于 2013-02-28T20:46:57.163 に答える