15中分辨率遥感图像中池塘提取方法研究

15中分辨率遥感图像中池塘提取方法研究

收藏

资源目录
跳过导航链接。
15中分辨率遥感图像中池塘提取方法研究.rar
李炜
李炜的论文.doc---(点击预览)
project副本
project
ReadMe.txt---(点击预览)
gh.txt---(点击预览)
res
DIBAPI.CPP
DIBAPI.H
MainFrm.cpp
MainFrm.h
project.aps
project.clw
project.cpp
project.dsp
project.dsw
project.h
project.ncb
project.opt
project.plg
project.rc
projectDoc.cpp
projectDoc.h
projectView.cpp
projectView.h
Resource.h
StdAfx.cpp
StdAfx.h
池塘4.bmp
压缩包内文档预览:

资源预览需要最新版本的Flash Player支持。
您尚未安装或版本过低,建议您

15中分辨率遥感图像中池塘提取方法研究,15,分辨率,遥感,图像,池塘,提取,方法,研究
编号:27036732    类型:共享资源    大小:453.46KB    格式:RAR    上传时间:2019-11-26 上传人:qq77****057 IP属地:江苏
12
积分
关 键 词:
15 分辨率 遥感 图像 池塘 提取 方法 研究
资源描述:
15中分辨率遥感图像中池塘提取方法研究,15,分辨率,遥感,图像,池塘,提取,方法,研究
内容简介:
目 录摘 要目 录第一章引言111 社会需求分析112遥感图像地物提取研究现状113 本文研究的内容、研究目标214 本文解决的关键问题215 本文的技术路线3第二章 遥感图像的读取与显示421 遥感图像的简介422 遥感图像的读取和显示编程实现过程7第 三 章 区域选择931 区域选择的基本思想932 区域选择具体实现过程10第 四 章 阈值的计算1441 Otsu 方法介绍1442 计算阈值15第 五 章 池塘提取1751 池塘的特点1752 池塘提取与显示18第 六 章 信息文件的创建、读取与保存2161 信息文件简介2162 信息文件的创建2163 信息文件的读取2264 信息文件的保存23第 七 章 结语与展望24参考文献25致谢26目录2752摘 要我国是一个农业大国,在农业生产中,池塘既是重要灌溉水源,也是主要水产养殖的重要基地,很多地区都有大量池塘,池塘目标出现在遥感图像中十分普遍。因此,池塘提取是引起人们注意的重要问题。以前常用手工的方式逐个把池塘从中分辨率遥感图像中提取绘制出来,工作量大且繁琐。为了提高工作效率,避免传统方法的弊端,如何利用池塘在中分辨率遥感图像中的特征实现人机交互式池塘提取是需要研究的重要问题。本文正是为了满足社会的需求,着重研究了从遥感图像中提取池塘的方法,根据池塘不同于其他水系地物且有自己的特点,提出了简单、实用的人机交互式模型进行池塘的提取方案,并在 Visual C+ 6.0环境下开发出从中分辨率遥感图像中提取池塘功能。该功能包括遥感图像的读取、区域的选择、阈值的计算、池塘提取、提取结果的存盘。关键词:遥感图像;池塘;提取;区域选择;图像读取;人机交互。ABSTRACTOur country is a big country for agriculture. And in the commercial agriculture, the pond is the important source using for irrigating as well as the important base using for water breeding. So a lot of ponds exist in many areas, and the pond appearing in the remote image is very popularity. We have usually used the handcrafted method of abstracting pond from middle resolution remote image on the before time, and the work is very hard. And to increase work efficiency and to avoid the abuse of tradition way, how to abstract pond from middle resolution remote image by human-computer manner becomes an important question that need studying. To satisfy the requirement of the society the paper studied the method of abstracting pond from remote image, and produced an easy and utility method which comes true by human-computer interaction based on the characteristic of pond different from other water system objects, and developed a set of software using for abstracting pond from middle resolution remote image in the condition of Visual C+ 6.0.And the functions of the software contain reading remote image, selecting areas, counting key number, abstracting pond, saving the result.Keywords: remote image; pond; abstracting; selecting areas; reading image; human-computer;第一章引言11 社会需求分析遥感技术是20世纪60年代兴起并迅速发展起来的一门综合性探测技术。它是在航空摄影测量的基础上,随着空间技术、电子计算机技术等当代科技的迅速发展,以及地学、生物学等学科发展的需要,发展形成的一门新兴技术学科。遥感作为获取自然资源、生态环境和人类活动等时空数据的重要来源和技术手段,人们对从遥感数据中抽取各种相关专题信息的需求和兴趣日益提高。遥感影像,特别是中高分辨率的卫星遥感影像的发展,使遥感影像的深入应用成为可能,为GIS数据的更新、GIS的应用提供了有利的条件。在信息时代的背景下,需要对海量的数据进行快速的处理,遥感图像是地理信息系统的巨大数据,但要真正成为有效的数据源,依赖于遥感图像的计算机自动识别分类和数据格式的直接转换。因此,遥感图像中的地物的计算机智能识别提取一直是图像处理的研究热点。我国是一个农业大国,在农业生产中,池塘既是重要灌溉水源,也是主要水产养殖的重要基地,很多地区都有大量池塘,池塘目标出现在遥感图像中十分普遍。以前常用手工的方式把池塘从遥感图像中逐一提取绘制出来,工作量大且繁琐。因此,如何利用池塘在遥感图像中的特征实现人机交互方式池塘提取,以减少把池塘从遥感图像中提取绘制出来工作量,已成为需要解决的重要问题。12遥感图像地物提取研究现状目前利用卫星遥感数据进行水体自动提取已取得到了广泛的研究,从统计分类到模拟人类视觉规律的神经网络分类方法、从引入地学专家知识的专家系统到采用推理模式识别技术的遥感影像理解系统,它们从不同方面、不同程度地提高了精度,各种方法相继提出并得到应用。刘建波等利用密度分割法从影像中提取水体的分布范围,陆家驹等分别利用阈值法、色度判别法、比率测算法从影像中识别水体,都金康等利用决策树方法从SPOT4影像中提取了水体信息,并有效地去除了阴影,如钟邵南等采用分区的方法,研究了从 Radarsat 图像上提取水体。目前,利用中分辨率遥感图像进行水体信息提取的研究尚不多见,针对池塘的提取提出的解决方案甚少,在分析研究了水体及背景地物的特征的基础上,根据池塘又不同于其他水系地物且有自己的特点,提出了简单、实用的人机交互式模型进行池塘的提取方案。13 本文研究的内容、研究目标由于池塘是水重要载体,水在遥感图像的特点直接反映了池塘在影像中的特点。水体的反射主要在蓝绿光,吸收率很强,特别在近红外、中红外波段有很强的吸收带,反射率几乎为零,因此在全色遥感影像中,水体的色调很黑,与周围的植被和土壤有明显的反差,水体的位置和轮廓比较清晰,很容易识别和判读。根据水所反映出的池塘特点,本文提出了提取池塘的方法,并在MicrosoftVisualC+6.0环境下编程实现,建立一个菜单实现功能选择,并编制一个池塘提取程序模块,实现人机交互方式从遥感影像中提取池塘。14 本文解决的关键问题图像截取问题:从整幅图中截取所要处理的区域的图像过程中,一般采用闭合的多边形截图方法,要想获取多边形内的区域,必须判断图像中的点是在多边形之内还是之外,如何快速、占用最少资源情况下获取多边形内的点,是本文解决的关键问题之一。阈值确定问题:在所选择的区域,池塘与池塘的堤坝内部图像灰度分布一般较均匀,而边界及其附近点的灰度跃变常常较大。因此,阈值选择的恰当与否直接对池塘的提取产生重要影像,如果阈值过大或过小,有可能将池塘和池塘的堤坝边界的部分都归属于池塘,或都没有归属到池塘,即出现了错分。通过经验输入阈值,很难确定边界的部分归属的平衡性,因此,阈值的自适应选取问题是本课题关键问题之一。提取信息保存问题:在池塘比较密集的遥感图像上,一次的工作量比较大,于是需要多次作业,这就需要将上次作业的成果保存到文件中,下次作业时能自动把上次的结果加载进来,如何实现这些功能成为关键问题之一。15 本文的技术路线读取遥感图像获取选择的区域根据选择的区域求相应的阈值根据阈值进行分类根据池塘的特点从分类结果中提取池塘将提取的信息保存图 1.5 技术路线图第二章 遥感图像的读取与显示21 遥感图像的简介211 图像的表现形式地物的特征性一般以图像的形式记录下来。地面反射或发射的电磁波信息经过地球大气到达遥感传感器,传感器根据地物对电磁波的反射强度以不同的亮度表示在遥感图像上。遥感传感器记录电磁波的形式有两种:一种以胶片或其他的光学成像载体的形式,另一种以数字形式记录下来,也就是所谓的光学图像和数字图像的方式记录地物的遥感信息。一、 光学图像一个光学图像,如像片或透明正片、负片等,可以看成是一个二维的连续的光密度函数。像片上的密度随坐标 x, y 变化而变化,如果取一个方向的图像,则密度随空间而变化,是一条连续的曲线。我们用函数f(x, y)来表示,这个函数的特点是:它是连续变化的,其值是非负的和有限的,用下式表示:0 f(x, y) 一般在光学密度仪上,量测光学图像某一点的密度值为03或04中的某一值,或用透过率表示为11/1000或11/10000,它们间的关系为:D = log(1/F)式中:D-密度; F-透过率。以上描述的是单一图像。如果对同一地区在不同时间获取的图像,则可用下标来区分其时间特性:0 ft(x, y) 同样对于不同图像则可用下标L来区分其特性,写成fl(x, y)二、 数字图像数字图像是一个二维的离散的光密度函数。相对光学图像,它在空间坐标(x, y)和密度上都离散化,空间坐标x, y仅取离散值:x=x0+mxy=y0+my式中:m = 0,1,2,m-1;x,y为离散化的坐标间隔。同时f(x, y)也仅取离散值,一般取值区间为0,1,2,127或0,1,2,255等。数字图像 可以用一个二维矩阵表示,即(x, y) =(0, 0) (0, 1) (0, n-1) (m-1, 0) (m-1, 1) (m-1, n-1)(1, 0) (1, 1) (1, n-1)矩阵中每个元素称为像元,一幅数字图像,实际上是由每个像元的密度值排列而成的一个数字矩阵。212 遥感图像的存储格式遥感数字图像必须以一定的格式存储,才能有效果的进行分发和利用。遥感技术被应用以来,遥感数据采用过很多格式,后来 Landsat Technical Working Group 提出了LTWG格式,即世界标准格式。从1982年以后包括陆地卫星、法国SPOT卫星等卫星遥感数据都采用了世界标准格式,目前世界各地遥感数据主要采用LTWG格式。LTWG格式有BSQ格式和BIL格式两种。所谓BSQ格式即按波段记载数据文件,陆地卫星4,5号CCT的格式就是BSQ格式。在这种格式的CCT磁带中,每一个文件记载的是某一个波段的图像数据。BIL格式是一种按照波段顺序交叉排列的遥感数据格式,BIL格式与BSQ格式相似。除了遥感专用的数字图像格式之外,还有其他类型的图像格式。在进行遥感图像处理时,往往需要在不同系统之间进行,所以对几种其他图像的格式的认识也是必需的。这里,我们主要介绍两种应用很广泛的图像格式。一种被称为TIFF格式,另一种与Windows操作系统密切相关的格式 BMP格式。标签化图像文件格式(TIFF)是Aldus公司与微软公司合作开发的一个多用途可扩展的用于存储栅格图像的文件格式。TIFF不仅能很好的处理黑白、灰度、彩色图像,而且还支持对图像象素值的许多数据压缩方案。TIFF用标签化字段保存信息。文件以一个文件头和至少一个图像文件目录(IFD)开始。IFD中有许多12byte的目录索引项,每条索引都是一个标签化字段中的相关信息。它带有一个标签,一个表示数据类型的常量,数据的长度和一个用来表示字段数据的位置与文件起始处之间的偏移的量。如果字段数据不多于4byte,则将其直接放在目录索引项中。TIFF文件头占用8byte,头两个字节控制着文件中剩下的所有数据的解释方式。这两个字节指示了文件中的字节顺序。其中”MM”和”II”分别表示Motorola或Intel字节顺序,Intel字节顺序按照从低位到高位的顺序排序,而Motorola顺序按相反的顺序排序。IFD的头两个字节给出目录中的索引项的数目。紧接着就是目录。每个目录索引项都是一个保存有与相应标签化字段有关的信息的12byte结构。IFD以一个4byte的值结束。该值为零,表示最后一个IFD的结束,否则它就是指向另一个IFD的指针。现在很多的遥感图像处理系统是基于Windows操作系统的。而Windows把BMP作为其图像的标准格式,而且内含了一套支持BMP图像处理的API函数。本文所使用的遥感图像格式为BMP格式,下面着重对BMP图像格式进行分析。BMP格式一般由两大部分组成:文件头和实际图像信息。其结构如图所示位图文件头结构 BITMAPFILEHEADER位图信息头结构 BITMAPINFOHEADER调色板 Palette位图象素数据 DIB Pixels图 2.1.2 BMP文件结构各结构定义分别如下:1 位图文件头结构typedef struct tagBITMAPFILEHEADER UINT bfType;文件类型标识,表示文件类型,必须是0x424D,即字符串BM DWORD bfSize;表示文件的大小,以字节为单位 UINT bfReserved1;表示保留字段1 UINT bfReserved2;表示保留字段2 DWORD bfOffBits;表示文件头到图像数据的偏移字节数BITMAPFILEHEADER;2 位图信息头结构typedef struct tagBITMAPINFOHEADER DWORD bitSize;结构所需的字节 LONG biWidth;以像素为单位的位图宽度 LONG biHeight;以像素为单位的位图高度 WORD biPlanes;目标设备的颜色位面数,必须是1 WORD biBitCount;每像素的位数,应是1,4,8,24 DWORD bitCompression;位图的压缩类型 DWORD biSizeImage;图像尺寸大小,一般置0 LONG biXPelsPerMeter;最佳目标设备水平分辨率 LONG biYPelsPerMeter; 最佳目标设备垂直分辨率 DWORD biClrUsed;位图所用的颜色表中颜色索引数 DWORD biClrImportant;最重要的颜色索引数,如为0,则全部重要BITMAPINFOHEADER; 3 调色板调色板是一个RGBQUAD结构数组,共有在BITMAPINFOHEADER中定义的biClrUsed个元素。RGBQUAD结构定义如下:typedef struct tagRGBQUAD BYTE rgbBlue; 蓝色值 BYTE rgbGreen;绿色值 BYTE rgbRed;红色值 BYTE rgbReserved;备用字段RGBQUAD;4 位图图像数据在调色板信息之后,存储的是图像的实际数据,图像数据有压缩和不压缩两种情形,而且位图图像数据存储与实际图像相反,是从底向上顺序逐行存放。22 遥感图像的读取和显示编程实现过程在实现数字图象处理的过程中,主要是通过对图像中的每一个像素点运用各种图像处理算法来达到预期的效果,所以进行图像处理的第一步,也是我们最关心的问题,是如何得到图像中每一个像素点的亮度值;为了观察和验证处理的图像效果,另一个需要解决的问题是如何将处理前后的图像正确的显示出来。BMP灰度图像作为Windows环境下主要的图像格式之一,以其格式简单,适应性强而倍受欢迎。这种文件格式就是每一个像素用8bit表示,显示出来的图像是黑白效果,最黑的像素的灰度(也叫做亮度)值为0,最白的像素的灰度值为255,整个图像各个像素的灰度值随机的分布在0到255的区间中,越黑的像素,其灰度值越接近于0,越白(即越亮)的像素,其灰度值越接近于255;与此对应的是在该文件类型中的颜色表项的各个RGB分量值是相等的,并且颜色表项的数目是256个。在进行图像处理时,操作图像中的像素点的值就是要得到图像阵列;经过处理后的图像像素点的值需要存储起来;显示图像时要正确实现调色板、得到位图的尺寸信息等。结合这些问题,下面针对性的给出了操作灰度BMP图像时的部分函数实现代码及注释。BMP位图包括位图文件头结构BITMAPFILEHEADER、位图信息头结构 BITMAPINFOHEADER、位图颜色表RGBQUAD和位图像素数据四部分。处理位图时要根据文件的这些结构得到位图文件大小、位图的宽、高、实现调色板、得到位图像素值等等。这里要注意的一点是在BMP位图中,位图的每行像素值要填充到一个四字节边界,即位图每行所占的存储长度为四字节的倍数,不足时将多余位用0填充。有了上述知识,可以开始编写图像处理的程序了,关于在VC的开发平台上如何开发程序的问题这里不再赘述。在开发该图像处理程序的过程中,本文充分利用了程序的文档视图结构,在程序中直接使用了一些API函数来操作图像。启动Visual C+,生成一个名为project的单文档程序,在处理图像应用程序的文档类(CProjectDoc.h)中声明如下宏及公有变量:#define WIDTHBYTES(bits) (bits) + 31) / 32 * 4)/计算图像每行象素所占的字节数目;HANDLE m_hDIB;/存放位图数据的句柄;CPalette* m_palDIB;/指向调色板Cpalette类的指针;CSize m_sizeDoc;/初始化视图的尺寸,该尺寸为位图的尺寸;读取灰度BMP位图可以根据BMP位图文件的结构,操作BMP位图文件并读入图像数据,为此我们充分利用了VC的文档视图结构,重载了文挡类的 OnOpenDocument()函数,这样用户就可以在自动生成程序的打开文件对话框中选择所要打开的位图文件,然后程序将自动调用该函数执行读取数据的操作。该函数的实现代码见附录。这种方法是通过CFile类对象的操作来读取位图文件的,它需要分析位图中的文件头信息,从而确定需要读取的图像长度。显示DIB位图数据可以通过设备上下文CDC对象的成员函数CDC:Bitblt()或CDC:StretchBlt()来实现,也可以通过API函数SetDIBBitsToDevice()或StretchDIBBits()来实现,函数中具体所用到的各个参数的意义可以参考 MSDN。其中StretchDIBBits()和CDC:StretchBlt()可以将图像进行放大和缩小显示。在视图类的 OnDraw()函数中正确的显示位图,具体实现代码见附录。第 三 章 区域选择31 区域选择的基本思想要选择一个区域,必须用一个闭合的图形如正方形、圆形、椭圆形、多边形等作为选择区域的边界,各种闭合的图形相比较而言,多边形比较灵活直观,而且符合人的思维习惯。本文就是用多边形作为选择区域的边界。多边形是由多条直线段组成,而且这些线段不能相互交叉,而直线段又是由起始点和终止点决定。由于组成多边形的线段是连续的,即前一条线段的终止点是下一条线段的起始点。因此,存储一个多边形只需将多边形的结点按照顺时针或逆时针存储在一个有序链表中,显示多边形只要将这些结点按顺序用直线连接起来,最后将链表的首节点和尾节点用直线连起来,就构成了一个闭合多边形。用多边形作为边界只能表达人所想要的目标范围,很多时候,我们不光想划一个范围,更多的是要获取指定区域的有用信息。本文所用的指定区域内的信息包括象素的坐标和象素的灰度值。要想获取这些信息,我们必须判断哪些点在指定多边形区域内。一般思想是:按扫描线的顺序,扫描线与多边形各边求交点,然后判断扫描线上相邻的交点之间区域是否在多边形内,具体方法见下一节322 获取多边形内的象素点。我们选择一个区域,并且能够获取区域内的相关信息,所做的这一切都为求选择区域的阈值和对信息提取以及将提取结果显示出来做好数据准备工作,为了能将区域内的相关信息在程序结束后仍存在,必须将这些信息写入文件,当需要时再从文件中读入。下面用图框的形式描述区域选择整个思想过程:绘制一个多边形判断象素点是否在多边形内获取多边形内象素点的信息(坐标和灰度值)将多边形内象素点的信息保存到一个文件中图3.1 区域选择基本思想32 区域选择具体实现过程321 绘闭合多边形在绘制多边形的时候,我们能捕获的信息是鼠标所点的点坐标,这些点就是我们绘制多边形的结点,此外,在捕获点坐标过程中,这些点是有顺序的,即顺时针或逆时针。因此,在存储这些点的的同时,要存储点的顺序。本文采用有序链表来存储这些结点。HEAD第一点坐标 NEXT第二点坐标 NEXT最后点坐标 NEXT第一点坐标 NEXT图3.2.1 坐标点链表在上面链表中,我们用一个HEAD指针指向链表第一个节点,每个节点都有一个指针NEXT指向下一个节点,这样就使各坐标点顺序保存下来了。我们还可以从上面链表看出,链表最后一个节点保存的坐标信息与第一个节点保存的信息相同,之所以这样,是因为方便多边形的绘制,当第一点与第二点用直线连接,第二点与第三点用直线连接,依次类推,倒数第二点与最后一点连接后,要闭合多边形,必须将最后一点与第一点连接,如果按照上面方法存储,没有必要把最后一点与第一点连接作为一个特殊过程来对待,即按照一个固定的模式:链表的上一个节点的坐标点与下一个节点的坐标点连接。322 获取多边形内的象素点一种常用的方法是按扫描线顺序,计算扫描线与多边形的相交区间,再求这些区间的象素。区间的端点可以通过计算扫描线与多边形边界线的交点获得。如图3.2.2-1所示,扫描线6与多边形的边界线交于四点A、B、C、D。这四点把扫描线分为五个区间0,2,2,3.5,3.5,7,7,11,11,12。其中,2,3.5,7,11两个区间落在多边形内,该区间内的象素为多边形内象素点。其他区间为多边形外象素。图3.2.2-1 一个多边形与若干扫描线这里的四个交点在计算时未必是按从左到右顺序获得。例如,当多边形采用顶点序列P1P2P3P4P5表示时,把扫描线6分别与边P1P2,P2P3,P3P4,P4P5,P5P6,P6P1相交,得到交点序列D、C、B、A,必须经过排序,才能得到从左到右,按x递增顺序排列的交点x坐标序列。关于一般多边形内象素获取过程,对于一条扫描线,可以分为四个步骤:(1)求交:计算扫描线与多边形过边的交点;(2)排序:把所有交点按递增顺序进行排序;(3)交点配对:第一个与第二个,第三个与第四个等等。每对交点就代表扫描线与多边形的一个相交区间;(4)输出:把这些相交区间内的象素的灰度值和坐标输出到一个外部文件中。在这个过程中必须要解决的一个特殊问题:当扫描线与多边形顶点相交时,交点的取舍问题。现在分析这个问题。当扫描线与多边形顶点相交时,会出现异常情况。例如图3.2.2-1所示,扫描线2与P1相交。按前述方法求得交点(x坐标)序列2,2,8。这将导致2,8区间内的象素取背景色,而这个区间的象素正是属于多边形内部。所以,我们拟考虑当扫描线与多边形的顶点相交时,相同的交点只取一个。这样,扫描线2与多边形边的交点序列就成为2,8。正是我们所希望的结果。然而,按新的规定,扫描线7与多边形边的交点序列为2,9,11。这将导致错把2,9区间作为多边形内部来看待。为了正确的进行交点取舍,必须对上述两种情况区别对待。在第一种情况,扫描线交于一顶点,而共享顶点的两条边分别落在扫描线的两边。这时,交点只算一个。第二种情况,共享交点的两条边在扫描线的同一边,这时交点作为零个或两个,取决于该点是多边形的局部最高点还是局部最低点。具体实现时,只需检查顶点的两条边的另外两个端点的y值。按这两个y值中大于交点y值的个数是0,1,2来决定是取零个、一个、还是两个。例如,扫描线1交顶点P2,由于共享该顶点的两条边的另外两个顶点均高于扫描线,故取交点P2两次。这使得P2象素作为多边形内部点来看待。再考虑扫描线2。在P1处,由于P6高于扫描线,而P2低于扫描线,所以该交点只算一个。而在P6处,由于P1和P5均在下方,所以扫描线7与之相交时,交点算零个,该点作为多边形外点看待。以上的分析,在进行多边形内象素点获取过程中,必须解决的问题。下面进一步讨论算法的步骤。HEADA NEXTB NEXTC NEXTD NEXT图3.2.2-2 交点链表为了计算每条扫描线与多边形各边的交点,最简单的方法是把多边形的所有边或结点放在一个表中,如图3.2.1所示。在处理每条扫描线时,按顺序从表中取出所有的边,先判断是否与扫描线相交,再判断是否为特殊情况,即扫描线过边端点,然后求交,把交点坐标存放在一个链表中,如图3.2.2-2所示,由于每条扫描线的交点横坐标相同,所以链表中只需存放各交点的纵坐标信息,接着对链表进行冒泡排序,由于共享交点的两条边在扫描线的同一边,这时交点作为零个处理,链表中不会存在这样的交点,而扫描线交于一顶点,且共享顶点的两条边分别落在扫描线的两边的情况,可能使链表中存在纵坐标相同的交点,而我们希望这种情况下的交点只存在一个,因此,对链表进行冒泡排序之后,还必须有一个合并过程,使纵坐标相同的交点在链表中只保留一个。做完上面的一系列的工作之后,我们就可以获得我们想要的区间A,B,C,D,在这些区间内的点就是我们最终想获得的多边形内象素点。上面我们获得的只是一条扫描线上多边形内象素点,要想获得所有多边形内象素点,我们必须对所有相关的扫描线进行上面的一个过程。为了获得起始扫描线和终止扫描线,即相关的扫描线区间,我们必须从多边形所有结点中求出横坐标最大值和最小值。323 保存选择区域内的信息当我们获取了我们想要的像素点,即区域内的点坐标,可以通过坐标在位图图像数据表中查找到我们所要的像素颜色索引号,在通过索引号在调色板中找到颜色值,由于本文所使用的是SPOT全色灰度影像,索引号等于灰度值,故只需通过坐标在位图图像数据表中查找到我们所要的像素颜色索引号,就可以获取灰度值。为了使灰度值和像素坐标对应起来,在我们保存所需要的像素灰度值时,相应的必须保存相应的点坐标信息。这些坐标和灰度值是我们下面进行阈值计算、池塘提取的数据源。为了方便下面进行阈值计算和提取池塘显示,而阈值计算用到区域内的灰度信息,提取池塘显示要用到象素点坐标,因此我们用一个链表来存储所选区域内每一点的灰度值和坐标,方便用到这些数据时可以直接从内存中读取;为了避免在程序结束后,或我们选择一个新的区域时,以前已获取的信息丢失,我们必须将已获取的这些坐标和灰度值存储在一个外部文件里面。信息保存格式可以见第 6 章 信息文件的创建、读取与保存。第 四 章 阈值的计算41 Otsu 方法介绍图像阈值自动选取方法的研究长期以来吸引着众多学者,寻找简单实用、自适应强的阈值自动选取方法是这些研究者们的共同目标。Otsu 在1979 年提出的最大类间方差法(有时也称之为大津方法) 一直被认为是阈值自动选取方法的最优方法,该方法计算简单,在一定条件下不受图像对比度与亮度变化的影响,因而在一些实时图像处理系统中得到了很广泛的应用。下面介绍Otsu基本思想:记f(i,j)为MN图像(i,j)点处的灰度值,灰度级为m,不妨假设f(i,j)取值0,m-1。记p(k)为灰度值为k的频率,则有:p(k)=nk/n ,nk 为图像中灰度为k的象素数,n为图像的总像素数。假设用灰度值t为阈值分割出的目标与背景分别为:f(i,j)=t,于是:目标部分比例: 目标部分点数: (4-1) (4-2)背景部分比例: 背景部分点数: (4-3) (4-4)目标均值: 背景均值: (4-5) (4-6)总均值: (4-7)求图像最佳阈值g的公式为: (4-8)该式右边括号内实际上就是类间方差值,阈值g 分割出的目标和背景两部分构成了整幅图像,而目标取值0 (t) ,概率为1 (t) ,背景取值1 (t) ,概率为0 (t) ,总均值为,根据方差的定义即得该式。因方差是灰度分布均匀性的一种度量,方差值越大,说明构成图像的两部分差别越大,当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小,因此使类间方差最大的分割意味着错分概率最小,这便是大津方法的真正含义。其实,换一种思想也能很好的理解大津方法。0 (t) 和1 (t) ,可以分别代表目标和背景的中心灰度,则代表整幅图像的中心灰度,要使目标和背景得到最好的分割,当然希望分割出的目标尽量远离图像中心,即(0 (t) - )2 (或|0 (t) - | ) 尽量大,背景也尽量远离中心,即(1 (t) - )2 (或|1 (t) - | )尽量大,由于希望两者都大,于是有:1) 两者之加权和最大 (4-9)2) 两者之积最大 (4-10)由于 (4-11),且0 (t)1 (t),因此,0(t) (0 (t) - )2+1(t) (1 (t) - )2=(-0 (t)( 1 (t)- ) (4-12),可见二者是等价的。根据上面大津方法的分析,它要求求取的阈值使得分割出的两部分都尽量远离图像中心,大津方法无外乎是以灰度均值来代表目标与背景。灰度均值反映了图像灰度分布的均匀性 ,目标与背景区内部一般较均匀,而边界及其附近点的灰度跃变常常较大,因此,灰度均值近似的反映了图像边界点的灰度跃变情况,因此,用大津法算出来的阈值,能够合理的将目标与背景区分离开来。42 计算阈值本文所用的计算阈值方法,就是上面介绍的Otsu法。由Otsu法实际上是在一个灰度范围m,n内,找一个灰度为t作为阈值,使g=0(t) (0 (t) - )2+1(t) (1 (t) - )2 (4-13)最大。所以我们必须求出灰度范围m,n内每个灰度所对应的g值,再对这些g值进行比较,找出域值t。下面具体介绍计算阈值过程。由于我们是计算的一个指定区域内的阈值,所选择的区域涉及到的灰度值范围是0,255的几个不连续的子区间,但考虑到处理的影像灰度连续性和计算的方便,从选择的区域找出灰度值最大值Max和最小值Min,用Min,Max作为选择的区域涉及到的灰度值区间。这样我们就完成了灰度区间确定,下面开始计算灰度为k的频率p(k)。在求频率的过程中,可以把灰度为k的频率存储在数组pk中,由于求每个灰度值所对应的频率,需要统计灰度值为k出现的次数nk和整个区域像素个数M,而我们所要的所有灰度值信息在323 保存选择区域内的信息过程中已经存放到一个链表中,为了统计灰度值为k出现的次数nk和整个区域像素个数M,必须对这个链表遍历。上面求Max和Min同样需要遍历链表,因而,统计灰度值为k出现的次数nk和整个区域像素个数M可以和求Max和Min同步进行。下面可以按照上一节Otsu法所提供的公式,将以上得到的结果带入公式进行计算即可。当得到我们所想要得的阈值后,一方面存放到阈值链表中,方便下面提取池塘时直接从内存中调用,另一的方面,为了使程序结束后,我们求阈值的工作不会浪费,将阈值存放在和区域信息保存的相同文件里,具体格式可以见第 6 章 信息文件的创建、读取与保存。第 五 章 池塘提取51 池塘的特点我们要提取指定区域内的池塘,可以将所选择的区域分两类来看,即水体和土壤。水体是池塘的主体,它反映了池塘的大小、空间位置、特征。我们提取池塘实际上是间接的通过提取水体来实现的。池塘不同于其他地物的一个方面,就是池塘的环境,普遍的池塘都是用篱笆筑的,这些篱笆的反射特征可以用土壤的反射特征来代替。下面我们分析水体和土壤的反射特性,就可以看出池塘在地物提取中的特点。遥感图像反映的是影像区域内地物的电磁波辐射能量,有明确的物理意义遥感图像数据中像元亮度值的大小极其变化主要由地物类型的变化引起。从图 5.1-1可以看出,在全色波段上,水体反射率都低于土壤反射率,并且在可见光波段之前,水的吸收少、发射少而大量透射,在红外波段,水体吸收的能量高于可见光波段,即使水很浅,水体也几乎全部吸收了近红外及中红外波段内的全部入射能量,所以水体在近红外及中红外波段的反射能量很少,而土壤在这两个波段内的吸收能量较小,且有较高的反射特性。通过以上比较可以看出,在全色遥感影像中,水体和土壤有明显的区别并反映在影像上,水体呈现出暗色调,而土壤则相对较亮。图 5.1-1 水体和其他几种常见地物反射曲线池塘除有上面的特点外,在实际提取过程中,池塘在影像中往往是成群出现,由图5.1-2可见,在图中有许多比较规则的黑色小方块,呈网格状,即池塘群,这些池塘单个的面积比较小,而且比较多,池塘之间间隔比较小,如果手工单个的逐一勾画,不仅工作量大、十分麻烦,而且难以确定提取信息、容易出错,能否找到一种可以只需人工画出池塘群的外廓,而将每个池塘自动提取出来的方法呢?本文找到了这种方法,并实现了,具体方法在下一节介绍。图 5.1-2 全色遥感影像图52 池塘提取与显示在前一章中,我们通过大律法求出所选区域的阈值,在上一节中,我们分析了池塘的特点,在池塘提取过程中,先选择一个区域,即池塘群的外廓,再求区域的阈值,然后用所求的阈值来对池塘进行提取。在遥感影像中,由于池塘呈现的色调暗,周围相对比较亮,用阈值来说,就是归属于池塘的像素点的灰度值小于阈值,池塘周围的像素灰度值大于阈值,这样我们就可以以阈值为依据对池塘进行提取。但在提取过程中,我们不但要获取归属于池塘的像素点的灰度信息,还要它的空间信息,即像点坐标。这点已经在323 保存选择区域内的信息节中做好了铺垫,其中所说的链表,可以用图5.2表示。HEAD像点1坐标 灰度值 NEXT像点2坐标 灰度值 NEXT像点n-1坐标 灰度值 NEXT像点n坐标 灰度值 NEXT图5.2 区域信息链表其实池塘提取的过程,也是遍历上面链表的过程,在这之前,先要规定归属于池塘像点的统一标志颜色值,为了便于观察,可以用彩色,比如用绿色表示池塘,其他用用蓝色表示。当我们判断每个像点的归属之后,就可以将它高亮显示出来。在对链表的每一个节点处理过程如下:(1)读取灰度值(2)阈值来判断该点是否归属于池塘,如果是,则该点的灰度值小于阈值,将该点用绿色高亮显示,如果否,则该点的灰度值大于阈值,将该点用蓝色高亮显示。在具体编程实现像点高亮显示时,不是通过更改原图像的数据来实现的,而是通过CDC类的一个画点函数SetPixel()来实现的,它包含两个接受参数,一个是点坐标,一个是点的颜色值。下面是提取的池塘结果图:图 5.2 池塘提取结果图从上面的提取结果可以看出,本文所使用的提取方案能将池塘(绿色部分)从影像中提取出来,提取过程简单,而且单个池塘的边缘比较清晰,具有一定的先进性。但有部分地方池塘的边缘比较模糊,引起的主要原因是周围环境的色调相对于整个选择区域来说趋近于池塘的色调,具体解决办法是适当增加选择区域的个数,即减少每个选择区域的面积。以上结果图,总共有4个选择区域,我们可以将池塘边缘比较模糊的地方单独作为一个选择区域,这样可以提高池塘提取的准确度。第 六 章 信息文件的创建、读取与保存61 信息文件简介信息文件包含的信息主要包括选择区域内的像素点坐标和对应的灰度值,以及每个选择区域的阈值。信息文件是一次作业结束后的成果,是能继续上次作业的保障。62 信息文件的创建首先,要确定一个合适的文件名和扩展名。本文在实践中,为了使信息文件名与原图像名相关,扩展名不同于其他文件,命名格式为:”chitang-”+原图像名+”.bmpinfo”,比如一个原图像名为”text.bmp”的文件,它所对应的信息文件是”chitang-test1.bmpinfo”。再就是确定信息文件的书写格式,本文在实践中,自定义了一个简单的文件数据书写格式,如图6.2所示文件头(标志符s)数据正文块头(标志符b)数据块正文(图像点坐标和灰度值)数据块正文结尾(标志符e)域值选择区域1的信息数据数据正文块头(标志符b)数据块正文(图像点坐标和灰度值)数据块正文结尾(标志符e)域值选择区域n的信息数据图6.2 信息文件格式63 信息文件的读取当我们结束一次作业之后,下次继续上次的作业时,我们希望上次作业的结果能在这次作业过程中能显示出来,使整个作业过程好像是一个连续的过程。所以在装载原是图像的同时,也要装载信息文件。信息文件装载过程,实际上是数据读取的过程,在这个过程中,可以申请一个内存空间来存储,当然,我们也可以不申请一个内存空间,当我们需要信息文件的数据时直接从存放在硬盘上的信息文件读取,但这个过程受硬盘读取数据速度的影响,在刷新时会出现短暂性的停留,这会对我们正常作业产生影响。而申请一个内存空间来存储信息文件的数据就可以解决这个问题,因为从内存读数据速度明显要快得多,刷新时短暂性的停留不会被人眼察觉。由于信息文件是由选择区域的像点坐标、灰度值和相应的阈值组成,在编程实践中,用一个链表来管理每个选择区域数据信息,每个选择区域数据信息再用一个链表来存储,而专门用一个链表来存储阈值,为了使阈值和相应的选择区域对应起来,阈值存储顺序与选择区域数据信息存储顺序一致,具体结构如下图6.3所示。指向选择区域2指针NEXT指向选择区域3指针NEXT指向选择区域n指针NEXT选择区域数据信息管理链表指向选择区域1指针NEXT像点1坐标 灰度值 NEXT像点n坐标 灰度值 NEXT像点1坐标 灰度值 NEXT像点n坐标 灰度值 NEXT像点1坐标 灰度值 NEXT像点n坐标 灰度值 NEXT像点1坐标 灰度值 NEXT像点n坐标 灰度值 NEXT每个选择区域的像点数据信息阈值链表选择区域1阈值NEXT选择区域2阈值NEXT选择区域3阈值NEXT选择区域n阈值NEXT图6.3 内存数据存储结构图64 信息文件的保存一般的文件保存方法是:在程序结束前,将内存中的数据导入到硬盘上的文件中,或者在程序运行过程中,创建一个临时文件,当程序结束前,将临时文件的内容存放到指定的文件中。本文在实践中,为了简便,对数据的保存采用实时、自动的方式,即当我们选择好一个区域后,自动将选择的区域内信息数据保存在事先已创建的文件中,写入方式是通过CStdioFile类的函数WriteString()以字符串的形式写入文件。为了不使新写入的数据覆盖了原来的数据,在每次写入数据前,先将文件指针移到文件末尾。第 七 章 结语与展望本文通过人机交互的方式从遥感影像中提取池塘地物,在很大程度上,减少了人的工作量,提高了工作效率。但实现计算机自动识别以实现自动提取,一直是人们所期望的,目前有许多学者在这方面做了深入的研究,这也是本文未来的研究方向。参考文献1 贾永红.数字图像处理.武汉:武汉大学出版社,20032 孙家抦.遥感原理与应用.武汉:武汉大学出版社,20033 孙家广.计算机图形学.北京:清华大学出版社,20004 付仲良.图像阈值选取方法.计算机应用,20005 路威.全色遥感影像面状地物半自动提取方法研究:学位论文.郑州,解放军信息工程大学6 吴一全,朱兆达.图象处理中阈值选取方法30 年(19621992)的进展(一).数据采集与处理,1993.8(3):193-2017 吴一全,朱兆达.图象处理中阈值选取方法30 年(19621992)的进展(二).数据采集与处理,1993.8(4):268-2778 都金康,黄永胜,冯学智等.卫星影像的水体提取方法及分类研究J.遥感学报,2001,5(3):214-2199 杜云艳,周成虎.水体的遥感信息自动提取方法J.遥感学报,1998,2(4):264-26810 盛永伟,肖乾广.应用气象卫星识别薄云覆盖下的水体J.环境遥感,1994,9(4):247-25511 周俊,晏非,孙曼.基于区域分割合并的建筑物半自动提取方法. 海洋测绘,2005(1)12 王润生. 图像理解M.北京:国防科技大学出版社,1995.1013 王涛.硕士论文,遥感图像人机交互判读系统的研制,199914 许殿元、丁树柏等.遥感图像信息处理,宇航出版社,1990 :141 16315 宁书年等.遥感图像处理与应用M.地震出版社,1995 :9 1316 苏俊英,曹辉,张剑清.高分辨率遥感影像上居民地半自动提取研究J.武汉大学学报.信息科学版,2004 ,26(9):792794.致谢毕业论文终于完成了,正是我的指导老师于子凡老师的指导、鼓励、和帮助使我能够顺利完成我的毕业论文。在这里,对我的指导老师表示崇高的敬意和真诚的感谢!当我遇到困难几乎想放弃的时候,是我的老师鼓励促使我继续研究下去;当我遇到理论和技术难题几乎一筹莫展的时候,是我的老师耐心讲解使我茅塞顿开,使我能够继续研究下去。同时对于我的指导老师为本文的选题、研究计划到最后论文成稿付出的劳动表示真诚的感谢!我的指导老师刻苦钻研、勤奋工作、献身于科研事业的精神是我永远学习的榜样!本人在大学四年的学习中,得到了孟令奎老师、余洁老师、于子松老师、张文军老师、魏克让老师、唐雪华老师、刘既林老师、胡庆武老师、黄长青老师、孙家柄老师、舒宁老师、郑肇葆老师、卢健老师、刘继琳老师、袁修孝老师、蔡列飞老师、马吉苹老师、倪玲老师、马洪超老师、刘良明老师、巫兆聪老师、李刚老师、 培其老师、刘莉老师、吴琼老师、谢云老师、高卫松老师、李洪老师多年来对我的栽培,在此对他们表示真诚的感谢!附录/ MainFrm.h#include ProgStatusBar.hclass CMainFrame : public CFrameWndprotected: / create from serialization onlyCMainFrame();DECLARE_DYNCREATE(CMainFrame)public:virtual BOOL PreCreateWindow(CREATESTRUCT& cs);public:virtual CMainFrame();virtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;protected: / control bar embedded membersCProgStatusBar m_wndStatusBar;CToolBar m_wndToolBar;/ Generated message map functionsprotected:/AFX_MSG(CMainFrame)afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnProgress(UINT pct);/AFX_MSGDECLARE_MESSAGE_MAP();/ MainFrm.cpp#include stdafx.h#include project.h#include MainFrm.hIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)ON_MESSAGE(MYWM_PROGRESS,OnProgress)ON_WM_CREATE()END_MESSAGE_MAP()static UINT indicators =ID_SEPARATOR, / status line indicatorID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,;CMainFrame:CMainFrame()CMainFrame:CMainFrame()int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) |!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)TRACE0(Failed to create toolbarn);return -1; / fail to createif (!m_wndStatusBar.Create(this) |!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)TRACE0(Failed to create status barn);return -1; / fail to createm_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);return 0;BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs)if( !CFrameWnd:PreCreateWindow(cs) )return FALSE;return TRUE;void CMainFrame:AssertValid() constCFrameWnd:AssertValid();void CMainFrame:Dump(CDumpContext& dc) constCFrameWnd:Dump(dc);void CMainFrame:OnProgress(UINT pct)m_wndStatusBar.OnProgressk(pct);/ ProgStatusBar.h :class CProgStatusBar : public CStatusBarpublic:CProgStatusBar();CProgressCtrl& GetProgressCtrl() return m_wndProgBar;public:public:virtual CProgStatusBar();void OnProgressk(UINT pct);protected:CProgressCtrl m_wndProgBar;/ the progress barafx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnSize(UINT nType, int cx, int cy);DECLARE_MESSAGE_MAP()DECLARE_DYNAMIC(CProgStatusBar);/ ProgStatusBar.cpp#include stdafx.h#include project.h#include ProgStatusBar.h#include afxpriv.hIMPLEMENT_DYNAMIC(CProgStatusBar, CStatusBar)BEGIN_MESSAGE_MAP(CProgStatusBar, CStatusBar)ON_WM_CREATE()ON_WM_SIZE()END_MESSAGE_MAP()CProgStatusBar:CProgStatusBar()CProgStatusBar:CProgStatusBar()int CProgStatusBar:OnCreate(LPCREATESTRUCT lpcs) lpcs-style |= WS_CLIPCHILDREN; VERIFY(CStatusBar:OnCreate(lpcs)=0); VERIFY(m_wndProgBar.Create(WS_CHILD, CRect(), this, 1); m_wndProgBar.SetRange(0,100); return 0;void CProgStatusBar:OnSize(UINT nType, int cx, int cy) CStatusBar:OnSize(nType, cx, cy); CRect rc; GetItemRect(0, &rc); m_wndProgBar.MoveWindow(&rc,FALSE);void CProgStatusBar:OnProgressk(UINT pct) CProgressCtrl& pc=m_wndProgBar; DWORD dwOldStyle=pc.GetStyle(); DWORD dwNewStyle=dwOldStyle; if (pct0) dwNewStyle |=WS_VISIBLE; else dwNewStyle &=WS_VISIBLE; if (dwNewStyle != dwOldStyle) SetWindowText(NULL); SetWindowLong(pc.m_hWnd, GWL_STYLE, dwNewStyle); pc.SetPos(pct); if (pct=0)GetParent()-PostMessage(WM_SETMESSAGESTRING,AFX_IDS_IDLEMESSAGE);/ projectDoc.h#include dibapi.hstruct ofkint k;struct ofk *next;struct blockCPoint newpoint;int color;struct block *next;struct pblockstruct block *pb;struct pblock *next;class CProjectDoc : public CDocumentprotected: / create from serialization onlyCProjectDoc();DECLARE_DYNCREATE(CProjectDoc)public:HDIB m_hDIB;BOOL FileFlag;struct ofk *hfork;struct pblock *hpblock;public:CString m_filename;public:virtual BOOL OnNewDocument();virtual void Serialize(CArchive& ar);virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);public:virtual CProjectDoc();virtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;protected:protected:DECLARE_MESSAGE_MAP();/ projectDoc.cpp#include stdafx.h#include project.h#include projectDoc.hIMPLEMENT_DYNCREATE(CProjectDoc, CDocument)BEGIN_MESSAGE_MAP(CProjectDoc, CDocument)END_MESSAGE_MAP()CProjectDoc:CProjectDoc()hfork=NULL;hpblock=NULL;FileFlag = FALSE;m_filename=text;CProjectDoc:CProjectDoc()BOOL CProjectDoc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;return TRUE;void CProjectDoc:Serialize(CArchive& ar)if (ar.IsStoring()/ TODO: add storing code hereelse/ TODO: add loading code herevoid CProjectDoc:AssertValid() constCDocument:AssertValid();void CProjectDoc:Dump(CDumpContext& dc) constCDocument:Dump(dc);BOOL CProjectDoc:OnOpenDocument(LPCTSTR lpszPathName) if (!CDocument:OnOpenDocument(lpszPathName)return FALSE;CWnd* pFrame = AfxGetMainWnd();/ TODO: Add your specialized creation code hereCFile m_File; FileFlag = m_File.Open(lpszPathName,false,NULL); /读取BMP文件的函数,返回的参数m_hDIB是操作BMP图象的句柄,在以后的图象处理操作中需要用到次变 /量,这就是把它定义为成员变量的原因 m_hDIB = ReadDIBFile(m_File);m_filename=m_File.GetFileName(); / FileFlag = TRUE表示文件已打开 UpdateAllViews(FALSE);/显示选择区域 CString filename,filepath;filename=m_filename;filepath.Format(.chitang-%sinfo,filename);CStdioFile myfile;CString m_Strk=0;char m_Str1,m_Str2;CString putinx,putiny,putcolor,m_String;CPoint drawpoint;if(!myfile.Open(filepath,CFile:modeReadWrite,NULL)return false;myfile.SeekToBegin();myfile.ReadString(m_String);if(m_String=)return false;myfile.SeekToEnd();int pct=0;for(;)struct block *hblock=NULL;char c_char;/读取域值myfile.Seek(-5,CFile:current);myfile.ReadString(m_Strk);/读入内存struct ofk* pofk;pofk=(struct ofk* )malloc(sizeof(struct ofk);pofk-k=atoi(m_Strk);pofk-next=hfork;hfork=pofk;/将指针移到数据块头for(;)myfile.Seek(-1,CFile:current); myfile.ReadString(&m_Str1,2);if(m_Str1=n)myfile.Seek(-1,CFile:current);if(m_Str1=b)break;myfile.Seek(-1,CFile:current);/读取数据块正文到内存for(;)myfile.ReadString(putinx); if(putinx=e)break;myfile.ReadString(putiny); myfile.ReadString(putcolor);drawpoint.x=atoi(putinx);drawpoint.y=atoi(putiny);struct block* plb;plb=(struct block* )malloc(sizeof(struct block);plb-newpoint=drawpoint;plb-color=atoi(putcolor);plb-next=hblock;hblock=plb;/if(atoi(putcolor)SetPixel(drawpoint,RGB(0,255,0);/else/pDC-SetPixel(drawpoint,RGB(0,0,255);/判断是否数据块已经读完for(;)myfile.Seek(-1,CFile:current); myfile.ReadString(&m_Str2,2);if(m_Str2=n)myfile.Seek(-1,CFile:current);myfile.Seek(-1,CFile:current);if(m_Str2=b)break;struct pblock* ptoblock;ptoblock=(struct pblock* )malloc(sizeof(struct pblock);ptoblock-pb=hblock;ptoblock-next=hpblock;hpblock=ptoblock;pct=pct+5; if (pFrame) pFrame-SendMessage(MYWM_PROGRESS,pct);myfile.Seek(-1,CFile:current);myfile.ReadString(&c_char,2);if(c_char=s)break;myfile.Seek(1,CFile:current);myfile.Close(); if (pFrame) pFrame-SendMessage(MYWM_PROGRESS,0);return TRUE;/ projectView.h :struct nodeCPoint newpoint;struct node *next;struct node *before;class CProjectView : public CViewprotected: / create from serialization onlyCProjectView();DECLARE_DYNCREATE(CProjectView)public:CProjectDoc* GetDocument(); struct node *head; struct node *rea;struct node *acrosspoint;struct node *back;CPoint lastpoint;CPoint m_point;BOOL bg;public:BOOL CANDRAW;public:virtual void OnDraw(CDC* pDC); / overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);public:virtual CProjectView();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:/AFX_MSG(CProjectView)afx_msg void OnChoosepoly();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);afx_msg void OnRButtonDown(UINT nFlags, CPoint point);afx_msg void OnMouseMove(UINT nFlags, CPoint point);/AFX_MSGDECLARE_MESSAGE_MAP();/ projectView.cpp #include stdafx.h#include project.h#include projectDoc.h#include projectView.h#include math.hIMPLEMENT_DYNCREATE(CProjectView, CView)BEGIN_MESSAGE_MAP(CProjectView, CView)/AFX_MSG_MAP(CProjectView)ON_COMMAND(ID_CHOOSEPOLY, OnChoosepoly)ON_WM_LBUTTONDOWN()ON_WM_RBUTTONDOWN()ON_WM_MOUSEMOVE()/AFX_MSG_MAP/ Standard printing commandsON_COMMAND(ID_FILE_PRINT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_DIRECT, CView:OnFilePrint)ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView:OnFilePrintPreview)END_MESSAGE_MAP()CProjectView:CProjectView()/ TODO: add construction code hereCANDRAW=FALSE;head=rea=NULL;acrosspoint=back=NULL;lastpoint=(-1,-1);bg=false;m_point=(-1,-1);CProjectView:CProjectView()BOOL CProjectView:PreCreateWindow(CREATESTRUCT& cs)/ TODO: Modify the Window class or styles here by modifying/ the CREATESTRUCT csreturn CView:PreCreateWindow(cs);/ CProjectView drawingvoid CProjectView:OnDraw(CDC* pDC)CProjectDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here /首先判断BMP文件是否打开 if(pDoc-FileFlag = FALSE)return; /获取文件句柄 HDIB bmpHandle = pDoc-m_hDIB; LPSTR pDib = (LPSTR) :GlobalLock(HGLOBAL) bmpHandle); /获取图象的高度和宽度,以设定图象显示的区域 DWORD Width = DIBWidth(pDib); DWORD Height = DIBHeight(pDib);:GlobalUnlock(HGLOBAL) bmpHandle); CRect bmpRect(0,0,Width,Height); /创建图象的调色板 CPalette pPal; CreateDIBPalette(bmpHandle,&pPal); /显示Bmp图象的函数,每个变量的意思可以参看该函数 PaintDIB(pDC-m_hDC,&bmpRect,bmpHandle,&bmpRect,&pPal); CPen mpen;mpen.CreatePen(PS_SOLID,1,255);pDC-SelectObject(mpen);struct node *p;/if(head!=NULL)if(rea!=NULL)/for(p=head;(p-next)!=NULL;p=p-next) for(p=rea;(p-before)!=NULL;p=p-before)pDC-MoveTo(p-newpoint);/pDC-LineTo(p-next)-newpoint);pDC-LineTo(p-before)-newpoint);/显示struct pblock *ppblock;struct ofk *ppk;for(ppblock=pDoc-hpblock,ppk=pDoc-hfork;ppblock!=NULL&ppk!=NULL;ppblock=ppblock-next,ppk=ppk-next)int m_myk;m_myk=ppk-k;struct block *myblock;for(myblock=ppblock-pb;myblock!=NULL;myblock=myblock-next) if(myblock-color)SetPixel(myblock-newpoint,RGB(0,255,0); else pDC-SetPixel(myblock-newpoint,RGB(0,0,255);/ TODO: add draw code for native data hereBOOL CProjectView:OnPreparePrinting(CPrintInfo* pInfo)/ default preparationreturn DoPreparePrinting(pInfo);void CProjectView:OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: add extra initialization before printingvoid CProjectView:OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)/ TODO: add cleanup after printing#ifdef _DEBUGvoid CProjectView:AssertValid() constCView:AssertValid();void CProjectView:Dump(CDumpContext& dc) constCView:Dump(dc);CProjectDoc* CProjectView:GetDocument() / non-debug version is inlineASSERT(m_pDocument-IsKindOf(RUNTIME_CLASS(CProjectDoc);return (CProjectDoc*)m_pDocument;#endif /_DEBUG/ CProjectView message handlersvoid CProjectView:OnChoosepoly() / TODO: Add your command handler code hereCANDRAW=TRUE;void CProjectView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default /CProjectDoc* pDoc = GetDocument(); /ASSERT_VALID(pDoc);if(CANDRAW) bg=TRUE;m_point=point;struct node *p;p=(struct node *)malloc(sizeof(struct node);p-newpoint=point;if(head!=NULL)if(head-next!=NULL)if(head-newpoint.x=rea-newpoint.x&head-newpoint.y=rea-newpoint.y)struct node *t;for(;(head-next)!=NULL;)t=head;head=head-next;free(t);t=head;rea=NULL;head=NULL;free(t); if(head=NULL)rea=p;p-next=head; p-before=NULL;if(head!=NULL)head-before=p;head=p;CPen mypen;mypen.CreatePen(PS_SOLID,1,(0,0,255);CClientDC dc(this);dc.SelectObject(mypen);if(head!=NULL)if(head-next!=NULL)dc.MoveTo(head-next)-newpoint); dc.LineTo(head-newpoint);/pDoc-UpdateAllViews(NULL);CView:OnLButtonDown(nFlags, point);void CProjectView:OnRButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CProjectDoc* pDoc = GetDocument();CWnd* pFrame = AfxGetMainWnd(); if(pDoc-FileFlag = FALSE)return;LPBITMAPINFO lpbmi;LPBITMAPCOREINFO lpbmc;WORD wNumColors;LPSTR lpDIBBits;BYTE* lpSrc;LONG OneLineBytes; HDIB bmpHandle = pDoc-m_hDIB; LPSTR lpDIB = (LPSTR) :GlobalLock(HGLOBAL) bmpHandle); LONG lWidth = DIBWidth(lpDIB); LONG lHeight = DIBHeight(lpDIB);lpbmi=(LPBITMAPINFO)lpDIB;lpbmc=(LPBITMAPCOREINFO)lpDIB; wNumColors=:DIBNumColors(lpDIB);lpDIBBits=:FindDIBBits(lpDIB);OneLineBytes=WIDTHBYTES(lWidth*8);if(wNumColors!=256)MessageBox(不是256色灰度图);:GlobalUnlock(HGLOBAL) bmpHandle);return; CString filename,filepath;filename=pDoc-m_filename;filepath.Format(.chitang-%sinfo,filename);CStdioFile myfile;if(!myfile.Open(filepath,CFile:modeReadWrite,NULL)myfile.Open(filepath,CFile:modeReadWrite|CFile:modeCreate,NULL);CString m_String1,m_String3,m_String4;char m_String2;struct block *hblock=NULL;m_String1.Format(s);m_String3.Format(b);m_String4.Format(en);myfile.SeekToBegin();myfile.ReadString(&m_String2,2);if(m_String2!=s)myfile.SeekToBegin();myfile.WriteString(m_String1);myfile.SeekToEnd();myfile.WriteString(m_String3);if(CANDRAW)struct node *p;p=(struct node *)malloc(sizeof(struct node);if(rea!=NULL)p-newpoint=rea-newpoint;p-next=head; p-before=NULL;if(head!=NULL)head-before=p;head=p;/获取参与计算的顶扫描线和最底扫描线if(head!=NULL)struct node *p;int max,min;max=min=head-newpoint.y;for(p=head;p!=NULL;p=p-next)if(p-newpoint.ymax)max=p-newpoint.y;if(p-newpoint.ynewpoint.y;/求每条扫描线在多边形内的部分for(int m_i=min;m_inext)!=NULL;p=p-next)/先判断多边形一条边是否与扫描线交,再求交点if(p-newpoint.y-m_i)*(p-next)-newpoint.y-m_i)newpoint; endPoint=(p-next)-newpoint; q=(struct node *)malloc(sizeof(struct node); q-newpoint.y=m_i; q-newpoint.x=(beginPoint.x-endPoint.x)*(m_i-beginPoint
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
提示  人人文库网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:15中分辨率遥感图像中池塘提取方法研究
链接地址:https://www.renrendoc.com/p-27036732.html

官方联系方式

2:不支持迅雷下载,请使用浏览器下载   
3:不支持QQ浏览器下载,请用其他浏览器   
4:下载后的文档和图纸-无水印   
5:文档经过压缩,下载后原文更清晰   
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

网站客服QQ:2881952447     

copyright@ 2020-2025  renrendoc.com 人人文库版权所有   联系电话:400-852-1180

备案号:蜀ICP备2022000484号-2       经营许可证: 川B2-20220663       公网安备川公网安备: 51019002004831号

本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知人人文库网,我们立即给予删除!