详细设计说明书TeamPal软件工程项目信息化平台_第1页
详细设计说明书TeamPal软件工程项目信息化平台_第2页
详细设计说明书TeamPal软件工程项目信息化平台_第3页
详细设计说明书TeamPal软件工程项目信息化平台_第4页
详细设计说明书TeamPal软件工程项目信息化平台_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1引言21.1编写目的21.2背景22程序系统的结构23、设计说明33.1程序描述33.2功能33.3性能43.4输入项43.5输出项43.6主要算法43.7流程逻辑183.8接口183.9限制条件183.10测试计划183.11尚未解决的问题18详细设计说明书1引言1.1编写目的项目详细设计计划1.2背景各小组成员开始工作后将会以详细设计为基础设计各个负责模块的内容。首先,按要求定制软件的基本需求,再次根据需求绘制出软件的开发甘特图,然后根据组员的状况分配任务并按时举行例会讨论项目进展与进度。最后,需要撰写相关的测试用例检验产品的容错性及其他特性,提交产品。2程序系统的结构系统流程图:系统各

2、流程详细实现功能:3、设计说明3.1程序描述这部分主要用来处理获取的视频图像,因为帧图像本身的数据量太大,所以无法被高效高速的被3D系统识别,所以需要对图像进行处理,进而得到简单的实时数据(大概不超过10个),这样可以保证数据的实时性与准确性。这些数据是传输给3D部分,使其得到相应的实时数据参数,从而可以操作3D模型动画与2D视频联动。3.2功能1、(视频输入)2、(相应的算法以及opencv库函数调用)3、(得到处理后的画面与感兴趣的参数)4、(参数传递并输出3D实时性渲染动画)3.3性能性能的好坏基于图像处理所获得的参数,有时会依赖于外界环境,有时因为机器原因或者硬件或者其他原因导致系能不

3、够稳定,我们会及时在未来的更新中把他完善。3.4输入项2D视频输入3.5输出项2D图像处理后的相关参数3.6主要算法人脸定位本项目中人脸定位的方法主要采用的是角点检测的方法。先提取每一帧图像中人脸上的眼睛、嘴的角点。眼睛和嘴的位置是按照大部分人脸上的尺寸来确定的。角点目前为止还没有明确的数学定义。角点可以是两条线的交叉处,也可以是位于相邻的两个主要方向不同的事物上的点。一般的角点检测都是对有具体定义的、或者是能够具体检测出来的兴趣点的检测。这意味着兴趣点可以是角点,也可以是在某些属性上强度最大或者最小的孤立点、线段的终点,或者是曲线上局部曲率最大的点。在实践中,通常大部分称为角点检测的方法检测

4、的都是兴趣点,而不是独有的角点。因此,如果只要检测角点的话,需要对检测出来的兴趣点进行局部检测,以确定出哪些是真正的角点。在本项目中,我们对脸部进行区域划分,划分出一些比较感兴趣的区域,比如将双眼所在的区域划分出来,以及嘴所在的区域划分出来,然后再对相应感兴趣的区域进行角点检测。分别取眼部角点横纵坐标的平均值,再取嘴部角点横纵坐标的平均值,两者去平均即可得到一个参考点,我们所做的动作,都是基于这个参考点来选取的。角点检测的代码如下:int FindCornerPot(int n) IplImage* imgRGB = cvCreateImage(sz,IPL_DEPTH_8U,1); IplI

5、mage* imgRGB2 = cvCreateImage(sz,IPL_DEPTH_8U,1); int w=thd_dst2->width; int h=thd_dst2->height; IplImage* eig_image = cvCreateImage(cvSize(w, h),IPL_DEPTH_32F, 1); IplImage* temp_image = cvCreateImage(cvSize(w, h),IPL_DEPTH_32F, 1); const int MAX_CORNERS = 20;/estimate a corner number CvPoint

6、2D32f cornersMAX_CORNERS = 0;/ coordinates of corners /CvPoint2D32f* corners = new CvPoint2D32f MAX_CORNERS ; /another method of declaring an array int corner_count = MAX_CORNERS; double quality_level = 0.1;/threshold for the eigenvalues double min_distance = 5;/minimum distance between two corners

