资源描述
软件工程实践项目总结报告(2010/2011 学年 第 1 学期)项目名称:图像简单处理系统班 级:软件 0801项目成员:2021 年 8 月软件工程实践项目总结报告- 1 -项目评分历次项目阶段性评审得分历次项目阶段性评审得分第 1 次第 2 次第 3 次第 4 次第 5 次第 6 次最终名次2222112项目成员对项目贡献比例(项目成员对项目贡献比例(%)黄超赵剑华孙芳芳谢彩燕胡华东施盛楠19%19%14%16%18%14%项目自我评价与心得体会项目自我评价与心得体会黄超: 在本次项目的开发过程中,我主要担任了项目组长的职务。在对项目进行管理方面进了自己最大的能力与心力去做了,但还是存在很多不足的。通过这次开发,我第一次感受到了开发一个项目的不容易。首先是在项目成员的管理上,由于人员较多,项目不同于其他的基于 WEB 的项目,在任务分配后各小组进度不同,很难进行系统的集成。所以在项目后期集成方面遇到了很多问题。同时通过这次项目开发也令我懂得了更多关于团队之间的协作的重要性。孙芳芳: 我们项目起初是作为创新项目在开发软件,所以我们在暑假的时候就有在学习和开发,起步相对其他小组比较早,但是虽然如此,由于在后阶段并没有像起初一样的积极性,在后面开发的内容并不多,导致最后赶得特别不易,这是我觉得下次开发需要改进的地方。我也从本次实践课中学到了很多东西,比方说团队合作与沟通,比方多新知识的学习等等。赵剑华: 在一个学期的实践中,不仅加强了编码能力,同时也加强了沟通交流能力,另外还锻炼了演讲能力。面对软件的不断重构以及软件功能不断更新,完善,在锻炼编码能力的同时还加强了代码的管理能力,使我的编码风格有很大的改进。在编码完成自己部分功能的同时不断与团队队员之间的沟通,并且不断地了解,使我明白要怎么样更好的与团队之间进行沟通,以及怎么去处理队员与队员之间的问题。这个学期里,为了软件付出了挺多,当然得到了也很多。最主要的不是有多辛酸辛苦,而且能力得到了,这个是最主要的,是生活中最需要的。在此感谢软件工程实践为我带来的一切。施盛楠:软件工程实践中我们已做了一学期图形图像的项目,但是并不成功,下学期要放弃做别的项目,我心里还是比较不痛快的。但是技术存在难题,这让大家有点徒叹奈何的感慨。第一次和团队做项目,大家都是第一次,对于项目的具体流程虽然有老师的指导,但是配合上还是出现了很多问题。我感觉我们小组并没出现什么化学反应,大家都不温不火的在做,一开始兴趣还比较大,但是后来就有点泄气了。可是做软件项目并不是个凭兴趣的事情,这是需要大家负担自己责任的。或许就像老师说的,我们肩上的压力不软件工程实践项目总结报告- 2 -够大吧,人有时候就是要逼自己才好。胡华东: 在此次项目开发过程中,不仅锻炼了自己的代码编程能力,文档编写能力,加强了小组成员之间的沟通能力,而且改善了编码风格。在编码完成自己部分功能的同时不断与团队队员之间的沟通,并且不断地了解,使我明白要怎么样更好的与团队之间进行沟通,以及怎么去处理队员与队员之间的问题。这个学期里,为了软件付出了挺多,当然得到了也很多。最主要的不是有多辛酸辛苦,而且能力得到了,这个是最主要的,是生活中最需要的。在此感谢软件工程实践为我带来的一切。教师评分教师评分优 良 中 及格 不及格软件工程实践项目总结报告- 1 -目 录1 项目概况项目概况 .21.1 团队组成.21.2 开发环境.21.3 需求概述.21.3.1项目背景.31.3.2现状分析.31.3.3项目意义.31.3.4适用范围.42 需求需求说说明明 .42.12.1 分割功能:分割功能: .42.2 合成功能:.52.3 修复功能:.53 架构设计架构设计 .63.1 功能设计.63.2 概要设计.63.2.1 分割功能.63.3 合成功能:.93.4 修补实现:.104 迭代迭代日日志志 .124.1 界面迭代:.124.2 分割迭代:.174.3 合成迭代:.184.4 修补迭代:.195 分工分工情情况况 .216FAQ.2261 环境配置:.2262 代码编写:.3063 项目管理:.416.3.1人员管理.416.3.2时间安排.416.3.3小组沟通问题.426.3.4小组进度缓慢.426.4 其他问题:.426.5 FAQ 的数量统计表 .42软件工程实践项目总结报告- 2 -1 项目概况项目概况1.1 团队组成团队组成本项目一共由 6 人组成,其中根据软件功能又分为 4 个小组,分别为界面设计小组:赵剑华;图像分割小组:黄超、孙芳芳;图像合成小组:XXX、XX;图像修复小组:XXX、XXX。组长由 XXX 担任。1.2 开发环境开发环境本项目开发工具主要使用了 Microsoft Visual Studio.NET 2003,同时还使用了 OpenCV 1.0 的类库,所使用的操作系统为 Windows XP。1.3 需求概述需求概述1.3.1 项目背景项目背景 随着计算机科学的飞速发展,虚拟现实技术已渗透进入了军事、工程、医学、教育等各个方面, 并且在这些领域中起着重要的作用。如海湾战争的美国士兵对周边的环境不觉得陌生,是由于虚拟现实已把他们带入那漫无边际的风尘黄沙,让他们“身临其境”感受到大漠的荒凉。虚拟现实技术是一种可以创建和体验虚拟世界的计算机仿真系统,它利用计算机生成一种模拟环境,是一种多源信息融合的交互式的三维动态视景和实体行为的系统仿真,使用户沉浸到该环境中去。虚拟现实技术是仿真技术的一个重要方向,是仿真技术与计算机图形学、人机接口技术、多媒体技术、传感技术、网络技术等多种技术的集合,是一门富有挑战性的交叉技术、前沿学科和研究领域。美国对此的投资从 80 年代的几千美金到现在 14 个亿足以说明其重要性。软件工程实践项目总结报告- 3 -1.3.2 现状分析现状分析 近年来,计算机图像技术的飞速发展和应用使个人电脑上的美术创作进入一个新的阶段,各种图像处理软件也越来越完善,普及程度不断地提高。其中的图像处理软件 Photoshop 是目前公认的较好用的通用美术设计软件。它包括的功能有:可以对图像进行修饰、对图形进行编辑、对图像的色彩进行处理等。在实际生活中人们通常将数码相机拍摄下来的照片利用图像处理软件来进行编辑和修饰,现在越来越多的用户不仅仅是满足与单纯的图像处理,更希望利用图像处理软件来进行高质量的广告设计、美术创意和三维动画。利用图像处理软件制作图形,要生产一个好的作品包括三个方面的内容:创意、构图能力、计算机表达。即首先要有好的创意,然后对其进行粗略构图,然后借助计算机手段,制作出所构想的最终效果图。由于图像处理软件的功能强大,目前正被越来越多的图像编排、广告和形象设计以及婚纱影楼等领域广泛使用,是非常受欢迎的软件类别。1.3.3 项目意义项目意义本项目拟研究以对象分割、图像修复和图像合成为核心的基于图像的编辑与绘制技术,并基于此开发一个虚拟现实场景图像的特效制作软件系统。首先,研究基于笔刷的对象分割算法,实现少量交互辅助下的便捷景物提取;此技术可用于图像的切割,切割下的图像可以黏贴至其他图像,可用于合成新的场景和图像。利用该项技术人们可以对自己喜欢的场景方便的进行截取,进行图像处理更加方便。然后,研究图像的修复和拼接算法,实现景物移除后所遗留的空白区域的自动填补;使得新的图像看不出剪裁过的痕迹且没有裂缝。利用该技术可以使原有图像在切割掉的基础上依然保持图像的完整性和连续性。最后,研究图像的融合和合成算法,实现克隆景物与已有场景的无缝合成。通过这个系统,我们可以方便地移除图像中不需要的景物、添加进原来没有的景物或者重新编排图像中已有景物的位置,制作和生成新的虚拟现实场景图像。此系统在现实生活中也有很广泛的应用,例如,对于旧照片的修复,照片的合成以及制作电影特效等。同时还可以给人带来很好的娱乐效果,人们可以利用软件工程实践项目总结报告- 4 -系统制作自己喜欢的图像,合成搞笑的图像等。本项目的开发从娱乐和实用的角度都具有很重要的意义。1.3.4 适用范围适用范围本软件适合于对各种格式的数字图像进行处理。2 需求说明需求说明界面功能主要有打开,保存,视图等基本功能,并且对功能分割,修补,合成功能的接口处理。程序分两部分,一部分为分割和修补,另一部分为合成。由两个界面构成,在分割和修补界面,界面中包含打开,圈定分割区域,分割,调色,改变位图等工具栏功能,并且对分割后的图像能够进行修补操作。在合成界面,具有打开图片,选定需要获取的图像信息,以及合成等功能。2.1 分割功能分割功能:总体需求可以归结为基于图像分割算法实现景物的精确提取功能。具体通过以下三个方面实现。在功能方面,实现对所框部分的图像进行前景的提取及显示,对该图像背景和灰度图像进行保存,传给其他功能模块图像的掩膜。在性能方面,时间特性要求:图像对鼠标操作的响应时间较短;能进行较快的处理分割操作。灵活性要求:可以改变分割图像的大小;可以改变所提取前景的颜色。在接口方面,得到界面所给的矩形框出的需要处理的图像的信息,同时得到被框图像的左上角和右下角坐标。传回处理好图像的 image 指针,图像的信息和物体的轮廓线指针及掩膜。2.2 合成功能:合成功能:我们要实现的功能模块是将两幅或多幅图像中的信息综合到一幅图像中,实现添加进的克隆景物与已有景物的无缝集成,满足亮度、颜色和结构信息的连续性和语义合理性。首先我们要对将要进行融合的图片进行预处理,让原图像和待合成图像不存在明显的几何畸变,在图像质量不理想的情况下进行图像融合,如果不经过预处理,很容易造成一些误匹配。软件工程实践项目总结报告- 5 -下一步是图像配准,主是对参考图像和待融合图像中的匹配信息进行提取,在提取出的信息中寻找最佳的匹配,完成图像间的对齐。图像融合的成功与否主要是取决于图像的配准。待融合的图像之间,可能存在平移、旋转、缩放等多种变换或者大面积的同色区域等很难匹配的情况,我们将努力实现能在多种情况下准确找到图像间的对应信息,将图像对齐。在完成图像配准以后,就要对图像进行缝合,并对缝合的边界进行平滑处理,使图像间的合成缝隙不明显,融合更自然。2.3 修复功能:修复功能:图像修复是一项古老的艺术,最早可以追溯到欧洲文艺复兴时期,为了恢复遭受破坏的美术作品,艺术家们利用人的感知力和想象力对作品的裂痕等受损区域进行修补,使其恢复和保持图像的完整性。这一技术就称之为Inpainting(修复,润饰)或称为 Retouching(分涂,修正) 。修复目的:对有划痕或者破损的图片进行数字扫描后加以修复;在图像上面增加或者去除物体,比如电影后期制作中发现图像中出现了多余的物体,麦克风,电线等的移除;修补信息缺失区域,如在数字图像或视频的获取、处理、压缩、传输和解压缩过程中因信息丢失所留下的信息缺损区。需要修补图像文件来源不确定,可由用户自行指定,一般为存储于本地磁盘的特定图像文件。图像文件一般为部分破损、信息缺失、图像信息赘余等情况的的文件。图像修复过程,对受到损坏的图像进行修复重建或者去除图像中的多余物体。例如:照片修复、去除污物、去除文字、去除目标 等行为即为此功能实现效果需求。软件工程实践项目总结报告- 6 -3 架构设计架构设计3.1 功能设计功能设计本软件主要功能分为数字图像的对象分割、图像修复和图像合成四部分。首先,研究基于笔刷的对象分割算法,实现少量交互辅助下的便捷景物提取;此技术可用于图像的切割,切割下的图像可以黏贴至其他图像,可用于合成新的场景和图像。利用该项技术人们可以对自己喜欢的场景方便的进行截取,进行图像处理更加方便。然后,研究图像的修复和拼接算法,实现景物移除后所遗留的空白区域的自动填补;使得新的图像看不出剪裁过的痕迹且没有裂缝。利用该技术可以使原有图像在切割掉的基础上依然保持图像的完整性和连续性。最后,研究图像的融合和合成算法,实现克隆景物与已有场景的无缝合成。通过这个系统,我们可以方便地移除图像中不需要的景物、添加进原来没有的景物或者重新编排图像中已有景物的位置,制作和生成新的虚拟现实场景图像。人们可以利用系统制作自己喜欢的图像,合成搞笑的图像等。3.2 概要设计概要设计3.2.1 分割功能分割功能主要思想主要思想:1通过高斯混合模型来描述前景与背景的分布。2通过迭代方法求取高斯混合模型中的各个参数。3通过非完全标记方法,用户只需利用矩形框标记处背景区域即可。4通过与高斯混合模型进行比较后,将得出的前景轮廓以链表的形式返回。软件工程实践项目总结报告- 7 -功能流程图功能流程图:获取矩形坐标值采样建立高斯模型判断像素点是否匹配输出前景轮廓提取完成图 3代码实现:代码实现:1从用户交互界面得到用户确定的矩形的坐标(左上角和右下角) 。2使用 cvKMeans2()函数对高斯模型进行聚类。从确定的矩形的中心开始采样,并对沿着 2 条对角线方向,取适量像素。3建立高斯混合模型1)定义 5 个高斯模型组件,对其进行初始化(全部为 1 或全部为 0) 。(将每个像素的像素值代入到高斯方程中进行估算,以便将适合的像素点划分到各个高斯模型组件中。 )2)利用迭代最小化方法求取混合高斯模型的参数(主要是均值和方差):混合高斯模型给出的概率密度函数实际上是几个高斯概率密度函数的加权和: 软件工程实践项目总结报告- 8 -其中 . 定义事件 , 则 . 据此可以产生服从上述混合高斯概率密度分布的样本. 混合分布的均值为 方差为 a为未知区域的每个像素点 n 设置高斯混合模型参数 b由图像中各个像素的数据求得高斯混合模型参数 U U (,(, k,k, z)z) = = DD (n(n , , knkn , znzn ) )D D (n(n , , knkn , z)z) = = - - loglog p p ( ( znzn | | nn , , knkn ,),) - - logwlogw (n(n , , knkn ) )其中p () 是高斯概率分布, w () 是该高斯模型的样本数在总样本中权值c利用最小化能量来得到初始分割d回到步骤 a 重复执行,直到收敛为止;e进行边界优化。 4对矩形框中图像的每一个像素进行处理,看是否匹配某个模型,若匹配则将软件工程实践项目总结报告- 9 -该像素标记为 1,若不匹配则标记为 0。 利用 for 循环对矩形内的像素点进行遍历,定义一个表示各像素匹配结果的变量,当像素符合高斯模型的特征值时,将该变量标记为 1,否则标记为0。5利用循环遍历矩形中各像素的匹配特征值,将变量值为 1 的像素点坐标建立成链表返回。3.3 合成功能:合成功能:主要思路主要思路:对于每幅数字图像,我们都可以看成由确定的像素组成,假设图像的每个像素看成由图像分割的每个网格。假设 S 和是无限像素网格中的有限点集。注意到 S 可能包含了网格中的所有像素,也可能只是部分像素。对于 S 中的每个像素 p,Np 是 S 中相关四个像素的集合。表示一对像素,其中 q 属于 Np; 的边界;fp 表示 f 函数中 p 点的值。我们的目的是使得将泊松方程变幻后最终可得到: 其中 f*是 S 中除去领域中的一个已知函数,f 是中定义的一个未知函数。当包含 S 边缘像素时,如果延伸到整个网格区域时,p 有截短领域,|Np|4 也就是 Np 属于.方程可简化成:其中 vpq 是 v((p+q)/2)在向量 pq 上的投影。求解出该方程组,得到新的像素值。功能流程图功能流程图:软件工程实践项目总结报告- 10 -打开需处理图像建立泊松方程解方程更新被融合图像像素,越界像处理返回新图像融合完成图 4代码实现代码实现:代码实现上主要涉及到三个函数,divengence()函数对图像的特征进行提取,求出图像的散度。posionPaste()函数,实现两幅图像的融合。其中 possionPaste中调用的子函数 doCal()对图像泊松方程进行求解。3.4 修补实现:修补实现:主要思想:主要思想:修补模块分为修补主函数,轮廓函数,计算优先级函数,修补函数。1 修补主函数获取上层分割完成后传入的带修补图像指针和 Mask 模板图指针,Mask 模板图作为传入的带修补图像任意像素是否真实的对照表。将待修补图像指针和 Mask 模板图指针传给轮廓函数。2 轮廓函数建立原图像待修补区域轮廓的链表,依操作据轮廓链表节点对图像相应像素进行。对轮廓链表的每个节点调用优先级函数。优先级函数获取传入像素点位置,可计算任意点像素的优先级。3 对轮廓中优先级最大的点调用修补函数,通过搜寻与以该点为样本块最相似的区域来填充样本块,完成修补,更新 Mask 模板图和带修补区域轮廓。重复 23 步,直至轮廓链表为空。功能流程图功能流程图:软件工程实践项目总结报告- 11 -边界不为空边界为空修补主函数Repair()确定待修补区域边界线边界是否为空计算边界点优先级修补优先级最大的点更新Mask模板图修补完成图 5软件工程实践项目总结报告- 12 -4 迭代日志迭代日志4.1 界面迭代:界面迭代: 第一次迭代:界面需求功能的确定,界面初步具有文件,编辑,视图,工具栏等基本功能图 6第二次迭代:增加界面菜单功能,工具栏功能a)文件菜单: 图 7b)编辑菜单:图 8c)视图菜单:软件工程实践项目总结报告- 13 -图 9第三次迭代:程序能够打开图片,并且能画出一个矩形确定范围(格式为JPG 和 BMP)图 10图 11第四次迭代:修改界面,去掉编辑功能,增加 process 菜单:包括功能打开新图,以及获取矩形框里图像 图 12软件工程实践项目总结报告- 14 -Process 菜单: 图 13第五次迭代:添加 New_Image 功能代码:形成副图图 14 图中黑色部分为副图打开的显示位置第六次迭代:完成副图上的打开图片和重新圈定功能:打开图片软件工程实践项目总结报告- 15 -图 15圈定功能:图 16第七次迭代:完成 process 菜单中,cut_image 功能软件工程实践项目总结报告- 16 -图 17Cut_image 功能完成后,圈定出来得部分如图左上显示第八次迭代:完成保存部分图像图 18第九次迭代:重做界面,分割和修补一程序界面,合成一个程序界面 完成分割修补界面:软件工程实践项目总结报告- 17 -图 19文件菜单: 图 20操作: 图 21帮助: 图 22完成合成界面: 图 23文件菜单: 图 24软件工程实践项目总结报告- 18 -4.2 分割迭代:分割迭代:第一次迭代:项目组成立第一次会议,集体讨论分工,以及分组。初步学习 OpenCV 以及数字图像处理方面的知识。了解当今的图像处理软件的前景和现状,并对常用的功能以及原理有所了解。第二次迭代:阅读图像分割的相关方面资料,运用 OpenCV 完成程序:在一幅图片上绘制正弦曲线,改变线宽,填充颜色,实现小球沿曲线滚动。第三次迭代:对第二阶段练习的程序进行完善,巩固软件的编写基础。第四次迭代:对分割功能模块的相关算法进行阅读与理解,确定各个模块间的参数传递以及界面的接口设计,尝试编写功能代码。第五次迭代:从多个算法中确定要使用的算法,并对这些算法进行深刻理解,对功能代码进行些微的变动及完善。第六次迭代:主攻编写功能实现代码及调试,检验算法的完善程度。第七次迭代:与其他小组的进行详细讨论,适当修改代码以便能很好得集成到一起。第八次迭代:与界面进行集成。4.3 合成迭代:合成迭代:第一次迭代:开发工具的学习:开始接触这个工程的时候首先是对开发软件的新工具 OpenCv 的学习. 首先安装 visual studio2003 和 openCV1.0 开发环境,熟悉 visual studio2003 各类工具操作和学习 openCV 基础,编写练习简软件工程实践项目总结报告- 19 -单的 openCV 程序,如图像的读写访问转换等,主要学习 OpenCv 中的函数,函数的参数以及具体如何调用. 练习简单的 openCV 程序,如图像的读写访问转换等。参考的资料主要有。第二次迭代:九月中(1120 号)代码练习:通过小例子练习对图像的操作,主要的程序练习:打开一幅图像,以图像四条边的中点为顶点画一个菱形,在菱形框中填充颜色,并设置菱形边的宽度和颜色,在菱形边上画一个小球,小球沿着菱形边做循环运动.通过对该功能的实现主要熟悉了对图像像素进行操作,以及如何用链表存储图像信息.第三次迭代:明确项目需求,编写需求文档:参加这个项目以后,就软件的整体需求开过多次会议,在代码练习.在明确了项目需求后,通过小组讨论划分了三个小组,分别实现软件的不同功能点.我们小组主要负责图像融合算法的实现.通过参考资料和文档对该功能的进一步理解,这一阶段主要内容是对算法的理解,以及对功能实现的初步架构.初步编写技术文档。第四次迭代:整体架构设计,细化需求文档:在对图像融合算法有了总体理解的基础上,要求对整个功能的实现提出整体的架构设计,并以技术文档的形式进行阐述.小组成员的工作进行进一步细分.根据图像融合算法主要实现的两大块,列方程和求解方程.小组讨论各自负责一个模块. 这一阶段要求对算法有明确的理解和初步实现代码的整体思路,对项目技术文档进行进一步细化,画出整体流程框图,编写部分伪代码。第五次迭代:代码实现:根据先前的思路以及对整个融合功能的理解,通过相关知识,将整体架构设计转化为具体代码,以函数分块实现具体功能.第六次迭代:与主界面进行集成,将融合部分功能与主界面进行集成,确定集成接口和参数类型,修改代码以实现各模块的集成。4.4 修补迭代:修补迭代:第一次迭代:小组内部软件需求分析,软件功能模块架构,研究受损图像的可靠修补算法,并完成对修补算法的可行性分析,画出算法流程图。并学习计算机图形学和计算机图像学的相关技术和知识。软件工程实践项目总结报告- 20 -第二次迭代:根据算法流程图,完成对算法的代码架构,完成修补主函数Repair()代码和各功能点函数代码框架。第三次迭代:对轮廓函数 Boundary()的代码编写,通过获取上层函数传入的待修补图像指针和 Mask 图,确定待修补区域的边界轮廓线。第四次迭代:计算优先级函数 Priority()的置信项和数据项部分代码编写。第五次迭代:完成优先级函数 Priority()剩余部分编写,并对修补函数repairing()搜寻相似样本块部分的代码编写。第六次迭代:完成修补函数 Repairing()的剩余部分代码编写,并对更新函数 Update()进行代码编写,删除被修补像素并更新 Mask 图。第七次迭代:修改修补主函数 Repair(),完成对子函数的调用,并对各函数进行代码走查,发现逻辑错误和语法错误。与其他小组进行集成。第八次迭代:对集成完毕的软件进行测试,发现软件缺陷并对已知的 Bug进行修复。软件工程实践项目总结报告- 21 -5 分工情况分工情况黄超赵剑华孙芳芳谢彩燕施盛楠胡华东项目管理100%0%0%0%0%0%需求分析16.5%(分割功能模块的需求分析)17.5%(界面模块的需求分析)16.5%(分割功能模块的需求分析)16.5%(合成功能模块的需求分析)16%(合成功能模块的需求分析)17%(修补功能模块的需求分析)架构设计16.5%(分割模块的架构设计以及接口设计)17.5%(界面模块的架构设计以及接口设计)16.5%(分割模块的架构设计以及接口设计)16.5%(合成模块的架构设计以及接口设计)16%(合成模块的架构设计以及接口设计)17%(修补模块的架构设计以及接口设计)编码与测试17.5%(分割模块的编码以及测试)17.5%(界面模块的编码以及测试)15.5%(分割模块的编码以及测试)16.5%(合成模块的编码以及测试)15%(合成模块的编码以及测试)17.5%(修补模块的编码以及测试)文档编写24%(项目概述,分工情况以及分割模块的功能模块需求,功能模块架构,开发过程的迭代情况,遇到的问题和解决方案,以及文档总体的整理)25%(项目的顶层架构设计,用户手册以及界面模块的功能模块需求,开发过程的迭代情况,使用手册,遇到的问题和解决方案)12.5%(分割模块的功能模块需求,开发过程的迭代情况,遇到的问题和解决方案)12.5%(合成模块的功能模块架构,开发过程的迭代情况,遇到的问题和解决方案)12.5%(合成模块的功能模块需求,开发过程的迭代情况,遇到的问题和解决方案)13.5%(修补模块的功能模块需求,功能模块架构,开发过程的迭代情况,使用手册,遇到的问题和解决方案)软件工程实践项目总结报告- 22 -6FAQ61 环境配置:环境配置:1 OpenCV 的安装以及在 Microsoft Visual Studio.NET 2003 中的配置问题。解决方法:下载 OpenCV 1.0 安装包,点击安装程序进行安装。配置方法:定制全局选项打开 VC+.net 应用程序,在菜单项里选择:Tools-Options 在列表中,选择 Projects-VC+ Directories 首先,从“Show Directories for”的 list box 中选择“Library files” 单击“Insert New”图标,定位你安装 opencv 的文件夹 假设它安装于“C:Program FilesOpenCV” 在库文件列表中,定位并添加: C:Program FilesOpenCVlib图 25软件工程实践项目总结报告- 23 -然后在 list box 中选择 include 文件,定位并添加以下路径: C:Program FilesOpenCVcvincludeC:Program FilesOpenCVcxcoreincludeC:Program FilesOpenCVotherlibshighguiC:Program FilesOpenCVcvauxincludeC:Program FilesOpenCVotherlibscvcaminclude图 26接下来,选择 list box 中的 source 文件,定位并添加一下路径 C:Program FilesOpenCVcvsrcC:Program FilesOpenCVcxcoresrcC:Program FilesOpenCVcvauxsrcC:Program FilesOpenCVotherlibshighguiC:Program FilesOpenCVotherlibscvcamsrcwindows软件工程实践项目总结报告- 24 -图 27单击选项对话框的“OK” 现在你就正确配置好了全局设置。 创建 新的项目在 Developer Studio 中创建新的 application 从菜单中选择File-New.-Projects 选择“Win32 Application或者Win32 console application,后者更加容易,示例都采取这种方式 软件工程实践项目总结报告- 25 -图 28输入项目名称现则位置 单击 OK,在向导中的直接单击 finish。 图 29软件工程实践项目总结报告- 26 -以上步骤之后 developer studio 将创建一个项目文件夹(缺省与项目同名)、.vcproj 文件、solution.sln 以及三个源文件:.cpp、stdafx.cpp 和 stdafx.h。stdafx 文件是预编译头文件,对于消减编译时间很有用处。例如,假设我们创建了一个新的叫“hello”的项目。打开 hello.cpp,包含 opencv 相关的#include 路径: #include #include #include 然后键入一些 OpenCV 的代码,按 F7 进行 Build,会有些 Link 错误。添加项目的 depencency 从菜单:“Projcet”-“Properties” 选择Linktab - Input - Additional Dependencies。添加所有需要的库 (cxcored.lib cvd.lib highguid.lib cvauxd.lib cvcamd.lib) 软件工程实践项目总结报告- 27 -图 30这就可以了,现在用 F5 编译、运行。 图 31软件工程实践项目总结报告- 28 -2安装 opencv 完后的配置问题解决方法:看老师给的安装文档解决,原来是没有把所需的 lib 文件包含进来 3安装 Microsoft Visual Studio 2003 时出现问题,是计算机系统的问题解决方法:在安装 2003 时放入老师给的 windows XP 系统安装盘4编程前提的奠基解决方案:开发之前必须准备好编程的开发环境。要有开发软件以及其他的必要条件。5安装开发软件解决方案:本次开发使用的是 vs 2003 的软件版本,在安装时需要使用windows XP 的系统环境支持,对于其他的环境支持可能并不是很好。特别对于w7 之类的较为新颖的操作系统兼容性并不强。因此建议使用 XP 的操作系统进行安装开发。在安装 vs 2003 的版本软件时,注意到可能会安装失败。可能是当前操作系统缺失了部分系统文件。解决方法可以选择使用安装光盘安装好缺失的部分。在安装过程中可以自行选择安装部分。建议只需安装需要的部分即可,以免占用较多的硬盘空间造成不便。6OPENCV 的配置问题解决方案:对于较早版本的 vs c+配置较为方便,但是现在的编程工具不断进步,c+6.0 的配置和 vs 2003 的配置又有所不同。在配置中应当注意一些问题 ,特别是路径的正确性,已经库的全部导入,不可缺失。7.开发环境的配置问题,我们小组一开始是在 VC2008 下,但是遇到了很多的问题,尤其反复出现了“MSVCR90D.dll not found”这个问题。解决方法:方法一:在解决方案配置中使用 release 模式,如果再有错误就说明你的程序错了,在 realise 模式下,不能方便的调试。方法二:项目-属性-配置属性-连接器-常规 ,把启用增量连接改为否。8在一开始 OpenCV 安装后“没有找到 cxcore100.dll”软件工程实践项目总结报告- 29 -解决方法:这是因为在安装时选择”将OpenCVbin 加入系统变量”(AddOpenCVbin to the systerm PATH)。 但该选项并不一定能成功添加到系统变量,如果编写的程序在运行时出现“没有找到 cxcore100.dll 说明这个应用程序未启动,重新安装应用程序可能会修复此问题。主要解决方案: 手动在我的电脑-属性-高级-环境变量-系统变量-path 添加 c:program filesopencvbin; 添加完成后需要重启计算机。9在后来改用 VC2005 后也遇到了一个问题,运行程序时出现“应用程序初始化错解决方法:打开 OpenCV 安装目录下的_make 文件夹,用 VS2005 打开其中的opencv.sln,进行批生成(生成-批生成-仅选择所有的 debug|win32 和release|win32-生成)10以上生成过程中有时会出现 “fatal error LNK1181: 无法打开输入文件“cvauxd.lib”和“error C2039: foreground_regions不是CvFGDStatModel的成员”两个错误解决方法:在解决方案资源管理器中打开 “cvaux-Include-External 的cvaux. h 文件,用查找功能找到上述 foreground_regions 成员,会发现此成员已被注释掉了,只要将其上一行末尾的“/”改为“*/”使该成员可见,再次启动项目,应该就可以编译通过了。11一开始使用 opencv 编程时由于头文件忘记添加会有编译没通过,后来就记住了。12调试时遇到 fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include stdafx.h”?解决方法:选择“配置属性”- “c/c+ ”-预编译头-选择“不使用预编译头”。开放环境的配置不正确。解决方法:咨询正确安装了软件的同学,对比步骤,重新进行配置。软件工程实践项目总结报告- 30 -13代码编译时提示找不到相关文件的错误。解决方案:将 OpenCv 安装路径下的 dll 文件复制到系统中。14Vistual studio 2008 运行速度太慢。解决方法:改为使用 Vistual studio 2003。15提示 IplImage 类型未定义,即无法识别 OpenCv 库函数。解决方案:在新建的工程中加入 lib 库,具体做法是:选择工程属性Configuration PropertiesLinker-Input 将需要用到的类库包含进来,如下图:图 3262 代码编写:代码编写:1在项目初始阶段,由于阅读的材料范围比较广泛,每个功能模块都有涉及到并且各个功能模块又有各种算法操作,在没决定用哪些算法之前,这些阅读资料都需阅读,所以有很多具体的算法难以理解解决方法:询问老师并且通过网络对这些算法进行查询,初步有些了解。2在确定具体用 grabcut 算法后阅读针对性的文档,对高斯混合模型以及 em算法(求解最大似然函数极值)的理解过程中遇到问题。解决方法:阅读图书馆有关书籍及询问老师并且通过网络查询,确定建立的高斯模型数目,用 em 迭代算法求解混合高斯模型。3具体的对 opencv 应用通过写程序练习,其中一个的要求是创建图片画菱形并对菱形着色,但是不知道如何改变颜色,这必须对图像有所了解。解决方法:看 opencv 文档中的例子及各种函数的应用情况,利用 CvScalar 和Cvget2D,Cvset2D 来设置图片像素的颜色。4具体的对 opencv 应用通过写程序练习,其中一个的要求是创建图片或者以任意图像作为背景图片显示正弦曲线,可以对曲线的线宽及颜色进行改变,还可以对其内部进行着色,曲线的高矮胖瘦都可以改变,有一个小球沿着曲线进软件工程实践项目总结报告- 31 -行滚动。其中在运用数据结构的时候遇到问题,宏定义线宽为 thickness 也出错,还有在改变线宽时对像素的处理我在上下加宽度值,殊不知由于我们的是正弦曲线而并非很正规的线条,产生的效果并不理想,变成波峰波谷处粗中间细,小球滚动部分,不知道用什么函数。解决方法:数据结构部分我是查看以前学的数据结构书籍;由于 thickness 在opencv 中已有,所以将线宽宏定义名改为 thick;线的宽度部分通过在正弦曲线的法线方向加 2/thick 的方法解决;通过查找,小球滚动部分用cvCircle()及 cvShowImage()方法实现。5具体编写切割代码部分,em 对各个参数的初始化问题及其他编程问题。解决方法:看书、看文档、上网查资料,老师的指导及组员间的相互讨论。6小组成员间需要哪些数据传递,以及与其他组的接口部分的问题。解决方法:老师的指导及组员间的相互讨论7如果打开图片解决方法:、新建一个单文档的应用程序,项目名称为 ShowBitmap、为 CShowBitmapView 类添加下述成员变量和成员函数:/参数定义public: int state; /位图显示状态 CString BmpName; /保存图像文件文件名 CString extname; /保存图像文件扩展名 CBitmap m_bitmap; /创建位图对象 void ShowBitmap(CString BmpName); /用来显示指定位图的函数 BOOL ShowJpgGif(CDC* pDC,CString strPath, int x, int y);、在 CShowBitmap 类的构造函数中,初始化成员变量 state软件工程实践项目总结报告- 32 -/ CShowBitmapView 构造/析构CShowBitmapView:CShowBitmapView() state=0;、为 ID_FILE_OPEN 消息添加响应函数(具体怎么加就不细说了),编写该函数/ CShowBitmapView 消息处理程序void CShowBitmapView:OnFileOpen() /CFileDialog dlg(TRUE,_T(BMP),_T(*.BMP),OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T(位图文件(*.BMP;*.jpg)|*.BMP;*.jpg|); /这行代码可以打开 BMP 格式的图片 CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,_T(位图文件(*.BMP)|*.BMP|jpg 文件(*.jpg)|*.jpg|); /这行代码可以打开 BMP 和 JPG格式的图片/gif 格式图片的打开在这就不列出来了,留给各位自己尝试吧,对于 gif 格式图片的显示图片函数和 jpg 格式图片是同一个函数。 if (IDOK=dlg.DoModal() state=0; BmpName.Format(_T(%s),dlg.GetPathName(); extname = dlg.GetFileExt(); /返回选定文件的扩展文件名软件工程实践项目总结报告- 33 - extname.MakeLower(); if (0=extname.Compare(_T(bmp) ShowBitmap(BmpName); else state=1; Invalidate(); 、编写 BMP 图片显示函数void CShowBitmapView:ShowBitmap(CString BmpName) if (state=0) HBITMAP hBitmap=(HBITMAP)LoadImage(NULL,BmpName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE); m_bitmap.Detach(); m_bitmap.Attach(hBitmap); state=1; Invalidate(); 、编写 jpg 或 gif 格式图片显示程序软件工程实践项目总结报告- 34 -BOOL CShowBitmapView:ShowJpgGif(CDC* pDC,CString strPath, int x, int y) IStream *pStm; CFileStatus fstatus; CFile file; LONG cb; /打开文件并检测文件的有效性 if (file.Open(strPath,CFile:modeRead)& file.GetStatus(strPath,fstatus)& (cb = fstatus.m_size) != -1) HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); LPVOID pvData = NULL; if (hGlobal != NULL) pvData = GlobalLock(hGlobal); if (pvData != NULL) /file.ReadHuge(pvData, cb); /6.0 中可能是用这个函数 file.Read(pvData, cb); /VC2005.NET 中用这个函数 GlobalUnlock(hGlobal); CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); 软件工程实践项目总结报告- 35 - else return false; /打开文件结束 /显示 JPEG 和 GIF 格式的图片,GIF 只能显示一帧,还不能显示动画, /要显示动画 GIF 请使用 ACTIVE 控件。 IPicture *pPic; /load image from file stream if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic) OLE_XSIZE_HIMETRIC hmWidth; OLE_YSIZE_HIMETRIC hmHeight; pPic-get_Width(&hmWidth); pPic-get_Height(&hmHeight); double fX,fY; /get image height and width fX = (double)pDC-软件工程实践项目总结报告- 36 -GetDeviceCaps(HORZRES)*(double)hmWidth/(double)pDC-GetDeviceCaps(HORZSIZE)*100.0); fY = (double)pDC-GetDeviceCaps(VERTRES)*(double)hmHeight/(double)pDC-GetDeviceCaps(VERTSIZE)*100.0); /use render function display image if(FAILED(pPic-Render(*pDC,x,y,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL) pPic-Release(); return false; pPic-Release(); else return false; return true;、修改 OnDraw 函数,实现图片的显示 / CShowBitmapView 绘制void CShowBitmapView:OnDraw(CDC* pDC)软件工程实践项目总结报告- 37 - CShowBitmapDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; if (state=1) if (0 = extname.Compare(_T(bmp) CDC dcImage; if (!dcImage.CreateCompatibleDC(pDC) return; BITMAP bm; m_bitmap.GetBitmap(&bm); dcImage.SelectObject(&m_bitmap); pDC-BitBlt(0,0,bm.bmWidth,bm.bmHeight,&dcImage,0,0,SRCCOPY); else if (0 = extname.Compare(_T(jpg) ShowJpgGif(pDC,BmpName,1,1); 软件工程实践项目总结报告- 38 -8滚动条实现解决方法:、建立工程时,将 View 类继承自 CScrollView 、在 OnInitialUpdate 中添加初始化时 Scroll 的相关属性值 CSize sizeTotal(0,0); SetScrollSizes(MM_TEXT,sizeTotal); 、打开文件 ( 图像后 ) 根据图像的大小,设置滚动属性值 ChangeScrollRange(); / 自定义函数 、在 View 类中添加成员变量。 作用是存储图像显示位置与原点的 offset int m_ImgVScrollPos ;/ VScroll distance int m_ImgHScrollPos ;/ HScroll distance 、滚动处理 添加自定义响应 WM_VSCROLL 、 WM_HSCROLL 消息的事件函数: OnVScroll 、 OnHScroll void CSockIIView : OnVScroll ( UINT nSBCode , UINT nPos , CScrollBar * pScrollBar ) / TODO: Add your message handler code here and/or call default SCROLLINFO si ; GetScrollInfo ( SB_VERT ,& si , SIF_ALL ); m_ImgVScrollPos = si . nPos ; Invalidate ( TRUE ); CScrollView : OnVScroll ( nSBCode , nPos , pScrollBar ); 、图像显示 软件工程实践项目总结报告- 39 -更改 OnPaint 函数中图像显示的代码: dc . BitBlt ( rc . left , rc . top , rc . Width (), rc . Height (), m_pMemDC , rc . left , rc . top , SRCCOPY ); 为: dc.BitBlt(rc.left,rc.top,rc.Width(),rc.Height(),m_pMemDC,(rc.left+m_ImgHScrollPos),(rc.top+m_ImgVScrollPos),SRCCOPY);9在项目开始初期,由于本项目主要利用 OpenCV 的类库来对数字图像进行处理,但 OpenCV 的相关知识是之前从未涉及到过的,所以不知道项目该从何入手。解决方法:由指导老师根据项目的功能来进行认为模块的分类,以及要求我们对相关知识的学习。同时自身加强了对相关方面的程序练习。10在进行用运 OpenCV 进行程序练习时,不清楚如何对图像信息进行处理。解决方法:借阅数字图像处理方面的书籍以及在网上查找资料。11在图像中绘制正弦曲线,改变线宽使线宽在各处相等。解决方法:求曲线各个点的斜率,然后求出垂直方向上的斜率,根据垂直方向修改线宽信息。12在正弦曲线上实现小球滚动。解决方法:使用 cvCircle()方法在图像上曲线上画一个圆,然后使用cvShowImage()方法对图像进行显示,再重新载入原图像取曲线上的下一个点绘制圆,如此循环。13在对图像采样信息进行聚类时,由于要使用到 OpenCV 中的 cvKMean2()方法,在对其参数进行初始化时,错误的把该赋为空值的矩阵也赋了值。解决方法:主要是理解了参数的意义后,对参数进行了重新初始化。14创建一幅图像,如何改变图像的颜色值。解决方法:创建一个指向图像颜色信息的指针,对指针的值进行操作改变指向的颜色信息,对颜色信息进行赋值。15也是关于矩阵方面的问题,由于对 OpenCV 中的矩阵结构理解的不够透彻,无法正确的对矩阵中的元素进行正确赋值,以及在创建矩阵时初始化信息不正确。软件工程实践项目总结报告- 40 -解决方法:在指导老师的指导下,正确的认识了矩阵的结构,然后正确的进行了初始化、赋值。16在对图像信息进行处理时总是存在越界问题。解决方法:对图像的边界进行判断,在对图像像素进行处理时对像素进行边界判断。17在测试聚类结果的正确性时,使用的方法是使用 cvCircle()方法对聚类结果进行输出。在提取像素坐标信息时产生了错误。解决方法:首先是对程序进行调试,检查产生错误的原因,然后对错误原因进行思考,查阅相关方面的资料。18在项目进行至一半时发现对分割功能的实现思想 grabcut 理解产生了偏差。 解决方法:重新仔细理解 grabcut 的实现步骤,重新编写技术文档。19由于各个功能模块由不同的小组负责,各个小组的进度不一致,界面实现后不能进行集成。解决方法:加快落后小组的进度,同时界面将与各功能的接口进行设计。20每次进行项目评审时,由于本项目并不是基于网页开发的,无法将完成的工作以可视化的方法展示出来,导致评分比较低。解决方法:加快项目进度,同时采用图片的方法进行成功展示。21本项目由 6 个人组成,其中又分为 4 各小组,大部分小组是男男组合或女女组合,但存在个别小组是男女组合,相互之间进行沟通比较少,导致项目进度缓慢。解决方法:将强小组成员之间的沟通,加快项目进度。22打开一幅图像对图像部分像素的 RGB 值改变,对修改后的图片进行保存。重新载入该图,以不同的指针对图像信息进行修改,修改后的图片保存后仍留有上一次对图像进行处
展开阅读全文