Perceive Dimensions (or prominent points) of a Cuboid in a 2D image using OpenCV
我想知道是否可以在如下图所示的图像中找到立方体/立方体的尺寸(以像素为单位)?
由于没有关于深度,视角等的信息,我知道它几乎是不可能的。但是至少可以找到立方体的适当角以使长度,宽度和高度都近似吗?
任何类型的帮助或信息将不胜感激。
预先感谢。
首先,找到图像中的边缘。如果目标图像与提供的图像一样清晰明了,则寻找边缘必须是直截了当的。使用
1 2 3 | cv::Mat img = cv::imread("cube.png"); cv::Mat edges; cv::Canny(img, edges, 20, 60); |
第二,在边缘图像中,检测直线。使用
1 2 | std::vector<cv::Vec2f> lines; cv::HoughLines(edges, lines, 0.6, CV_PI / 120, 50); |
Plaese参考Hough行上的OpenCV文档。我还从那里获取了可视化代码。
我们这种情况的好处是,每个尺寸(长度,宽度和高度)可放置的立方体的边都将具有相同的旋转角?在找到的线方程中。例如,我们可以期望立方体的垂直边(负责高度尺寸)保持垂直并具有?接近0或?€(请参阅OpenCV文档)。我们可以在检测到的霍夫线的向量中找到这样的线:
1 2 3 4 5 6 | std::vector<cv::Vec2f> vertical_lines; std::copy_if(lines.begin(), lines.end(), std::back_inserter(vertical_lines), [](cv::Vec2f line) { //copy if ?? is near 0 or CV_PI return ((0 < line[1]) && (line[1] < 0 + CV_PI / 10)) || ((line[1] < CV_PI) && (line[1] > CV_PI - CV_PI / 10)); }); |
相同的推理适用于查找其余立方体边的线。只需通过适当的??过滤找到的霍夫线。
现在我们有了感兴趣的线的方程,我们可以找到它们对应的边缘像素(下面不是最优代码,只是演示):
1 2 3 4 5 6 7 8 | std::vector<cv::Point> non_zero_points; cv::findNonZero(edges, non_zero_points); std::vector<std::vector<cv::Point>> corresponding_points(vertical_lines.size()); for (int i = 0; i < vertical_lines.size(); ++i) for (auto point : non_zero_points) if (abs(cos(vertical_lines[i][1])*point.x + sin(vertical_lines[i][1])*point.y - vertical_lines[i][0]) < 2) corresponding_points[i].push_back(point); |
现在,对于找到的每个群集,找到最顶部,最底部的点(或另一侧的最左侧/最右侧),并获得立方体角。
请注意由感叹号表示的像素I。偶然将其分类为垂直霍夫线之一,但实际上属于非垂直顶侧。需要通过某种离群值检测或通过其他方法对相应的像素搜索进行删除。
关于修整边的实际长度:据我所知,这确实是一个不平凡的问题。也许这样的问题是一个很好的起点。