7、int eig_block_size = 3;/window size int use_harris = false;/use 'harris method' or not int r=2; /rectangle size int lineWidth=1; / rectangle line width if(n=0|n=1) /-initial guess by cvGoodFeaturesToTrack- cvGoodFeaturesToTrack(thd_dst2,eig_image, / output temp_image,corners,&corner_coun

8、t,quality_level,min_distance,NULL,eig_block_size,use_harris); /-draw good feature corners on the original RGB image- /*for (int i=0;i<corner_count;i+) cvRectangle(imgRGB2, cvPoint(cornersi.x-r,cornersi.y-r), cvPoint(cornersi.x+r,cornersi.y+r), cvScalar(255,0,0),lineWidth); */ int half_win_size=3;

9、/the window size will be 3+1+3=7 int iteration=20; double epislon=0.1; cvFindCornerSubPix( thd_dst2, corners, corner_count, cvSize(half_win_size,half_win_size), cvSize(-1,-1),/no ignoring the neighbours of the center corner cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,iteration,epislon) ); / char

10、 features_found MAX_CORNERS ; float feature_errors MAX_CORNERS ; CvSize pyr_sz = cvSize ( thd_dst2->width,thd_dst22->height ); IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); CvPoint2D32f* cornersB = new CvPoint2D32f MAX_COR

11、NERS ; cvCalcOpticalFlowPyrLK( thd_dst2, thd_dst22, pyrA, pyrB, corners, cornersB, corner_count, cvSize(half_win_size,half_win_size), 5, features_found, feature_errors, cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ), 0 ); if(n=2) corner_count2=corner_count1; /-initial guess by cvGoodFe

12、aturesToTrack- cvGoodFeaturesToTrack(thd_dst2,eig_image, / output temp_image,corners,&corner_count1,quality_level,min_distance,NULL,eig_block_size,use_harris); /-draw good feature corners on the original RGB image- int half_win_size=3;/the window size will be 3+1+3=7 int iteration=20; double epi

13、slon=0.1; cvFindCornerSubPix( thd_dst2, corners, corner_count1, cvSize(half_win_size,half_win_size), cvSize(-1,-1),/no ignoring the neighbours of the center corner cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,iteration,epislon) ); / char features_found MAX_CORNERS ; float feature_errors MAX_CORNE

14、RS ; CvSize pyr_sz = cvSize ( thd_dst2->width,thd_dst22->height ); IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); CvPoint2D32f* cornersB = new CvPoint2D32f MAX_CORNERS ; cvCalcOpticalFlowPyrLK( thd_dst2, thd_dst22, pyrA, py

15、rB, corners, cornersB, corner_count1, cvSize(half_win_size,half_win_size), 5, features_found, feature_errors, cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ), 0 ); if(n=3) corner_count4=corner_count3; /-initial guess by cvGoodFeaturesToTrack- cvGoodFeaturesToTrack(thd_dst2,eig_image, /

16、output temp_image,corners,&corner_count3,quality_level,min_distance,NULL,eig_block_size,use_harris); /-draw good feature corners on the original RGB image- int half_win_size=3;/the window size will be 3+1+3=7 int iteration=20; double epislon=0.1; cvFindCornerSubPix( thd_dst2, corners, corner_cou

17、nt3, cvSize(half_win_size,half_win_size), cvSize(-1,-1),/no ignoring the neighbours of the center corner cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,iteration,epislon) ); / char features_found MAX_CORNERS ; float feature_errors MAX_CORNERS ; CvSize pyr_sz = cvSize ( thd_dst2->width,thd_dst22-

18、>height ); IplImage* pyrA = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); IplImage* pyrB = cvCreateImage( pyr_sz, IPL_DEPTH_32F,1 ); CvPoint2D32f* cornersB = new CvPoint2D32f MAX_CORNERS ; cvCalcOpticalFlowPyrLK( thd_dst2, thd_dst22, pyrA, pyrB, corners, cornersB, corner_count3, cvSize(half_win_size,

19、half_win_size), 5, features_found, feature_errors, cvTermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, .3 ), 0 ); / /-draw subpix corners on another original RGB image- if(corner_count!=0) if(n=0) for (int i=0;i<corner_count;i+) /*cvRectangle(thd_dst2, cvPoint(cornersi.x-r,cornersi.y-r), cvPo

20、int(cornersi.x+r,cornersi.y+r), cvScalar(0,0,255),lineWidth);*/ coredot1.x=coredot1.x+cornersi.x; coredot1.y=coredot1.y+cornersi.y; /CvPoint p0 = cvPoint( cvRound( cornersi.x ), cvRound( cornersi.y ) ); /CvPoint p1 = cvPoint( cvRound( cornersBi.x ), cvRound( cornersBi.y ) ); /cvLine( thd_dst222, p0,

21、 p1, CV_RGB(255,0,0), 2 ); coredot1.x=coredot1.x/corner_count; coredot1.y=coredot1.y/corner_count; corners19=corners19; cvRectangle(thd_dst2, cvPoint(coredot1.x-3*r,coredot1.y-3*r), cvPoint(coredot1.x+3*r,coredot1.y+3*r), cvScalar(0,0,255), lineWidth); /to display a coordinate of the third corner co

