利用C#版本的GDAL中的ReadRaster函数读取单波段复数图像

来源:互联网 发布:手机查询淘宝信誉级别 编辑:程序博客网 时间:2024/04/29 23:00

        近期组里在做一个项目,需要读取单波段的复数影像,开发平台为C#想利用C#版本的GDAL来读取影像,但是在使用过程中遇到了困难,因为在C#版本中的GDAL读取影像的函数ReadRaster针对每一种数据类型有一个重载函数,对于普通的数据类型可以不用指定数据类型直接进行读取即可。但是对于复数类型就有点复杂了。下面就针对GDAL如何来读取复数数据来进行一个简单的说明。

        我们知道,在使用GDAL读取数据的时候使用的是ReadRaster这个函数,这个函数重载了6个,函数声明分别如下,以Band的ReadRaster为例,Dataset类中的ReadRaster与之类似。

 public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, byte[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace);        public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, double[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace);        public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, float[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace);        public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, int[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace);        public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, short[] buffer, int buf_xSize, int buf_ySize, int pixelSpace, int lineSpace);        public CPLErr ReadRaster(int xOff, int yOff, int xSize, int ySize, IntPtr buffer, int buf_xSize, int buf_ySize, DataType buf_type, int pixelSpace, int lineSpace);

        前五个函数的声明基本上完全一致,除了第五个参数,分别是Byte[],Int16[],Int32[],Single[],Double[]。分别对应的是将图像中的像素值使用8U,16U\16S,32U\32S,32F和64F。如果图像数据是普通的数据(这里指的是除复数图像之外),那么这五个函数完全可以满足所有的需求。但是如果图像是复数图像(复数图像就是图像的像素值是由复数组成的,比如通过傅立叶变换后的图像),这时,上面的五个函数就有点爱莫能助了,就需要上面的第六个函数来出场救急了。

        接下来我们通过这个方法来读取一个复数类型的图像。没有复数类型的图像,可以使用ENVI随便打开一个图像,然后在Transform菜单下有个FFT,将打开的数据进行傅立叶变换,输出的结果就是一个复数图像。使用下面的代码进行打开。

            int Width = 0;            int Height = 0;            int Bands = 0;            Gdal.AllRegister();            Dataset srcDS = Gdal.Open(textBox1.Text, Access.GA_ReadOnly);            if (srcDS == null)            {                MessageBox.Show("图像打开失败!");                return;            }            Width = srcDS.RasterXSize;            Height = srcDS.RasterYSize;            Bands = srcDS.RasterCount;            Band realBand = srcDS.GetRasterBand(1);            int datatype = (int)realBand.DataType;            float[] real = new float[2 * Width];            unsafe            {                fixed (float* preal = real)                {                    IntPtr ptrData = new IntPtr(preal);                    realBand.ReadRaster(0, 0, Width, 1, ptrData, Width, 1, realBand.DataType, 0, 0);                }            }

         使用第六个函数时需要一个IntPtr的类型,这里在unsafe环境下利用fixed定义一个real类型对应的float * 变量preal,并且把real赋值给preal,然后再定义一个 IntPtr类型的变量,利用其构造函数

public static explicit operator IntPtr(void* value);

创建一个变量ptrData,然后利用ReadRaster函数进行读取,这样读取的值会自动赋给real。因为是复数类型,一个复数由实部和虚部组成,所以一个像素值就对应于普通图像的2个像素值,故读取Width大小的数据就需要分配普通图像2倍的大小。如此便完成了利用C#版本的GDAL读取一个单波段的复数影像

0 0
原创粉丝点击