GDAL的C#版本虽然在很多算法接口没有导出,但是在读写数据中的接口基本上都是完全导出了。使用ReadRaster和WriteRaster方法来进行读写,同时对这两个方法进行了重载,对于常用的数据类型可以不用指定数据类型直接进行读取即可。但是对于复数类型就有点复杂了。下面就针对GDAL如何来读取复数数据来进行一个简单的说明。
 
   我们知道,在使用GDAL读取数据的时候使用的是ReadRaster这个函数,这个函数重载了6个,函数声明分别如下,以Dataset的ReadRaster为例,Band类中的ReadRaster与之类似。
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.Byte[], System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.Int16[], System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.Single[], System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.Double[], System.Int32, System.Int32, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   OSGeo.GDAL.Dataset.ReadRaster(System.Int32, System.Int32, System.Int32, System.Int32, System.IntPtr, System.Int32, System.Int32, OSGeo.GDAL.DataType, System.Int32, System.Int32[], System.Int32, System.Int32, System.Int32);
 
   前五个函数的声明基本上完全一致,除了第五个参数,分别是Byte[],Int16[],Int32[],Single[],Double[]。分别对应的是将图像中的像素值使用8U,16U\16S,32U\32S,32F和64F。如果图像数据是普通的数据(这里指的是除复数图像之外),那么这五个函数完全可以满足所有的需求。但是如果图像是复数图像(复数图像就是图像的像素值是由复数组成的,比如通过傅立叶变换后的图像),这时,上面的五个函数就有点爱莫能助了,就需要上面的第六个函数来出场救急了 www.lefeng123.com
 
   第六个函数的声明和C\C++的声明完全一致,使用C\C++的同学对这个接口应该比较熟悉。这个函数可以替代上面五个函数来使用,但是比较麻烦的时,就是传入的参数会比较多,首先看一个例子。使用普通的方式来读取一个单波段8U的数据(Landsat5的一个数据)。从数据中读取100×100大小的数据,直接使用ReadRaster的Byte接口。
 
   static void ReadRaster()
 
   {
 
   string strFile = @"D:\Data\landsat\etp139r26_5t19900902\p139r26_5t19900902_nn1.tif";
 
   OSGeo.GDAL.Gdal.AllRegister();
 
   OSGeo.GDAL.Dataset ds = OSGeo.GDAL.Gdal.Open(strFile, OSGeo.GDAL.Access.GA_ReadOnly);
 
   int []bandmap = new int [1];
 
   bandmap[0] = 1;
 
   //读取Byte类型
 
   Byte[] data = new Byte[100 * 100];
 
   OSGeo.GDAL.CPLErr err = ds.ReadRaster(3000, 2000, 100, 100, data, 100, 100, 1, bandmap, 0, 0, 0);
 
   //将读取的数据输出
 
   for (int i = 0; i < 100; i++ )
 
   {
 
   for (int j = 0; j < 100; j++)
 
   {
 
   Console.WriteLine("{0}", ddata[i*100+j]);
 
   }
 
   }
 
   Console.WriteLine("done\n");
 
   }
 
   下面看看如何使用第六个接口来完成上面的功能,代码如下:
 
   static void ReadRaster()
 
   {
 
   string strFile = @"D:\Data\landsat\etp139r26_5t19900902\p139r26_5t19900902_nn1.tif";
 
   OSGeo.GDAL.Gdal.AllRegister();
 
   OSGeo.GDAL.Dataset ds = OSGeo.GDAL.Gdal.Open(strFile, OSGeo.GDAL.Access.GA_ReadOnly);
 
   int []bandmap = new int [1];
 
   bandmap[0] = 1;
 
   //读取Byte类型
 
   Byte[] data = new Byte[100 * 100];
 
   //构造一个IntPtr,大小为100×100个Byte
 
   IntPtr ptr = Marshal.AllocCoTaskMem(data.Length);
 
   //需要指明读取的数据类型
 
   OSGeo.GDAL.CPLErr err = ds.ReadRaster(3000, 2000, 100, 100, ptr, 100, 100, OSGeo.GDAL.DataType.GDT_Byte, 1, bandmap, 0, 0, 0);
 
   //将读取到的数据拷贝到data中
 
   Marshal.Copy(ptr, data, 0, data.Length);
 
   //将读取的数据输出
 
   for (int i = 0; i < 100; i++ )
 
   {
 
   for (int j = 0; j < 100; j++)
 
   {
 
   Console.WriteLine("{0}", ddata[i*100+j]);
 
   }
 
   }
 
   Console.WriteLine("done\n");
 
   }
 
   从上面的代码中可以看出,使用第六个函数的时候,需要一个IntPtr的类型,使用Marshal类中的AllocCoTaskMem函数来进行分配内存空间(不知道C#中的说法是啥,按照C\C++中应该就是分配空间)。需要注意的是,分配的大小是按照字节(Byte)为单位的。接下来在调用ReadRaster时需要指定数据类型,调用之后,像素值应该都存储在这个IntPtr中了,然后再使用Marshal类中的Copy函数将IntPtr中的数据拷贝到Byte数组data中即可 www.tfjy386.com
 
   通过上面的代码,我们大致知道第六个ReadRaster的大致用法,接下来我们通过这个方法来读取一个复数类型的图像。没有复数类型的图像,可以使用ENVI随便打开一个图像,然后在Transform菜单下有个FFT,将打开的数据进行傅立叶变换,输出的结果就是一个复数图像。这里我将上面使用的Landsat的数据使用FFT转了下。使用下面的代码进行打开。
 
   static void ReadRaster()
 
   {
 
   string strFile = @"D:\Data\landsat\etp139r26_5t19900902\p139r26_5t19900902_nn1_fft.tif";
 
   OSGeo.GDAL.Gdal.AllRegister();
 
   OSGeo.GDAL.Dataset ds = OSGeo.GDAL.Gdal.Open(strFile, OSGeo.GDAL.Access.GA_ReadOnly);
 
   int []bandmap = new int [1];
 
   bandmap[0] = 1;
 
   //读取复数类型,由于一个复数由两个数据组成,所以读取100×100的像元需要2倍普通图像的大小
 
   double[] data = new double[100 * 100 * 2];
 
   //构造一个IntPtr,大小为100×100×2个double,一个double为4个byte,所以下面的长度要乘以8
 
   IntPtr ptr = Marshal.AllocCoTaskMem(data.Length*8);
 
   //需要指明读取的数据类型
 
   OSGeo.GDAL.CPLErr err = ds.ReadRaster(0, 0, 100, 100, ptr, 100, 100, OSGeo.GDAL.DataType.GDT_CFloat64, 1, bandmap, 0, 0, 0);
 
   //将读取到的数据拷贝到data中
 
   Marshal.Copy(ptr, data, 0, data.Length*8);
 
   //将读取的数据输出
 
   int in1 = 0;
 
   for (int i = 0; i < 100; i++ )
 
   {
 
   for (int j = 0; j < 100; j++)
 
   {
 
   Console.WriteLine("({0}*i+{1})", ddata[in1++], ddata[in1++]);
 
   }
 
   }
 
   Console.WriteLine("done\n");
 
   }
 
   在上面的代码中,一个复数由实部和虚部组成,所以一个像素值就对应于普通图像的2个像素值,故读取100×100大小的数据就需要分配普通图像2倍的大小。除此之外与读取普通图像一样,不过在最后获取像素值的时候,复数图像的像素值是顺序存储的,即实部,虚部,实部,虚部...这样的顺序来进行存储。

使用C#版本GDAL读取复数图像的更多相关文章

  1. OpenCV imread读取jpg图像的一个大坑

    长话短说 版本区间[OpenCV3.0.0, OpenCV3.4.1]内的OpenCV,(至少在windows下,使用官方提供的预编译版本),imread读取jpg图片后的像素值,和版本区间[Open ...

  2. GDAL关于读写图像的简明总结

    读写影像可以说是图像处理最基础的一步.关于使用GDAL读写影像,平时也在网上查了很多资料,就想结合自己的使用心得,做做简单的总结. 在这里写一个例子:裁剪lena图像的某部分内容,将其放入到新创建的. ...

  3. GDAL读取的坐标起点在像素左上角还是像素中心?

    目录 1. 问题 2. 结论 3. 例外 1. 问题 笔者在处理地理栅格数据的时候,总是会发生偏差半个像素的问题. 比如说通过ArcMap打开一张.tif,查看其地理信息:同时用记事本打开.tfw,比 ...

  4. GDAL读取Shp问题解决:Unable to open EPSG support file gcs.csv

    在GIS软件的开发中,经常用到开源库GDAL读取Shp数据,当shp数据中包含投影信息时,可能会遇到“Unable to open EPSG support file gcs.csv”错误提示,该错误 ...

  5. ArcGIS二次开发之读取遥感图像像素值的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 首先是读取遥感图像的R.G.B波段数据的做法.读取R.G.B波段数据的像素值主要通过IRaster接口的Read方法在 ...

  6. VTK读取序列化图像

    vtk获取内存中图像数据 原文链接:http://blog.csdn.net/zmy3376365/article/details/7717721 内存中有段图片数据  ,使用VTK来读入,然后就可以 ...

  7. Halcon一日一练:读取文件目录图像的三种方法

    第一种方法: 读了一个单一图像: read_image(Image,'fabrik') 这种方式可以快速的读取软件自身携带的库图像文件,系统设定了库图像映像文件的快速读取方式,我们也可以通过绝对地址的 ...

  8. 从二进制数据流中构造GDAL可以读取的图像数据

    在很多时候,我们的图像数据往往都不是文件方式存储在磁盘上,而是可能从网络或者数据库中获取的是二进制的图像数据流.最简单的方式和最容易想到的方式就是将这个文件流保存到磁盘上形成一个文件,然后再使用GDA ...

  9. 从二进制数据流中构造GDAL可以读取的图像数据(C#)

    在上一篇博客中,讲了一下使用GDAL从文件流中构造一个GDAL可以识别的数据来进行处理.原以为这个接口在C#中没有,仔细看了下GDAL库中源码,发现C#版本也有类似的函数,下面是GDAL库中的一个C# ...

随机推荐

  1. OpenGl学习总结

    http://wenku.baidu.com/view/5305fe4f866fb84ae45c8dcd.html

  2. Bellman_ford最短路

    #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> ...

  3. 动态规划初级练习(二):BadNeighbors

    Problem Statement      The old song declares "Go ahead and hate your neighbor", and the re ...

  4. Windows 10 代理上网用户的正确使用姿势

      1.找不到IE,如何使用IE来配置局域网代理 打开Edge浏览器,点击选项,找到“使用Internet Explorer打开” 接下来可以使用熟练的姿势设置IE局域网代理上网了 2.Windows ...

  5. cppunit学习笔记

    下载cppunit 链接:http://www.cnblogs.com/duxiuxing/p/4303809.html cppunit官方文档浅析 链接:http://www.cnblogs.com ...

  6. 《Linear Algebra and Its Applications》-chaper2-矩阵的逆

    矩阵的逆: 逆矩阵的定义: 类比于我们在研究实数的时候回去讨论一个数的倒数,对应的,在矩阵运算中,当AB = I的时候,A,B互称为逆矩阵,这里的I类似实数中的1,表示单位矩阵,即对角线是1其余位置是 ...

  7. libvirt 基于C API基本使用案例

    玩开源分享,需要有干到底的精神,今晚随便逛逛技术论坛突发有感;Ruiy不足之处,需跟进了; 最近变的较懒了,干活有点没劲,也不怪干来干去收获不大,缺少鼓励! 现在玩的技术大多是上不了台面了,想过没,你 ...

  8. 基于Struts2 的日志管理系统的Java实现

    1.首先,项目的架构如下:          2.com.sxl.dba 中:OracleConnector.java package com.sxl.dba; import java.sql.*; ...

  9. Facade外观模式 笔记

    Facede模式: 把内部系统复杂隐藏,提供一个方便统一的接口. 微波炉在界面简单操作下就可以烹饪出美味佳肴, 微波炉内部运作原理,各个组件互相交互运作,使用者并不需要关心.  而且关心的话可能没有多 ...

  10. VSS Get Latest Version 没有提示recursive的对话框解决

    今天按照VSS使用时,当“Get Latest version”时,不小心勾选了 “Only show this dialog when the Shift key is down”,因此当我再“Ge ...