22、ut<<"x="<<corners2.x; cout<<",y="<<corners2.y<<endl; cvNamedWindow("cvFindCorner0", CV_WINDOW_AUTOSIZE ); cvShowImage( "cvFindCorner0", thd_dst2 ); if(n=1) for (int i=0;i<corner_count;i+) /*cvRectangle(thd_dst2, cvPoint(corners

23、i.x-r,cornersi.y-r), cvPoint(cornersi.x+r,cornersi.y+r), cvScalar(0,0,255),lineWidth);*/ coredot2.x=coredot2.x+cornersi.x; coredot2.y=coredot2.y+cornersi.y; /CvPoint p0 = cvPoint( cvRound( cornersi.x ), cvRound( cornersi.y ) ); /CvPoint p1 = cvPoint( cvRound( cornersBi.x ), cvRound( cornersBi.y ) );

24、 /cvLine( thd_dst222, p0, p1, CV_RGB(255,0,0), 2 ); coredot2.x=coredot2.x/corner_count; coredot2.y=coredot2.y/corner_count; cvRectangle(thd_dst2, cvPoint(coredot2.x-3*r,coredot2.y-3*r), cvPoint(coredot2.x+3*r,coredot2.y+3*r), cvScalar(0,0,255), lineWidth); /to display a coordinate of the third corne

