如何根据点云计算对应物体的长宽

输入:一组点云(位于同一个平面,四边形物体的点云,如矩形或者正方形)

输出:对应实际物体的长和宽

输入的点云可能存在噪声干扰,需要通过一系列处理去除干扰,并在求到最小外接矩阵后进行优化,才可获得较准确的长和宽。

主要进行如下几个步骤:1)将点云旋转到XOY平面;2)生成点云图像;3)进行膨胀腐蚀,填补空白区域;4)进行连通域标记,取最大连通域;5)获取图像的边缘;6.求边缘部分的最小外接矩阵并进行优化。

现介绍一下第六步处理时遇到的问题。

求最小外接矩阵的基本原理:获取点簇最开始的minx,maxx,miny,maxy确定最初的外接矩形,求外接矩形的面积,然后对点簇进行旋转,按照下面公式即可:

在这里插入图片描述
旋转之后,求出新的minx,maxx,miny,maxy,计算此时的面积,直到面积达到最小,对应的即为最小外接矩形。

关于图像旋转参考:https://blog.csdn.net/zhouxuguang236/article/details/31820095

输入第五步得到的边缘图edge,求外接矩阵:

测试代码:

 vector> contours; 

 vector hierarchy; 

   findContours(edge, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point()); 

   Mat imageContours = Mat::zeros(edge.size(), CV_8UC1); 

   int idx, maxcontours = 0; 

   vector selectpoint; 

  for (int i = 0; i < contours.size(); i++) 

   {
    
     
   
  vector ptmp = contours[i]; 

  if (ptmp.size() > maxcontours) 

    {
    
     

   selectpoint = ptmp; 

   idx = i; 

   } 

     } 

   drawContours(imageContours, contours, idx, Scalar(255), 1, 8, hierarchy); 

   RotatedRect rect = minAreaRect(selectpoint); 

  Point2f P[4]; 

   rect.points(P); 

  for (int j = 0; j <= 3; j++) 

   {
    
     

  line(imageContours, P[j], P[(j + 1) % 4], Scalar(255), 2); 

   } 

  imshow("MinAreaRect", imageContours); 

  waitKey(0);

注意:

(1)部分关键量解释

contours;//向量内每个元素保存了一组由连续的Point点构成的点的集合的向量,每一组Point点集就是一个轮廓。

//有多少轮廓,向量contours就有多少元素

hierarchy;//向量内每一个元素包含了4个int型变量,向量hiararchy内的元素和轮廓向量contours内的元素是一一对应的,向量的容量相同。每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~hierarchy[i][3]的相应位被设置为默认值-1。 findContours(edge, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point());

//RETR_EXTERNAL,只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略。

//CHAIN_APPROX_NONE,保存物体边界上所有连续的轮廓点到contours向量中。

备注:

点击下面链接,进入奥比中光开发者社区,了解更多3D视觉技术信息:
https://developer.orbbec.com.cn/

或扫描下方二维码,进入奥比中光开发者社区:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/limingmin2020/article/details/109645207#comments_21746372