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

原创 2015年07月09日 17:05:06

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

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

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

总思路:

        用二维的数据来表示三维数据(数据量从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())
{
}
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

一种基于OpenCV的三维重建实现方案

一种基于OpenCV的三维重建实现方案 来源:淘金者论文范文 作者:Www.TaoJz.Com 日期:08/30/09 摘 要 本文以计算机视觉三维重建技术为研究对象,分析了开放计...

OPENCV轮廓提取findContours和drawContours

关于opencv中的轮廓提取函数findcontours()和轮廓绘制函数drawContours()中参数的说明和实验结果。

三维重构

视差用于双目的三维重建中,双目三维重建包括以下几步:1、摄像机标定(求取两个摄像头的内外参数),MATLAB中有这个工具包;2、利用摄像头标定得到的内外参数进行图像矫正和校正,校正后的两幅图像对应特征...

常见三维重建算法及其实现(含源码下载链接)

这里三维重建,输入的是断层图像切片,节选于自己毕业设计,文末贴出一些关键代码。 三维重建的方法大概有两种:直接将体素投影到计算机显示平面的方法被称为体绘制(Volume Rendering),也可...

对话框中加入标签页的5种方法

(2008-07-08 15:25 博客搬家拾遗)标签页是MFC控件里有一点难用的东西,今天看到了一篇相关文章,觉得写得比较系统,而且浅显易懂,特地转来,与大家分享的同时也留备自己以后查用。(以下转...
  • fm0517
  • fm0517
  • 2008-08-18 23:12
  • 2478

VTK 三维轮廓等值面的提取

目的: 学习VTK可视化 案例一 /************************************************************************/ /*...

Cairngorm核心骨架(解说)

  • 2010-07-15 16:25
  • 34KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)