25、r cout<<"x="<<corners2.x; cout<<",y="<<corners2.y<<endl;cvNamedWindow("cvFindCorner1", CV_WINDOW_AUTOSIZE ); cvShowImage( "cvFindCorner1", thd_dst2 ); /cvNamedWindow("FLOW VECTORS", CV_WINDOW_AUTOSIZE ); /cvShowImage( &q

26、uot;FLOW VECTORS", thd_dst222 ); /cvNamedWindow("cvGoodFeaturesToTrack", CV_WINDOW_AUTOSIZE ); /cvShowImage( "cvGoodFeaturesToTrack", imgRGB2 ); /char c=getchar(); return 0;识别与实时动画之间的结合动作的识别与实时动画的生成的完美结合是本项目的难点之一,如何定义表情、动作等参数的范围,如何将识别与实时动画生成的代码结合,如何将识别的参数无损的传递给生成动画的代码都是需要考虑的

27、问题。以本项目中控制模型摇头这一个简单的特征为例,在识别代码中所获取的角度参数存储在参数angle.y中,然后将这个参数传递给实时动画生成部分的代码,在动画生成部分的代码中控制模型旋转的参数是yrot,然后将yrot参数跟随angle.y的参数而变化,从而控制模型的摇头动画。当然项目中需要传递的参数很多,因此也增加了项目的复杂度和这一模块的难度。 三维表示搭建OpenGL程序窗口在Windows编程构建窗口过程的基础上(设计窗口类->注册窗口类->创建窗口->显示及更新窗口->消息循环)设计OpenGL窗口,需要设置着色描述表,将OpenGL连接到着色描述表中,着色描述

28、表会所有的OpenGL的调用命令连接到设备描述表中。因此还要创建设备描述表来绘制OpenGL窗口,设备描述表会将窗口连接到GDI(图形设备接口)中。然后定义一些函数分别用来重置OpenGL场景大小,为透视图设置屏幕,选择和重置投影矩阵和模型观察矩阵,初始化OpenGL场景,定义绘制函数和销毁OpenGL窗口的函数,创建OpenGL窗口。最后在主函数WinMain()中调用这些函数创建OpenGL窗口,并定义消息循环。绘制OpenGL的三维世界;给单调的OpenGL窗口增加色彩,绘制出整个三维的模拟世界,使用OpenGL的绘制函数实现。比如给整个场景添加一个天空和大地,用天空盒的方法实现。载入模

29、型载入MS3D的模型,一个完整的MS3D模型如图所示:MS3D模型的数据结构如下:typedef unsigned char byte;typedef unsigned short word;/MS3D文件头struct MS3DHeaderchar m_ID10;int m_version; PACK_STRUCT;/MS3D顶点信息struct MS3DVertexbyte m_flags;float m_vertex3;char m_boneID;byte m_refCount; PACK_STRUCT;/MS3D三角形信息struct MS3DTriangleword m_flags;

30、word m_vertexIndices3;float m_vertexNormals33;float m_s3, m_t3;byte m_smoothingGroup;byte m_groupIndex; PACK_STRUCT;/MS3D材质信息struct MS3DMaterial char m_name32; float m_ambient4; float m_diffuse4; float m_specular4; float m_emissive4; float m_shininess;/ 0.0f - 128.0f float m_transparency;/ 0.0f - 1.

31、0f byte m_mode;/ 0, 1, 2 is unused now char m_texture128; char m_alphamap128; PACK_STRUCT;/MS3D连接点信息struct MS3DJointbyte m_flags;char m_name32;char m_parentName32;float m_rotation3;float m_translation3;word m_numRotationKeyframes;word m_numTranslationKeyframes; PACK_STRUCT;/MS3D关键帧数据struct MS3DKeyfr

32、amefloat m_time;float m_parameter3; PACK_STRUCT;最后通过loadModelData函数来载入模型,函数定义如下:bool MilkshapeModel:loadModelData( const char *filename )/以二进制的方式打开文件ifstream inputFile( filename, ios:in | ios:binary | ios:nocreate );if ( inputFile.fail()return false;/ 不能打开模型文件,返回失败/返回文件大小inputFile.seekg( 0, ios:end

33、);long fileSize = inputFile.tellg();inputFile.seekg( 0, ios:beg );/分配一个内存,载入文件byte *pBuffer = new bytefileSize;inputFile.read( pBuffer, fileSize );inputFile.close();/读取文件头const byte *pPtr = pBuffer;MS3DHeader *pHeader = ( MS3DHeader* )pPtr;pPtr += sizeof( MS3DHeader );/如果不是一个有效的MS3D文件则返回if ( strncmp

34、( pHeader->m_ID, "MS3D000000", 10 ) != 0 )return false; /如果不能支持这种版本的文件,则返回失败if ( pHeader->m_version < 3 | pHeader->m_version > 4 )return false; /读取顶点数据int nVertices = *( word* )pPtr; m_numVertices = nVertices;m_pVertices = new VertexnVertices;pPtr += sizeof( word );int i;for

35、 ( i = 0; i < nVertices; i+ )MS3DVertex *pVertex = ( MS3DVertex* )pPtr;m_pVerticesi.m_boneID = pVertex->m_boneID;memcpy( m_pVerticesi.m_location, pVertex->m_vertex, sizeof( float )*3 );pPtr += sizeof( MS3DVertex );/读取三角形信息int nTriangles = *( word* )pPtr;m_numTriangles = nTriangles;m_pTriang

36、les = new TrianglenTriangles;pPtr += sizeof( word );for ( i = 0; i < nTriangles; i+ )MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr;int vertexIndices3 = pTriangle->m_vertexIndices0, pTriangle->m_vertexIndices1, pTriangle->m_vertexIndices2 ;float t3 = 1.0f-pTriangle->m_t0, 1.0f-pTrian

37、gle->m_t1, 1.0f-pTriangle->m_t2 ;memcpy( m_pTrianglesi.m_vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 );memcpy( m_pTrianglesi.m_s, pTriangle->m_s, sizeof( float )*3 );memcpy( m_pTrianglesi.m_t, t, sizeof( float )*3 );memcpy( m_pTrianglesi.m_vertexIndices, vertexIndices,

38、 sizeof( int )*3 );pPtr += sizeof( MS3DTriangle );/用来填充网格结构int nGroups = *( word* )pPtr;m_numMeshes = nGroups;m_pMeshes = new MeshnGroups;pPtr += sizeof( word );for ( i = 0; i < nGroups; i+ )pPtr += sizeof( byte );/ flagspPtr += 32;/ nameword nTriangles = *( word* )pPtr;pPtr += sizeof( word );int *pTriangleIndices = new intnTriangles;for ( int j = 0; j < nTriangles; j+ )pTriangleIndicesj = *( word* )pPtr;pPtr += sizeof( word );char materialIndex = *( char* )pPtr;pPtr += sizeof( char );m_pMeshesi.m_materialIndex = materialIndex;m_pMeshesi.m_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论