检测视频流中的几何对象并重建其轮廓

Detect geometric object on video stream and reconstruct its contours

我正在尝试使用 C++ 上的 OpenCV 2.4.9 检测视频流中的塑料物体。 该物体有六个角,其轮廓如下:.
对于每一帧,我都在做某种分割和边缘检测。在这些操作之后,我得到了一些二进制图像,其中包含损坏的对象轮廓和一些来自背景的噪声。
例如:

我需要以某种方式在这里检测我的对象并恢复轮廓。你能建议一些方法吗?我需要一个快速的方法,因为我想在 android phone 上 运行 这个程序。

我知道我的对象的比例。并且相机始终与物体表面大致成垂直角度。
有时当轮廓没有损坏太多时我可以找到正确的边界框,但在其他情况下我不能。
我认为我需要以某种方式在这里使用有关对象几何的信息。我将不胜感激任何帮助!

UPD:
如果我找到了对象的部分轮廓,是否可以以某种方式将我的形状放入找到的轮廓内以获得缺失的线条?

鉴于形状是一个相当规则的多边形,您是否尝试过 运行 霍夫线和计算交点来找到顶点?

即使你不能得到所有的顶点,如果你得到 6 个中的 4 个,你应该能够重建缺失的顶点。

下面使用霍夫概率线来识别可能的线段。设置最小线长可以避免一定的噪音。

然后我在所有发现的线段的端点上使用 kmeans 来识别 6 个可能的顶点。

我测试的一张图像的结果还不错,但如果您的 inout 图像中有很多其他人工制品,您可能需要进行一些额外的异常值删除

Mat image = imread(image_name);

// Convert to grey scale    
Mat grey;
cvtColor(image, grey, CV_RGB2GRAY);

// Invert colour scheme
grey = 255 - grey;

// Find Hough probabilistic lines
vector<Vec4i> lines;
double rho( 1 );
double theta( M_PI / 180.0 );
int thresh( 10 );
double minLineLength(20.0);
double maxLineGap( 5.0);
HoughLinesP(grey, lines, rho, theta, thresh, minLineLength, maxLineGap);

// Store end points of these segments as vertices
vector<Point2f> vertices;
for( int i=0; i<lines.size(); i++ ) {
    float x1 = lines[i][0];
    float y1 = lines[i][1];
    float x2 = lines[i][2];
    float y2 = lines[i][3];
    vertices.push_back(Point2f(x1, y1) );
    vertices.push_back(Point2f( x2, y2) );
}

// Run kMeans on line ends to find 6 centres which we assume are verts
TermCriteria criteria(TermCriteria::EPS+TermCriteria::COUNT, 500, 1.0);
int attempts(20);
Mat centres, labels;
kmeans(vertices, 6, labels, criteria, attempts, KMEANS_PP_CENTERS, centres );

// Plot them on the RGB image
for( int i=0; i<6; i++ ) {
    Point2f v1 = Point2f( vertices[i].x-2, vertices[i].y-2 );
    Point2f v2 = Point2f( vertices[i].x-2, vertices[i].y+2 );
    Point2f v3 = Point2f( vertices[i].x+2, vertices[i].y-2 );
    Point2f v4 = Point2f( vertices[i].x+2, vertices[i].y+2 );
    line(image, v1, v4, Scalar(255,255,0));
    line(image, v2, v3, Scalar(255,255,0));
}

imshow( "Verts", image );
cout << centres << endl;

您可以看到最上面的两个点实际上位于同一位置。我猜这是因为缺少几个顶点。尽管如此,其他人的位置都很好,您可以通过形状的对称性来恢复丢失的人。