关闭

基于轮廓的三维骨架重建方法和核心代码

标签: opencvPCL轮廓三维重建骨架
453人阅读 评论(0) 收藏 举报

 背景(为什么要这么做?):

        目前获取三维数据的方法很多,比如:双目视觉技术,深度相机等等。

        但是存在一个问题:数据量巨大!如果要做在线检测,那速度很可能达不到要求。

总思路:

        用二维的数据来表示三维数据(数据量从n3降到n2)

课题需求:

        本人的实验室目前的课题是要做马铃薯的形状检测。通过二维图像误差很大,通过传统三维方法达不到在线检测速度要求。

步骤:

1.推导出二维轮廓像素点到三维空间的坐标映射关系;

2.通过图像处理获取轮廓坐标;

3.转换到三维空间;

4.通过PCL点云数据库显示合成三维图像。

核心代码:

        //计算x,y轴的方向余弦
//p1表示上面点x,p2表示上面点y,p3表示下面点x,p4表示下面点y
float StaticClassify::DirectionCosineX(float angle,float p1,float p2,float p3,float p4)
{
float pp=p3-p1;
float ppp=sqrt(pow((p3-p1),2)+pow((p2-p4),2));
float Cosine;
if (angle<100)
{Cosine=-pp/ppp;

else
{Cosine=pp/ppp;
}
return Cosine;
}


    //轮廓的二维点到三维点转换

for (i0 = 0; i0 < length0; i0++)
{
point0[i0]=*CV_GET_SEQ_ELEM(CvPoint,contours0,i0);//在当前contour下一个一个的读取数据

point30[i0].x=(float)(point0[i0].x-x0);
point30[i0].y=(float)(point0[i0].y-y0);
point30[i0].z=(float)0;
}
for (i1 = 0; i1 < length1; i1++)
{
point1[i1]=*CV_GET_SEQ_ELEM(CvPoint,contours1,i1);
   point31[i1].x=((float)(point1[i1].x-x1))*0.92388;    //cos22.5°
   point31[i1].y=((float)(point1[i1].y-y1));
   point31[i1].z=((float)-(point1[i1].x-x1))*0.38268;   //sin22.5°
    }
for (i2 = 0; i2 < length2; i2++)
{
point2[i2]=*CV_GET_SEQ_ELEM(CvPoint,contours2,i2);


point32[i2].x=((float)(point2[i2].x-x2))*0.7071;
point32[i2].y=((float)(point2[i2].y-y2));
point32[i2].z=((float)-(point2[i2].x-x2))*0.7071;
}
for (i3 = 0; i3 < length3; i3++)
{
point3[i3]=*CV_GET_SEQ_ELEM(CvPoint,contours3,i3);

point33[i3].x=((float)(point3[i3].x-x3))*0.38268;
point33[i3].y=((float)(point3[i3].y-y3));
point33[i3].z=(float)-(point3[i3].x-x3)*0.92388;
}
for (i4 = 0; i4 < length4; i4++)
{
point4[i4]=*CV_GET_SEQ_ELEM(CvPoint,contours4,i4);

   point34[i4].x=(float)0;
   point34[i4].y=((float)(point4[i4].y-y4));
point34[i4].z=(float)-(point4[i3].x-x3);
}
for (i5 = 0; i5 < length5; i5++)
{
point5[i5]=*CV_GET_SEQ_ELEM(CvPoint,contours5,i5);

   point35[i5].x=((float)-(point5[i5].x-x5))*0.38268;
   point35[i5].y=((float)(point5[i5].y-y5));
   point35[i5].z=((float)-(point5[i5].x-x5)*0.92388);
}
for (i6 = 0; i6 < length6; i6++)
{
point6[i6]=*CV_GET_SEQ_ELEM(CvPoint,contours6,i6);

      point36[i6].x=(float)-(point6[i6].x-x6)*0.7071;
    point36[i6].y=((float)(point6[i6].y-y6));
    point36[i6].z=((float)-(point6[i6].x-x6))*0.7071;
}
for (i7 = 0; i7 < length7; i7++)
{
point7[i7]=*CV_GET_SEQ_ELEM(CvPoint,contours7,i7);

point37[i7].x=((float)-(point7[i7].x-x7))*0.92388;
    point37[i7].y=((float)(point7[i7].y-y7));
    point37[i7].z=((float)-(point7[i7].x-x7))*0.38268;
}
}


//三维点云显示
void StaticClassify::OnBnClickedButtonThreeDimensional()
{
pcl::PointXYZ p;
// TODO: 在此添加控件通知处理程序代码
TwoPointToThreePoint();

pcl::PointCloud<pcl::PointXYZ>::Ptr cloud0(new pcl::PointCloud<pcl::PointXYZ>);   //Ptr是一种指针
cloud0->reserve(contours0->total);                                                //reserve开辟空间
for(int i=0;i<contours0->total;i++)
{
p.x=point30[i].x;
p.y=point30[i].y;
p.z=point30[i].z;
cloud0->push_back(p);
}

pcl::visualization::CloudViewer viewer("点云");
viewer.runOnVisualizationThreadOnce(viewerOneOff);
viewer.showCloud(cloud0,"cloud0");

while(!viewer.wasStopped())
{
}
}


0
0

猜你在找
【套餐】Hadoop生态系统零基础入门
【套餐】嵌入式Linux C编程基础
【套餐】2017软考系统集成项目——任铄
【套餐】Android 5.x顶级视频课程——李宁
【套餐】深度学习入门视频课程——唐宇迪
【直播】广义线性模型及其应用——李科
【直播】从0到1 区块链的概念到实践
【直播】计算机视觉原理及实战——屈教授
【直播】机器学习之凸优化——马博士
【直播】机器学习&数据挖掘7周实训--韦玮
查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:464次
    • 积分:15
    • 等级:
    • 排名:千里之外
    • 原创:1篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章存档