如何确定我跟踪的目标球是否穿过我画的线?

How do I find if the object ball I track crosses a line that I have drawn?

我正在使用 C++ 和 OpenCV 3.0 创建 SimulCam 的基本形式。

我目前正在寻找一种方法来检查目标球何时 crossed/intersected 以及我在输出 window.

上绘制的一条线

正在使用轮廓跟踪球,最终我想计算出这个相交发生的确切帧数。

但首先,我想了解如何执行检查以查看对象球何时具有 crossed/intersected 和绘制的线。

Scene with ball moving towards line

我有对象的轮廓,我想了解如何执行交点检查。

查找轮廓和对象跟踪的代码:

findContours(resizedThresh, contourVector, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

contourVector.resize(contourVector.size());

line(resizedF_Fast, Point(300, 0), Point(300, 360), Scalar(255), 2, 8);
for (size_t i = 0; i < contourVector.size(); i++) {

     approxPolyDP(Mat(contourVector[i]), contourVector[i], 0.01*arcLength(contourVector[i], true), true);
     double area = contourArea(contourVector[i]);

     if (contourVector[i].size() > 5 && (area > 200)) {
        ++circlesC;
        drawContours(resizedF_Fast, contourVector, i, Scalar(255, 255, 255), 2, CV_AA, hierarchy, abs(1));
        searchForMovement(resizedThresh, resizedF_Fast);
     }
}

我做了一些其他研究,我一直在研究使用 lineIterator,但我不完全确定..

对于潜在的粗略代码表示歉意,这里是新手。任何帮助将不胜感激。

我的第一种方法是将圆拟合到轮廓点中,然后使用点积计算线与圆心之间的距离。可能是这样的(没试过):

Point Pc; // circle center
Point L0(300,0);
Point L1(300,360);

double v[] = {L1.x-L0.x,L1.y-L0.y};
double w[] = {Pc.x-L0.x,Pc.y-L0.y};

Mat v(1,2,CV_32F,v);
Mat w(1,2,CV_32F,w);

double c1 = w.dot(v);
double c2 = v.dot(v);  
double b = c1 / c2;

Mat Pb = L0 + b * v;
double distance = norm(Pc,Pb);

然后你检查你的距离减去你的圆半径是否小于等于零。

但是由于你相机的透视变换,球变成了椭圆,我的假设变得不太准确。

如果您需要更精确的解决方案,您需要检查每个轮廓点并取最小距离。

This link 显示一些代码和进一步的解释。

我终于解决了这个问题,我将post这里的总体思路。

对于每一帧,计算对象轮廓。

  • 每个轮廓都会存储一个 x 和 y 坐标

使用 LineIterator(例如 lineIt)循环显示一行的所有值。

if (xpos_contour < lineIt.pos().x) {
     // Object is on the left of the line
}
else if (xpos_contour > lineIt.pos().x) {
     // Object is to the right of the line
}

请记住我使用的是自上而下拍摄的输入视频,因此只有 x 坐标很重要。