2

私が現在取り組んでいるプログラムはほぼ完成していますが、結果にはあまり満足していません。キャニー アルゴリズムを使用することで、オブジェクトの輪郭を非常に明確に取得することができましたが、プログラムは輪郭を認識して赤い線で輪郭を描くのに問題があります。プログラム:

void setwindowSettings(){
    namedWindow("Contours", CV_WINDOW_AUTOSIZE);

    createTrackbar("LowerC", "Contours", &lowerC, 255, NULL);
    createTrackbar("UpperC", "Contours", &upperC, 255, NULL);
}

void wait(void)
{
    long t=30000000;
    while(t--);
}

int main(void)
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
    return -1;

Mat frame,foreground,image;
double pt1, pt2, area;
Rect rect;
int i;

vector<vector<Point> > contours;
vector<vector<Point> > largest_contours;

namedWindow("Capture", CV_WINDOW_AUTOSIZE);
setwindowSettings();

while(1){
    cap >> frame; // get a new frame from camera
    if( frame.empty() )
            break;
    image=frame.clone();

    cvtColor(image,foreground,CV_BGR2GRAY);
    GaussianBlur(foreground,foreground,Size(9,11),0,0);
    Canny(foreground,foreground,lowerC,upperC,3);

    findContours(foreground,contours,CV_RETR_EXTERNAL,CV_CHAIN_APPROX_SIMPLE);  

    if(contours.empty())
        continue;

    double largest_area = 0;

    for( i= 0; i < contours.size(); i++){  // get the largest contour
        area = fabs(contourArea(contours[i]));
        if(area >= largest_area){
            largest_area = area;
            largest_contours.clear(); 
            largest_contours.push_back(contours[i]);
        }
    }

    if(largest_area>=3000){   // draw the largest contour if exceeded minimum largest area 
        drawContours(image,largest_contours,-1,Scalar(0,0,255),2);
        printf("area = %.f\n",largest_area);
    }

    wait();

    imshow( "Capture",image );
    imshow("Contours",foreground);

    if(waitKey(30) >= 0) break;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;
}

プログラム概要:

  1. カメラから画像を取得する
  2. ノイズフィルター(グレー→ぼかし→キャニーに変換)
  3. 輪郭を見つける
  4. 画像内の最大の輪郭とその領域、別名オブジェクトを見つけます
  5. オブジェクトの周りに赤い線を引き、最大の領域を印刷します
  6. すすいで繰り返す

そして結果:

欲しいものを手に入れることはめったにありません。輪郭が検出され、赤い線が描かれました ( GOOD ONE ):

輪郭が検出されました。 等高線の半分が消えることに注意してください

...そして通常、私はこれを手に入れました。赤い線ではなく、輪郭が検出されません ( BAD ONE ):

輪郭はあるが、輪郭が検出されない

GOOD ONEを取得するチャンスは、1/20どれがあまり良くないかです. また、オブジェクトの周りに赤い線が表示されると、画面内のオブジェクトの輪郭の線Contoursが点滅します (GOOD ONE の写真を参照)。この質問にはオブジェクトの 1 つ (小さな黒い四角いボックス) を使用していますが、このオブジェクト検出プログラムの主な目的は、形状や色に関係なくオブジェクトを検出することであることに注意してください。

だから私の質問は:

  1. 輪郭が一日のようにはっきりしているのに、なぜ BAD ONES が表示されるのですか?
  2. 輪郭検出を改善する方法について、誰かがより良いアイデアを共有できますか? (つまり、より良いぼかしアルゴリズム)
  3. オブジェクトの周りに赤い線が描かれているときに輪郭の線が点滅しないようにするにはどうすればよいですか?

編集:輪郭の線の点滅は、その周りに描かれた赤い線が原因ではないことを発見しました(drawContoursまたはline関数を使用)が、関数によって最大の輪郭が検出さfindContoursれ、最大の輪郭として計算された後に発生します。

No.に関するご質問は 3ここをクリック. ビデオはこちら、クリックしてください!!!

前もって感謝します。

PS: Ms Visual C++ 2010 Exp で OpenCV 2.4.3 を使用しています。

4

1 に答える 1

1
  1. あなたは最大の輪郭の事実を使用しているので、カメラの視野に現れる最大のオブジェクトを検出しようとしていると思います.右上の窓の光/明るい光源が輪郭を作成しないのはなぜですか(ブレによるものかもしれません)。背景画像を保存して、オブジェクトが表示される画像から差し引くことができます。このようにして、オブジェクトを導き出すことができます。差分画像に輪郭検出を適用できます。差分画像はabsdiff(frame_now,frame_backgrnd,diff)どこ?diff
  2. オブジェクトが動いていて検出したい場合は、オプティカル フローと最大輪郭を組み合わせてオブジェクトを検出できます。
  3. ぼかし機能なしで処理を行ってから、最大の輪郭領域を検出してみてください。
  4. ポイントをプロットするには、これを試してください

    for(int i = 1;i<(int)largest_contours[0].size();i++)
         line(image,largest_contours[0][i-1],largest_contours[0][i],cv::Scalar(0,0,255),2,8,0);
    
于 2013-02-05T13:47:12.493 に答える