2016-07-07 16 views
0

私はアンドロイドでopencvのプロジェクトを持っています。ボールを検出しようとしていますが、MinEnclosingCircleを使うことにしました。私はボールの正確な半径を取得することはできません。この現象のために。MinEnclosingCircleはオブジェクトの高速モーションで安定していませんopencv android

オブジェクトが待機すると、私は以下のような画像が得られます。

enter image description here

が、私は右から左にボールを移動すると、非常に速く、私は間違った半径を得るために、この現象の

左から右へ

enter image description here

この問題の解決方法を教えてください。あなたのご協力に感謝します。

EDIT 1:イメージについてのさらなる詳細、私はこれは私が enter image description here

を捕獲し、これはボール enter image description here

の輪郭を示した画像である円を描くない画像である

を取得それは非常に薄暗いので、私は簡単に見るために輪郭を描きます。

enter image description here

+0

期待される結果は何ですか?私は重心とコグの輪郭の平均/中央の距離を計算し始めます。境界線の代わりに(それぞれ約1/3の円を描く)境界線が必要な場合は、半円形を検出する輪郭上にhoughCircleまたはRANSACサークル検出を試みます。 – Micka

+0

ok ... right radius(正しい位置が不明ですか?)私はCoGを計算し、外側の輪郭までの最小距離を計算します。 – Micka

+0

私が望む結果は、正確に半径です。私はハフサークルを使用していました。この方法では安定した半径を得ることができませんでした。私はfindhomographyも使いましたが、遅すぎます。 findcontourとminenclosingCircleを使用すると、安定した中心位置と半径を得ることができますが、ボールが左から右に移動するときには正確に半径を検出できません。右から左に移動するには速すぎるので、解決するための考えはありますか:( – Bruce

答えて

1

これは私が推測かなりうまく機能:

これらの入力を使用して
int main(int argc, char* argv[]) 
{ 
    //cv::Mat input = cv::imread("C:/StackOverflow/Input/ballMaskClean2.png"); 
    cv::Mat input = cv::imread("C:/StackOverflow/Input/ballMaskClean1.png"); 



    cv::Mat mask; 
    cv::cvtColor(input, mask, CV_BGR2GRAY); 
    //cv::inRange(input, cv::Scalar(200, 200, 200), cv::Scalar(255, 255, 255), mask); // was used for your provided images with red circle inside 
    cv::imshow("mask", mask); 


    std::vector<std::vector<cv::Point> > contours; 
    cv::findContours(mask, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); 

    cv::Mat cleanMask = cv::Mat::zeros(input.size(), CV_8UC1); 
    for (unsigned int i = 0; i < contours.size(); ++i) 
    { 
     cv::drawContours(cleanMask, contours, i, 255, -1); // draw filled 
    } 
    //cv::imwrite("C:/StackOverflow/Input/ballMaskClean.png", cleanMask); 


    cv::Mat dt; 
    cv::distanceTransform(cleanMask, dt, CV_DIST_L1, 3); 

    double minVal, maxVal; 
    cv::Point minLoc, maxLoc; 
    cv::minMaxLoc(dt, &minVal, &maxVal, &minLoc, &maxLoc); 

    double radius = maxVal; 
    cv::Point2f center = maxLoc; 
    cv::circle(input, center, radius, cv::Scalar(0, 255, 0), 2); 

    cv::imshow("output", input); 
    cv::imwrite("C:/StackOverflow/Input/ballCircle.png", input); 

    cv::waitKey(0); 
    return 0; 
} 

私はその出力を得る: enter image description here enter image description here

enter image description here enter image description here

enter image description here enter image description here

enter image description here enter image description here

+0

こんにちはミカ、遅く返信して申し訳ありません、私はモルフォロジーを使って問題を解決しました。結果はかなり良かったですが、もっと詳しく知る。私は理解していないと私は尋ねたい:distTransformとminmaxLocを行うにはdistancetransformを知っているが、私はdistancetransformとminmaxLocを使用するときあなたの目的がわからない – Bruce

+0

roiのインテリアを検索したい国境までの距離が最も遠い – Micka

+1

ああ、私は今、理解しています、ついにあなたの助けに感謝したいと思います。 – Bruce

関連する問題