通过YOLO检测得到目标的检测框后,这些区域就可以作为ROI将包含在各roi内的点云分组聚类出来,从而通过点云得到目标的准确位置。
代码解析:
1.boundingbox数据结构:
struct BoundingBox { // bounding box around a classified object (contains both 2D and 3D data)
int boxID; // unique identifier for this bounding box
int trackID; // unique identifier for the track to which this bounding box belongs
cv::Rect roi; // 2D region-of-interest in image coordinates
int classID; // ID based on class file provided to YOLO framework
double confidence; // classification trust
std::vector<LidarPoint> lidarPoints; // Lidar 3D points which project into 2D image roi
std::vector<cv::KeyPoint> keypoints; // keypoints enclosed by 2D roi
std::vector<cv::DMatch> kptMatches; // keypoint matches enclosed by 2D roi
};
2.调整boundingbox大小,减少两个重叠区域包含同一部分点云的情况
发现框图往往会比实际物体大一些,这样的话,会把一些不属于目标物体的点,聚类到该物体上了。所以往往会在原来框图的基础上缩小一定比例,然后将投影在缩小之后的小框图上的点保留,下面分别是缩小10%,25%的结果。
vector<vector<BoundingBox>::iterator> enclosingBoxes; // pointers to all bounding boxes which enclose the current Lidar point
for (vector<BoundingBox>::iterator it2 = boundingBoxes.begin(); it2 != boundingBoxes.end(); ++it2)
{
// shrink current bounding box slightly to avoid having too many outlier points around the edges
cv::Rect smallerBox;
smallerBox.x = (*it2).roi.x + shrinkFactor * (*it2).roi.width / 2.0;
smallerBox.y = (*it2).roi.y + shrinkFactor * (*it2).roi.height / 2.0;
smallerBox.width = (*it2).roi.width * (1 - shrinkFactor);
smallerBox.height = (*it2).roi.height * (1 - shrinkFactor);
因子“ shrinkFactor”,该因子表示以[%]为单位的大小调整量,从原始边界框创建了一个较小的框。在实践中,应使用5-10%的适当设置,以避免丢弃过多的数据。
3.避免错误分组
有时候检测框会包含不属于本车辆的点云,在这里主要通过循环检测框中点,只保留那些仅存在与一个检测框中的点。
if (smallerBox.contains(pt))
{
enclosingBoxes.push_back(it2); //remove overlapping points
}
} // eof loop over all bounding boxes
if (enclosingBoxes.size() == 1){
enclosingBoxes[0]->lidarPoints.push_back(*it1); //collect the point contained for every rectangle
}