これは私が推測かなりうまく機能:
これらの入力を使用して
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;
}
私はその出力を得る:
期待される結果は何ですか?私は重心とコグの輪郭の平均/中央の距離を計算し始めます。境界線の代わりに(それぞれ約1/3の円を描く)境界線が必要な場合は、半円形を検出する輪郭上にhoughCircleまたはRANSACサークル検出を試みます。 – Micka
ok ... right radius(正しい位置が不明ですか?)私はCoGを計算し、外側の輪郭までの最小距離を計算します。 – Micka
私が望む結果は、正確に半径です。私はハフサークルを使用していました。この方法では安定した半径を得ることができませんでした。私はfindhomographyも使いましたが、遅すぎます。 findcontourとminenclosingCircleを使用すると、安定した中心位置と半径を得ることができますが、ボールが左から右に移動するときには正確に半径を検出できません。右から左に移動するには速すぎるので、解決するための考えはありますか:( – Bruce