我在android中有一个opencv的项目,我尝试检测球,我决定使用MinEnclosingCircle,但是当我快速移动物体时我有问题。我无法准确得到球的半径。因为这种现象。
当对象待命时,我得到如下图像:
但是当我从右向左移动球时,由于这种现象,左右移动得太快我得到了错误的半径
你能告诉我如何解决这个问题。非常感谢你的帮助。
编辑1 :关于我得到的图片的更多细节
它非常暗淡,所以我画轮廓看起来更容易。
答案 0 :(得分:2)
我认为这很有效:
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;
}