16

ペトリ皿 (または他の円形容器) 内の小動物を追跡するアプリケーションを開発しています。追跡が行われる前に、最初の数フレームを使用して領域を定義します。各皿は、円形の独立した静的領域に一致します (つまり、追跡中に更新されません)。ユーザーは、元の画像から料理を見つけて領域として使用するようにプログラムに要求できます。

以下に例を示します。 ここに画像の説明を入力 ここに画像の説明を入力

このタスクを実行するために、私はHough Circle Transformを使用しています。しかし、実際には、ユーザーごとに設定やイメージが大きく異なるため、ユーザーにパラメーターを手動で定義するように依頼したくありません。すべてのパラメーターを推測することもできません。

ただし、使用したい追加情報があります。

検出される円の正確な数を知っています。

  • すべての円はほぼ同じ大きさです。
  • 円は重ねることができません。
  • 円の最小サイズと最大サイズの大まかなアイデアがあります。
  • 円は完全に画像内になければなりません。

したがって、定義するパラメーターの数を 1 つに絞り込むことができます:しきい値。これらの情報を使用し、N 個の円を見つける必要があることを考慮すると、現在の解決策は、しきい値の多くの値をテストし、標準偏差が最小である円を維持することです(すべての円が同様のサイズである必要があるため)。

//at this point, minRad and maxRad were calculated from the size of the image and the number of circles to find.
//assuming circles should altogether fill more than 1/3 of the images but cannot be altogether larger than the image.
//N is the integer number of circles to find.
//img is the picture of the scene (filtered).

//the vectors containing the detected circles and the --so far-- best circles found.
std::vector<cv::Vec3f> circles, bestCircles;

//the score of the --so far-- best set of circles
double bestSsem = 0;

 for(int t=5; t<400 ; t=t+2){
//Apply Hough Circles with the threshold t
    cv::HoughCircles(img, circles, CV_HOUGH_GRADIENT, 3, minRad*2, t,3, minRad, maxRad );

    if(circles.size() >= N){
//call a routine to give a score to this set of circles according to the similarity of their radii
        double ssem = scoreSetOfCircles(circles,N);
//if no circles are recorded yet, or if the score of this set of circles is higher than the former best
        if( bestCircles.size() < N ||  ssem > bestSsem){
//this set become the temporary best set of circles
                bestCircles=circles;
                bestSsem=ssem;
        }
    }
}

と:

 //the methods to assess how good is a set of circle (the more similar the circles are, the higher is ssem)
    double scoreSetOfCircles(std::vector<cv::Vec3f> circles, int N){
    double ssem=0, sum = 0;
        double mean;
        for(unsigned int j=0;j<N;j++){
            sum = sum + circles[j][2];
        }
        mean = sum/N;
        for(unsigned int j=0;j<N;j++){
            double em = mean - circles[j][2];
            ssem = 1/(ssem + em*em);
        }
    return ssem;

}

最初のパスの結果を使用して [minRad:maxRad] 間隔を狭めるこのアルゴリズムを繰り返した 2 番目のパスを実行することで、より高い精度に達しました。

たとえば、minRad2 = 0.95 * 最良の円の平均半径と maxRad2 = 1.05 * 最良の円の平均半径です。

これまでのところ、この方法を使用してかなり良い結果が得られました。しかし、それは遅く、かなり汚れています。私の質問は次のとおりです。

  • この問題をよりクリーンで高速な方法で解決するための代替アルゴリズムはありますか?
  • または、このアルゴリズムを改善するために何を提案しますか?
  • 一般化されたハフ変換を調査する必要があると思いますか?

回答と提案をありがとうございます。

4

3 に答える 3

10

次のアプローチは、あなたの場合にはかなりうまくいくはずです:

  1. 画像を 2 値化します (アルゴリズムを照明条件から独立させるために、いくつかのレベルのしきい値でこれを行う必要がある場合があります)。
  2. 輪郭を見つける
  3. 各輪郭についてモーメントを計算します
  4. 小さすぎる等高線を削除するには、領域でフィルター処理します
  5. 円形度で等高線をフィルター処理する:

    double area = moms.m00;
    double perimeter = arcLength(Mat(contours[contourIdx]), true);
    double ratio = 4 * CV_PI * area / (perimeter * perimeter);
    

    ratio1 に近いと円になります。

  6. 各円の半径と中心を計算する

    center = Point2d(moms.m10 / moms.m00, moms.m01 / moms.m00);
    

さらにフィルターを追加して、堅牢性を向上させることができます。

実際、OpenCV で手順全体の実装を見つけることができます。SimpleBlobDetectorクラスと関数がどのようにfindCirclesGrid実装されているかを見てください。

于 2012-06-03T21:02:22.940 に答える
5

現在のアルゴリズムの中で、最も目立つのはfor(int t=5; t<400; t=t+2)ループです。いくつかのテスト画像のスコア値を記録しようとしています。score(t)対グラフt。運が良ければ、より狭い範囲を示唆するか、t最大値が 1 つの滑らかな曲線になります。後者の場合、Hill Climbingメソッドtを使用して、すべての値のループをよりスマートな検索に変更できます。

かなりノイズが多い場合でも、最初にたとえば 30 の倍数をループし、そのうちの最良の 1 つまたは 2 つについては、近くの 2 の倍数をループします。

また、スコア関数では、円が重なっている結果を失格にし、円の間隔が広すぎる場合はペナルティを課す必要があります。

于 2012-06-03T21:48:28.177 に答える
3

黒い背景を使用している理由を説明していません。テレセントリック レンズを使用していない限り (見かけの視野を考えるとそうではないようです)、放射状の歪みを今のところ無視すると、料理の画像は楕円形になるため、それらを円として推定すると重大なエラーが発生する可能性があります。

結局のところ、あなたが良いアプローチに従っているとは思えません。目標が単純に背景を削除して、皿の中の虫を追跡できるようにすることである場合、目標はそれだけである必要があります。背景のピクセルを見つけて、それらをマークします。これを行う最も簡単な方法は、同じ照明とカメラの下で皿のない背景の写真を撮り、画像との写真との違いを直接検出することです。これを行うには、色付きの背景が望ましく、皿に表示されにくい色 (緑や青のベルベットなど) を使用します。したがって、視覚効果に適用されるマシン ビジョンの古典的な手法であるブルースクリーン処理 (またはクロマ キー処理) に問題を軽減したことになります。この問題を解決するための古典的なアルゴリズムを見つけるには、「マット ペトロ ヴラホス仮定」を Google 検索してください。

于 2012-06-04T16:19:57.963 に答える