예제 #1
0
        public void WriterRasterResult(string nFileName, ResultInfo resultInfo)
        {
            try
            {
                _fileName   = nFileName;
                _resultInfo = resultInfo;

                OSGeo.GDAL.Gdal.AllRegister();
                OSGeo.GDAL.Driver nDriver = OSGeo.GDAL.Gdal.GetDriverByName("GTiff");

                double[] inGeo    = _resultInfo.InGeo;
                string[] strs     = new string[] { "INTERLEAVE = PIXEL" };
                string   prjWGS84 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"912\"]],AUTHORITY[\"EPSG\",\"4326\"]]";

                _dataSet = nDriver.Create(_fileName,
                                          _resultInfo.Width,
                                          _resultInfo.Height,
                                          1,
                                          OSGeo.GDAL.DataType.GDT_Byte,
                                          strs);

                _pixels1 = new double[_resultInfo.Width * _resultInfo.Height];


                _dataSet.SetGeoTransform(inGeo);
                _dataSet.SetProjection(prjWGS84);
                _dataSet.Dispose();
            }
            catch (System.Exception err)
            {
                throw new Exception("数据写入失败。" + err.Message);
            }
        }
예제 #2
0
        /// <summary>
        /// 数据保存
        /// </summary>
        public void Save()
        {
            try
            {
                OSGeo.GDAL.Gdal.AllRegister();
                _dataSet = OSGeo.GDAL.Gdal.Open(_fileName, OSGeo.GDAL.Access.GA_Update);

                _band1 = _dataSet.GetRasterBand(1);
                CPLErr err1 = _band1.WriteRaster(0,
                                                 0,
                                                 _resultInfo.Width,
                                                 _resultInfo.Height,
                                                 _pixels1,
                                                 _resultInfo.Width,
                                                 _resultInfo.Height,
                                                 0,
                                                 0);

                _dataSet.Dispose();
                _band1.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception("数据写入失败。" + ex.Message);
            }
        }
예제 #3
0
        public void Save(int xoff, int yoff, int buf_xsize, int buf_ysize, double[] buffer)
        {
            try
            {
                OSGeo.GDAL.Gdal.AllRegister();
                _dataSet = OSGeo.GDAL.Gdal.Open(_fileName, OSGeo.GDAL.Access.GA_Update);

                _band1 = _dataSet.GetRasterBand(1);
                CPLErr err1 = _band1.WriteRaster(xoff,
                                                 yoff,
                                                 _resultInfo.Width,
                                                 buf_ysize,
                                                 buffer,
                                                 buf_xsize,
                                                 buf_ysize,
                                                 0,
                                                 0);

                _dataSet.Dispose();
                _band1.Dispose();
            }
            catch (Exception ex)
            {
                throw new Exception("数据写入失败。" + ex.Message);
            }
        }
예제 #4
0
        public new TerrainTile GetTerrainTile(double latitude, double longitude, double samplesPerDegree)
        {
            //Get Empty Terrain Tile
            TerrainTile tt = base.GetTerrainTile(latitude, longitude, samplesPerDegree);
            //Populate target .bil file with data from DataSet
            string cachefile = tt.TerrainTileFilePath;

            //work out lines and pixels to extract from VRT
            int startpixel = (int)Math.Floor((tt.West - m_transform[0]) / m_transform[1]);
            int endpixel   = (int)Math.Ceiling((tt.East - m_transform[0]) / m_transform[1]);
            int startline  = (int)Math.Floor((tt.North - m_transform[3]) / m_transform[5]);
            int endline    = (int)Math.Ceiling((tt.South - m_transform[3]) / m_transform[5]);


            int xsize = endpixel - startpixel;
            int ysize = endline - startline;

            //Allow partial raster access for beyond edge cases
            int realstartpixel = Math.Max(0, startpixel);
            int realstartline  = Math.Max(0, startline);
            int realendpixel   = Math.Min(m_pixels, endpixel);
            int realendline    = Math.Min(m_lines, endline);

            //Scale target window in case of partial access
            int realxsize = realendpixel - realstartpixel;
            int realysize = realendline - realstartline;

            //Scale buffer window
            int bufxsize = (int)Math.Round(256.0 * (double)realxsize / (double)xsize);
            int bufysize = (int)Math.Round(256.0 * (double)realysize / (double)ysize);
            int xoff     = (int)Math.Round(256.0 * (double)(realstartpixel - startpixel) / (double)xsize);
            int yoff     = (int)Math.Round(256.0 * (double)(realstartline - startline) / (double)ysize);
            int totalbuf = bufxsize * bufysize;

            //use pixel space and line space instead of separate buffers
            Int16[] dembuffer = new Int16[totalbuf];


            //extract data from vrt
            try
            {
                m_dataset.GetRasterBand(1).ReadRaster(realstartpixel, realstartline, realxsize, realysize, dembuffer, bufxsize, bufysize, 0, 0);
            }
            catch
            {
                Console.WriteLine("Raster Could not be accessed");
            }

            //write out cache file
            Driver memdriver = Gdal.GetDriverByName("ENVI");

            string[] options = new string[0];
            //TODO: Add compression

            OSGeo.GDAL.Dataset tile_ds = memdriver.Create(cachefile, 256, 256, 1, (DataType)OSGeo.GDAL.GdalConst.GDT_Int16, options);
            tile_ds.GetRasterBand(1).WriteRaster(xoff, yoff, bufxsize, bufysize, dembuffer, bufxsize, bufysize, 0, 0);
            tile_ds.Dispose();

            return(tt);
        }
예제 #5
0
        /// <summary>
        /// 切分图像||
        /// 解决图像过大导致的计算缓慢||
        /// 输入图像路径,输出分幅路径||
        /// 重叠区根据图像分辨率确定,约为实地100~200米
        /// </summary>
        /// <param name="inPaht"></param>
        /// <returns></returns>
        public static List <string> getSubImg(string inPaht)
        {
            //注册插件
            OSGeo.GDAL.Gdal.AllRegister();
            OSGeo.GDAL.Driver gdalDriver = OSGeo.GDAL.Gdal.GetDriverByName("HFA");
            //读进数据
            OSGeo.GDAL.Dataset inDS = OSGeo.GDAL.Gdal.Open(inPaht, OSGeo.GDAL.Access.GA_ReadOnly);

            //根据栅格分辨率确定重叠区大小
            double[] dsTraansform = new double[6];
            inDS.GetGeoTransform(dsTraansform);
            if (dsTraansform[1] < 0.16)
            {
                xBuf = 1000; yBuf = 1000;
            }                            //1000*0.1=>100M
            if (dsTraansform[1] < 0.3)
            {
                xBuf = 500; yBuf = 500;
            }                          //500*0.25=>125M
            else if (dsTraansform[1] < 0.6)
            {
                xBuf = 300; yBuf = 300;
            }                          //300*0.5=>150M
            else if (dsTraansform[1] < 1.1)
            {
                xBuf = 200; yBuf = 150;
            }                          //150*1=>200M
            else if (dsTraansform[1] < 2.1)
            {
                xBuf = 100; yBuf = 100;
            }                          //100*2=>200M
            else
            {
                xBuf = 50; yBuf = 50;
            }                        //50*5=>250M


            //获取数据XY相元数量
            int oriXcount = inDS.RasterXSize;
            int oriYcount = inDS.RasterYSize;

            //用来返回的文件路径列表
            List <string> imgFilePaths = new List <string>();

            if (oriXcount > userSetX || oriYcount > userSetY)
            {
                //确定文件行列数
                int u, v;
                u = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriXcount) / userSetX)); //行文件数
                v = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriYcount) / userSetY)); //列文件数

                //循环列
                for (int i = 0; i < v; i++)
                {
                    //循环行
                    for (int j = 0; j < u; j++)
                    {
                        ////////////  定义起点  /////////////
                        int offX = j * userSetX;
                        int offY = i * userSetY;

                        //////////////定义边缘栅格大小/////////////////
                        int thinkJ    = userSetX * (j + 1) + xBuf;
                        int thinkI    = userSetY * (i + 1) + yBuf;
                        int subXcount = oriXcount - thinkJ > 0 ? userSetX + xBuf : oriXcount - userSetX * j;
                        int subYcount = oriYcount - thinkI > 0 ? userSetY + yBuf : oriYcount - userSetY * i;

                        ////////////  把原栅格读进内存,内容为oriValue /////////////
                        OSGeo.GDAL.Band oriBand  = inDS.GetRasterBand(1);
                        double[]        oriValue = new double[subXcount * subYcount];

                        oriBand.ReadRaster
                        (
                            offX,      //起点X索引
                            offY,      //起点Y索引
                            subXcount, //X方向相元数量
                            subYcount, //Y方向相元数量
                            oriValue,  //各相元值
                            subXcount, //执行读入的X方向数量
                            subYcount, //执行读入的Y方向数量
                            0,         //执行读入的起点X索引
                            0          //执行读入的起点Y索引
                        );

                        ////////////  创建子栅格 /////////////
                        string             imgFilePath = StaticTools.tempFilePath("img", i.ToString() + "_" + j.ToString());
                        OSGeo.GDAL.Dataset subDs       = gdalDriver.Create
                                                         (
                            imgFilePath,
                            subXcount,
                            subYcount,
                            1,
                            OSGeo.GDAL.DataType.GDT_Float32,
                            null
                                                         );
                        subDs.SetProjection(inDS.GetProjectionRef());

                        //获取数据Transfrom
                        double[] oriTransFrom = new double[6];
                        inDS.GetGeoTransform(oriTransFrom);
                        oriTransFrom[0] = oriTransFrom[0] + offX * oriTransFrom[1] + offY * oriTransFrom[2];
                        oriTransFrom[3] = oriTransFrom[3] + offX * oriTransFrom[4] + offY * oriTransFrom[5];
                        subDs.SetGeoTransform(oriTransFrom);
                        ////////////  把值写入子栅格 /////////////
                        subDs.GetRasterBand(1).WriteRaster
                        (
                            0,
                            0,
                            subXcount,
                            subYcount,
                            oriValue,
                            subXcount,
                            subYcount,
                            0,
                            0
                        );

                        ///////////////// 返回子栅格路径 ////////////////////
                        imgFilePaths.Add(imgFilePath);
                        subDs.Dispose();
                    }
                }
            }
            else
            {
                imgFilePaths.Add(inPaht);
            }
            inDS.Dispose();
            return(imgFilePaths);
        }
예제 #6
0
        /// <summary>
        /// Brovey变换融合。融合前会将多光谱数据集的每一波段与全色数据集做直方图匹配。
        /// </summary>
        /// <param name="PanDS">全色数据集。</param>
        /// <param name="MSDS">多光谱数据集</param>
        /// <param name="PanCumu">全色数据集的累积概率表。</param>
        /// <param name="MSCumu">多光谱数据集的累积概率表。</param>
        /// <param name="MSBandList">多光谱数据集的波段组合。</param>
        /// <param name="OutDataType">输出数据类型。</param>
        /// <param name="OutPath">输出路径。</param>
        /// <returns>返回操作成功或失败。</returns>
        public static bool Brovey(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath)
        {
            try
            {
                if (PanDS == null)
                {
                    throw new ArgumentNullException("输入的全色数据集为空。");
                }
                if (PanDS.RasterCount > 1)
                {
                    throw new RankException("全色数据集波段大于1。");
                }
                if (MSDS == null)
                {
                    throw new ArgumentNullException("输入的多光谱数据集为空。");
                }
                if (String.IsNullOrWhiteSpace(OutPath.Trim()))
                {
                    throw new ArgumentNullException("输出路径为空或非法。");
                }
                OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff");
                if (Dri == null)
                {
                    throw new Exception("无法获取GDAL Driver。");
                }

                int panWidth  = PanDS.RasterXSize;
                int panHeight = PanDS.RasterYSize;
                int msWidth   = MSDS.RasterXSize;
                int msHeight  = MSDS.RasterYSize;
                //int rat = (int)Math.Ceiling((double)panHeight / msHeight);

                if (panWidth < msWidth)
                {
                    throw new RankException("全色数据集宽度小于多光谱数据集宽度。");
                }
                if (panHeight < msHeight)
                {
                    throw new RankException("全色数据集高度小于多光谱数据集高度。");
                }
                //if (rat <= 0)
                //    throw new ArgumentOutOfRangeException("全色高度:多光谱高度小于1。");

                FrmProgress FP = new FrmProgress()
                {
                    Text = "正在进行Brovey融合...",
                };

                Thread t = new Thread(() =>
                {
                    FP.ShowDialog();
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();

                #region 预处理
                //创建临时文件,进行直方图匹配。
                string             HisMatFileName = Tools.Common.GetTempFileName();
                OSGeo.GDAL.Dataset MatchingDS     = Dri.CreateCopy(HisMatFileName, MSDS, 0, null, null, null);
                FP.Output("已创建直方图匹配临时文件\"" + HisMatFileName + "\"");
                for (int band = 1; band <= MSDS.RasterCount; band++)
                {
                    FP.Output("正在进行直方图匹配(" + band.ToString() + "/" + MSDS.RasterCount.ToString() + ")...");
                    Band b = Tools.BaseProcess.HistogramMatching(MSDS.GetRasterBand(band), PanDS.GetRasterBand(1), MSCumu[band - 1], PanCumu[0], OutDataType);
                    if (b == null)
                    {
                        throw new ArgumentNullException("直方图匹配返回波段为空。");
                    }
                    for (int row = 0; row < b.YSize; row++)
                    {
                        double[] tmp = new double[b.XSize];
                        b.ReadRaster(0, row, b.XSize, 1, tmp, b.XSize, 1, 0, 0);
                        MatchingDS.GetRasterBand(band).WriteRaster(0, row, MatchingDS.GetRasterBand(band).XSize, 1, tmp, MatchingDS.GetRasterBand(band).XSize, 1, 0, 0);
                        MatchingDS.FlushCache();
                        Thread.Sleep(1);
                    }
                }

                //创建临时文件,进行重采样。
                double[]           resamptmp;
                string             ResampFileName = Tools.Common.GetTempFileName();
                OSGeo.GDAL.Dataset ResampDS       = Dri.Create(ResampFileName, panWidth, panHeight, 3, MSDS.GetRasterBand(1).DataType, null);
                FP.Output("已创建重采样临时文件\"" + ResampFileName + "\"");
                //Tools.Common.CopyMetadata(PanDS, tmpDS);
                //Gdal.ReprojectImage(MSDS, tmpDS, null, null, 0, 0, 0, null, null);

                //将直方图匹配后的图像重采样。
                for (int i = 0; i < 3; i++)
                {
                    FP.Output("正在对直方图匹配后影像进行重采样(" + (i + 1).ToString() + "/" + "3)...");
                    resamptmp = new double[panWidth * panHeight];
                    MatchingDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0);
                    ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0);
                    ResampDS.FlushCache();
                    Thread.Sleep(1);
                    if (FP.Canceled)
                    {
                        Thread.Sleep(500);

                        FP.Finish();
                        throw new OperationCanceledException("操作被用户取消。");
                    }
                }
                //释放直方图匹配图像资源。
                MatchingDS.Dispose();
                if (File.Exists(HisMatFileName))
                {
                    File.Delete(HisMatFileName);
                }
                FP.Output("已删除直方图匹配临时文件");
                #endregion

                //创建输出数据集。
                OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null);
                FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。");
                Tools.Common.CopyMetadata(PanDS, DS);

                double[]   p;
                double[][] ms;
                double[]   ds;

                for (int row = 0; row < panHeight; row++)
                {
                    FP.SetProgress2("正在处理", row + 1, panHeight, "行");
                    //将全色波段行读取进数组。
                    p = new double[panWidth];
                    PanDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, p, panWidth, 1, 0, 0);

                    //将重采样后的多光谱行读取进数组。
                    ms    = new double[3][];
                    ms[0] = new double[panWidth];
                    ms[1] = new double[panWidth];
                    ms[2] = new double[panWidth];
                    ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, ms[0], panWidth, 1, 0, 0);
                    ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, ms[1], panWidth, 1, 0, 0);
                    ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, ms[2], panWidth, 1, 0, 0);

                    //遍历三波段
                    for (int bandcount = 0; bandcount < 3; bandcount++)
                    {
                        FP.SetProgress1("正在处理", bandcount + 1, 3, "波段");
                        ds = new double[panWidth];  //临时数组
                        for (long i = 0; i < panWidth; i++)
                        {
                            ds[i] = p[i] * ms[bandcount][i] / (ms[0][i] + ms[1][i] + ms[2][i]);                  //Brovey公式
                        }
                        DS.GetRasterBand(bandcount + 1).WriteRaster(0, row, panWidth, 1, ds, panWidth, 1, 0, 0); //计算完后的数据写入
                        DS.FlushCache();
                    }
                    Thread.Sleep(1);
                    if (FP.Canceled)
                    {
                        Thread.Sleep(500);

                        FP.Finish();
                        throw new OperationCanceledException("操作被用户取消。");
                    }
                }
                //释放重采样图像资源。
                ResampDS.Dispose();
                if (File.Exists(ResampFileName))
                {
                    File.Delete(ResampFileName);
                }
                FP.Output("已删除重采样临时文件");

                /*一次性读取一时爽,遇到大文件爆内存。
                *  一次性读取一时爽,遇到大文件爆内存。
                *  一次性读取一时爽,遇到大文件爆内存。*/
                //p = new double[panWidth * panHeight];
                //ms = new double[3][];
                //ms[0] = new double[panWidth * panHeight];
                //ms[1] = new double[panWidth * panHeight];
                //ms[2] = new double[panWidth * panHeight];

                //PanDS.GetRasterBand(1).ReadRaster(0, 0, panWidth, panHeight, p, panWidth, panHeight, 0, 0);
                //MSDS.GetRasterBand(MSBandList[0]).ReadRaster(0, 0, msWidth, msHeight, ms[0], panWidth, panHeight, 0, 0);
                //MSDS.GetRasterBand(MSBandList[1]).ReadRaster(0, 0, msWidth, msHeight, ms[1], panWidth, panHeight, 0, 0);
                //MSDS.GetRasterBand(MSBandList[2]).ReadRaster(0, 0, msWidth, msHeight, ms[2], panWidth, panHeight, 0, 0);

                //for (int bandcount = 0; bandcount < 3; bandcount++)
                //{
                //    ds = new double[panWidth * panHeight];
                //    for (int row = 0; row < panHeight; row++)
                //    {
                //        for (int col = 0; col < panWidth; col++)
                //        {
                //            ds[row * panWidth + col] = p[row * panWidth + col] * ms[bandcount][row * panWidth + col] / (ms[0][row * panWidth + col] + ms[1][row * panWidth + col] + ms[2][row * panWidth + col]);
                //        }
                //    }
                //    DS.GetRasterBand(bandcount + 1).WriteRaster(0, 0, panWidth, panHeight, ds, panWidth, panHeight, 0, 0);
                //    DS.FlushCache();
                //}

                FP.Finish();
                Dri.Dispose();
                DS.Dispose();
                return(true);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.ToString());
                return(false);
            }
        }
예제 #7
0
        /// <summary>
        /// IHS融合。融合前会将全色数据集与多光谱数据集转换到IHS空间下的I波段做直方图匹配。
        /// </summary>
        /// <param name="PanDS">全色数据集。</param>
        /// <param name="MSDS">多光谱数据集</param>
        /// <param name="PanCumu">全色数据集的累积概率表。</param>
        /// <param name="MSCumu">多光谱数据集的累积概率表。</param>
        /// <param name="MSBandList">多光谱数据集的波段组合。</param>
        /// <param name="OutDataType">输出数据类型。</param>
        /// <param name="OutPath">输出路径。</param>
        /// <returns>返回操作成功或失败。</returns>
        public static bool IHSFusion(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath)
        {
            try
            {
                if (PanDS == null)
                {
                    throw new ArgumentNullException("输入的全色数据集为空。");
                }
                if (PanDS.RasterCount > 1)
                {
                    throw new RankException("全色数据集波段大于1。");
                }
                if (MSDS == null)
                {
                    throw new ArgumentNullException("输入的多光谱数据集为空。");
                }
                if (String.IsNullOrWhiteSpace(OutPath.Trim()))
                {
                    throw new ArgumentNullException("输出路径为空或非法。");
                }
                OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff");
                if (Dri == null)
                {
                    throw new Exception("无法获取GDAL Driver。");
                }

                int panWidth  = PanDS.RasterXSize;
                int panHeight = PanDS.RasterYSize;
                int msWidth   = MSDS.RasterXSize;
                int msHeight  = MSDS.RasterYSize;

                if (panWidth < msWidth)
                {
                    throw new RankException("全色数据集宽度小于多光谱数据集宽度。");
                }
                if (panHeight < msHeight)
                {
                    throw new RankException("全色数据集高度小于多光谱数据集高度。");
                }

                FrmProgress FP = new FrmProgress()
                {
                    Text = "正在进行IHS融合...",
                };

                Thread t = new Thread(() =>
                {
                    FP.ShowDialog();
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();

                #region 预处理
                //创建临时文件,进行重采样。
                double[]           resamptmp;
                string             ResampFileName = Tools.Common.GetTempFileName();
                OSGeo.GDAL.Dataset ResampDS       = Dri.Create(ResampFileName, panWidth, panHeight, MSDS.RasterCount, MSDS.GetRasterBand(1).DataType, null);
                FP.Output("已创建重采样临时文件\"" + ResampFileName + "\"");

                //将多光谱影像重采样。
                for (int i = 0; i < 3; i++)
                {
                    FP.Output("正在进行重采样(" + (i + 1).ToString() + "/" + "3)...");
                    resamptmp = new double[panWidth * panHeight];
                    MSDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0);
                    ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0);
                    ResampDS.FlushCache();
                    Thread.Sleep(1);
                    if (FP.Canceled)
                    {
                        Thread.Sleep(500);

                        FP.Finish();
                        throw new OperationCanceledException("操作被用户取消。");
                    }
                }

                double[] BandMax = new double[3];
                double[] BandMin = new double[3];
                for (int i = 0; i < 3; i++)
                {
                    FP.Output("正在计算重采样影像统计数据(" + (i + 1).ToString() + "/" + "3)...");
                    Common.ComputeRasterMinMax(ResampDS.GetRasterBand(i + 1), out BandMin[i], out BandMax[i]);
                }
                #endregion

                //多光谱RGB转IHS。
                string             MSIHSFileName = Tools.Common.GetTempFileName();
                OSGeo.GDAL.Dataset MSIHSDS       = Dri.Create(MSIHSFileName, panWidth, panHeight, 3, OSGeo.GDAL.DataType.GDT_Float32, null);
                FP.Output("已创建IHS临时文件\"" + MSIHSFileName + "\"");

                //按行读入,进行拉伸后再IHS转换,写入。
                for (int row = 0; row < panHeight; row++)
                {
                    FP.SetProgress1("正在处理IHS临时文件(", row + 1, panHeight, ")");
                    double[]   iArr     = new double[panWidth];
                    double[]   hArr     = new double[panWidth];
                    double[]   sArr     = new double[panWidth];
                    double[][] MSRGBArr = new double[3][];
                    MSRGBArr[0] = new double[panWidth];
                    MSRGBArr[1] = new double[panWidth];
                    MSRGBArr[2] = new double[panWidth];
                    //读。
                    ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, MSRGBArr[0], panWidth, 1, 0, 0);
                    ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, MSRGBArr[1], panWidth, 1, 0, 0);
                    ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, MSRGBArr[2], panWidth, 1, 0, 0);
                    //按行逐像元转IHS。
                    for (long i = 0; i < panWidth; i++)
                    {
                        double[] tmp = Common.RGB2IHS(
                            new double[3] {
                            Common.LinearStretchDouble(MSRGBArr[0][i], BandMin[0], BandMax[0]),
                            Common.LinearStretchDouble(MSRGBArr[1][i], BandMin[1], BandMax[1]),
                            Common.LinearStretchDouble(MSRGBArr[2][i], BandMin[2], BandMax[2])
                        });
                        iArr[i] = tmp[0]; hArr[i] = tmp[1]; sArr[i] = tmp[2];
                    }
                    //写。
                    MSIHSDS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, iArr, panWidth, 1, 0, 0);
                    MSIHSDS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, hArr, panWidth, 1, 0, 0);
                    MSIHSDS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, sArr, panWidth, 1, 0, 0);
                    MSIHSDS.FlushCache();
                    Thread.Sleep(1);
                    if (FP.Canceled)
                    {
                        Thread.Sleep(500);

                        FP.Finish();
                        throw new OperationCanceledException("操作被用户取消。");
                    }
                }
                //释放重采样数据集资源。
                ResampDS.Dispose();
                if (File.Exists(ResampFileName))
                {
                    File.Delete(ResampFileName);
                }
                FP.Output("已删除重采样临时文件");

                //全色匹配多光谱I
                FP.Output("正在计算IHS统计数据...");
                Common.GetStatistics(MSIHSDS.GetRasterBand(1), out double Imin, out double Imax, out double Imean, out double Istddev);   //多光谱统计信息。
                int[] IHis = new int[(int)(Imax - Imin) + 1];
                MSIHSDS.GetRasterBand(1).GetHistogram(Imin, Imax, (int)(Imax - Imin) + 1, IHis, 1, 0, null, null);
                double[] ICumu = new double[IHis.Length];
                for (int i = 0; i < IHis.Length; i++)
                {
                    ICumu[i] = (double)IHis[i] / (MSIHSDS.RasterXSize * MSIHSDS.RasterYSize);
                    if (i > 0)
                    {
                        ICumu[i] += ICumu[i - 1];   //累积概率
                    }
                }
                FP.Output("正在进行I波段直方图匹配...");
                Band PanMatIBand = Tools.BaseProcess.HistogramMatching(PanDS.GetRasterBand(1), MSIHSDS.GetRasterBand(1), PanCumu[0], ICumu, OSGeo.GDAL.DataType.GDT_Float32);
                if (PanMatIBand == null)
                {
                    throw new ArgumentNullException("直方图匹配返回波段为空。");
                }
                //全色融合。
                //创建输出数据集。
                OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null);
                FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。");
                Tools.Common.CopyMetadata(PanDS, DS);
                for (int row = 0; row < panHeight; row++)
                {
                    FP.SetProgress1("正在融合(", row + 1, panHeight, ")");
                    //读取匹配多光谱I后的全色波段。
                    double[] Itmp = new double[panWidth];
                    PanMatIBand.ReadRaster(0, row, panWidth, 1, Itmp, panWidth, 1, 0, 0);

                    //读入IHS变换后的多光谱影像的H、S波段。
                    double[] Htmp = new double[panWidth];
                    double[] Stmp = new double[panWidth];
                    MSIHSDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, Htmp, panWidth, 1, 0, 0);
                    MSIHSDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, Stmp, panWidth, 1, 0, 0);

                    double[] Rtmp = new double[panWidth];
                    double[] Gtmp = new double[panWidth];
                    double[] Btmp = new double[panWidth];
                    for (long i = 0; i < panWidth; i++)
                    {
                        double[] tmp = Common.IHS2RGB(new double[3] {
                            Itmp[i], Htmp[i], Stmp[i]
                        });
                        Rtmp[i] = tmp[0]; Gtmp[i] = tmp[1]; Btmp[i] = tmp[2];
                    }
                    DS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, Rtmp, panWidth, 1, 0, 0);
                    DS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, Gtmp, panWidth, 1, 0, 0);
                    DS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, Btmp, panWidth, 1, 0, 0);
                    DS.FlushCache();
                    Thread.Sleep(1);
                    if (FP.Canceled)
                    {
                        Thread.Sleep(500);

                        FP.Finish();
                        throw new OperationCanceledException("操作被用户取消。");
                    }
                }
                //释放IHS图像资源。
                MSIHSDS.Dispose();
                PanMatIBand.Dispose();
                if (File.Exists(MSIHSFileName))
                {
                    File.Delete(MSIHSFileName);
                }
                FP.Output("已删除IHS临时文件");

                FP.Finish();
                Dri.Dispose();
                DS.Dispose();
                return(true);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.ToString());
                return(false);
            }
        }
예제 #8
0
        private static IRaster WrapDataSetInRaster(string name, Type dataType, Dataset dataset)
        {
            // todo: what about UInt32?
            if (dataType == typeof(int) || dataType == typeof(UInt16))
            {
                return new GdalRaster<int>(name, dataset);
            }
            else if (dataType == typeof(short))
            {
                return new GdalRaster<short>(name, dataset);
            }
            else if (dataType == typeof(float))
            {
                return new GdalRaster<float>(name, dataset);
            }
            else if (dataType == typeof(double))
            {
                return new GdalRaster<double>(name, dataset);
            }
            else if (dataType == typeof(byte))
            {
                return new GdalRaster<byte>(name, dataset);
            }

            // It was an unsupported type.
            if (dataset != null)
            {
                dataset.Dispose();
                if (File.Exists(name)) File.Delete(name);
            }
            return null;
        }
예제 #9
0
        /// <summary>
        /// RGB转灰度显示。
        /// </summary>
        /// <param name="InputImg">影像对象。</param>
        /// <param name="RGBWeight">RGB权重数组,长度为3。</param>
        /// <param name="OutDataType">输出数据类型。</param>
        /// <param name="OutPath">输出路径。</param>
        /// <returns>返回操作成功或失败。</returns>
        public static bool RGB2GrayScale(Img InputImg, double[] RGBWeight, OSGeo.GDAL.DataType OutDataType, string OutPath)
        {
            try
            {
                if (OutPath == InputImg.Path)
                {
                    throw new Exception("输出路径与源文件相同。");
                }
                if (InputImg.GDALDataset == null)
                {
                    throw new ArgumentNullException("输入数据集为空。");
                }
                if (String.IsNullOrWhiteSpace(OutPath.Trim()))
                {
                    throw new ArgumentNullException("输出路径为空或非法。");
                }
                if (RGBWeight.Length != 3)
                {
                    throw new ArgumentException("权重数组长度无效,应为3。");
                }
                if (Math.Abs(RGBWeight[0] + RGBWeight[1] + RGBWeight[2] - 1) > 1E-7)
                {
                    throw new ArgumentOutOfRangeException("RGB分量权重设置错误。总和应为1。");
                }
                OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff");
                if (Dri == null)
                {
                    throw new Exception("无法获取GDAL Driver。");
                }

                int xSize = InputImg.Width;
                int ySize = InputImg.Height;

                FrmProgress FP = new FrmProgress()
                {
                    Text = "正在导出灰度影像...",
                };

                Thread t = new Thread(() =>
                {
                    FP.ShowDialog();
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();

                OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null);
                FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。");
                Tools.Common.CopyMetadata(InputImg.GDALDataset, DS);

                for (int Row = 0; Row < ySize; Row++)
                {
                    FP.SetProgress1("正在处理", Row + 1, ySize, "行");
                    double[] RValues    = new double[xSize];
                    double[] GValues    = new double[xSize];
                    double[] BValues    = new double[xSize];
                    double[] GrayValues = new double[xSize];

                    InputImg.GDALDataset.GetRasterBand(InputImg.BandList[0]).ReadRaster(0, Row, xSize, 1, RValues, xSize, 1, 0, 0);
                    InputImg.GDALDataset.GetRasterBand(InputImg.BandList[1]).ReadRaster(0, Row, xSize, 1, GValues, xSize, 1, 0, 0);
                    InputImg.GDALDataset.GetRasterBand(InputImg.BandList[2]).ReadRaster(0, Row, xSize, 1, BValues, xSize, 1, 0, 0);
                    for (int Col = 0; Col < xSize; Col++)
                    {
                        //拉伸到0~255后再加权计算。
                        RValues[Col]    = LinearStretch(RValues[Col], InputImg.Min[InputImg.BandList[0] - 1], InputImg.Max[InputImg.BandList[0] - 1]);
                        GValues[Col]    = LinearStretch(GValues[Col], InputImg.Min[InputImg.BandList[1] - 1], InputImg.Max[InputImg.BandList[1] - 1]);
                        BValues[Col]    = LinearStretch(BValues[Col], InputImg.Min[InputImg.BandList[2] - 1], InputImg.Max[InputImg.BandList[2] - 1]);
                        GrayValues[Col] = RGBWeight[0] * RValues[Col] + RGBWeight[1] * GValues[Col] + RGBWeight[2] * BValues[Col];
                    }

                    //写结果到新栅格
                    DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, GrayValues, xSize, 1, 0, 0);
                    DS.FlushCache();
                }

                FP.Finish();
                Dri.Dispose();
                DS.Dispose();
                return(true);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
                return(false);
            }
        }
예제 #10
0
        /// <summary>
        /// 导出当前视图。
        /// </summary>
        /// <param name="InputImg">影像对象。</param>
        /// <param name="OutDataType">输出数据类型。</param>
        /// <param name="OutPath">输出路径。</param>
        /// <returns>返回操作成功或失败。</returns>
        public static bool ExportView(Img InputImg, OSGeo.GDAL.DataType OutDataType, string OutPath)
        {
            try
            {
                if (OutPath == InputImg.Path)
                {
                    throw new Exception("输出路径与源文件相同。");
                }
                if (InputImg.GDALDataset == null)
                {
                    throw new ArgumentNullException("输入数据集为空。");
                }
                if (String.IsNullOrWhiteSpace(OutPath.Trim()))
                {
                    throw new ArgumentNullException("输出路径为空或非法。");
                }
                OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff");
                if (Dri == null)
                {
                    throw new Exception("无法获取GDAL Driver。");
                }

                int xSize   = InputImg.Width;
                int ySize   = InputImg.Height;
                int Bandnum = 3;
                if (InputImg.IsGrayscale)
                {
                    Bandnum = 1;
                }
                else
                {
                    Bandnum = 3;
                }

                FrmProgress FP = new FrmProgress()
                {
                    Text = "正在导出影像...",
                };

                Thread t = new Thread(() =>
                {
                    FP.ShowDialog();
                });
                t.SetApartmentState(ApartmentState.STA);
                t.Start();

                OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, Bandnum, OutDataType, null);
                FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。");
                Tools.Common.CopyMetadata(InputImg.GDALDataset, DS);

                for (int i = 0; i < Bandnum; i++) //遍历每个波段
                {
                    FP.SetProgress2("正在处理", i + 1, Bandnum, "波段");
                    for (int Row = 0; Row < ySize; Row++)   //遍历每一行(y)
                    {
                        FP.SetProgress1("正在处理", Row + 1, ySize, "行");
                        double[] Values = new double[xSize];

                        //读取DN到数组
                        InputImg.GDALDataset.GetRasterBand(InputImg.BandList[i]).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0);
                        for (int Col = 0; Col < xSize; Col++)   //对每一个值进行计算
                        {
                            //无拉伸不做处理直接导出
                            if (InputImg.StretchMode == 0)
                            {
                                break;
                            }
                            //已经有处理的情形
                            switch (InputImg.StretchMode)
                            {
                            case 1:
                            case 2:
                            case 3:
                            case 4:
                            case 9:
                            {
                                //线性
                                Values[Col] = LinearStretch(Values[Col], InputImg.StretchInfo[InputImg.BandList[i] - 1].Item1, InputImg.StretchInfo[InputImg.BandList[i] - 1].Item2);
                                break;
                            }

                            case 5:
                            {
                                //直方图均衡
                                Values[Col] = EqualizationStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]);
                                break;
                            }

                            case 6:
                            {
                                //高斯
                                Values[Col] = GaussianStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Mean[InputImg.BandList[i] - 1], InputImg.Stddev[InputImg.BandList[i] - 1]);
                                break;
                            }

                            case 7:
                            {
                                //平方根
                                Values[Col] = SquarerootStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]);
                                break;
                            }

                            case 8:
                            {
                                //对数
                                Values[Col] = LinearStretch(LogarithmicStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]), InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]);
                                break;
                            }

                            default:
                            {
                                //不是0-9还能是啥?
                                throw new Exception("拉伸模式未知。");
                            }
                            }
                        }
                        //写结果到新栅格
                        DS.GetRasterBand(i + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0);
                        DS.FlushCache();
                        Thread.Sleep(1);
                        if (FP.Canceled)
                        {
                            Thread.Sleep(500);

                            FP.Finish();
                            throw new OperationCanceledException("操作被用户取消。");
                        }
                    }
                }

                FP.Finish();
                Dri.Dispose();
                DS.Dispose();
                return(true);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message);
                return(false);
            }
        }
예제 #11
0
        private static void ReadRasterBlocks(ref Dataset valueRaster, ref Dataset zoneRaster)
        {
            _rasInfoDict = new Dictionary<int, StatisticsInfo>[valueRaster.RasterCount];

            int valueRasterBandCount = valueRaster.RasterCount;

            int rasterRows = zoneRaster.RasterYSize;
            int rasterCols = zoneRaster.RasterXSize;

            const int blockSize = AppUtils.GdalUtilConstants.RasterBlockSize;

            for (int rasBand = 0; rasBand < valueRasterBandCount; rasBand++)
            {
                Band bandValueRaster = valueRaster.GetRasterBand(rasBand + 1);
                Band bandZoneRaster = zoneRaster.GetRasterBand(1);

                _rasInfoDict[rasBand] = new Dictionary<int, StatisticsInfo>();

                for (int row = 0; row < rasterRows; row += blockSize)
                {
                    int rowProcess;
                    if (row + blockSize < rasterRows)
                    {
                        rowProcess = blockSize;
                    }
                    else
                    {
                        rowProcess = rasterRows - row;
                    }

                    for (int col = 0; col < rasterCols; col += blockSize)
                    {
                        int colProcess;
                        if (col + blockSize < rasterCols)
                        {
                            colProcess = blockSize;
                        }
                        else
                        {
                            colProcess = rasterCols - col;
                        }

                        double[] valueRasterValues = new double[rowProcess * colProcess];
                        double[] zoneRasterValues = new double[rowProcess * colProcess];

                        bandValueRaster.ReadRaster(col, row, colProcess, rowProcess, valueRasterValues, colProcess, rowProcess, 0, 0);
                        bandZoneRaster.ReadRaster(col, row, colProcess, rowProcess, zoneRasterValues, colProcess, rowProcess, 0, 0);

                        ProcessEachRasterBlock(valueRasterValues, zoneRasterValues, rasBand, ref _rasInfoDict);
                    }
                }
            }

            //flush rasters cache
            valueRaster.FlushCache();
            zoneRaster.FlushCache();

            valueRaster.Dispose();
            zoneRaster.Dispose();

            StatisticsExport writer = new StatisticsExport(_zoneFile);
            writer.ExportZonalStatistics(ref _rasInfoDict, _cellSize);
        }
예제 #12
0
        //变化检测
        private void ChangeDetectionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                //选择第一张影像
                FrmImgSelect FIS1 = new FrmImgSelect(Images, "变化检测 - 选择变化前影像...");
                if (FIS1.ShowDialog(this) == DialogResult.OK)
                {
                    //选择第二张影像
                    FrmImgSelect FIS2 = new FrmImgSelect(Images, "变化检测 - 选择变化后影像...");
                    if (FIS2.ShowDialog(this) == DialogResult.OK)
                    {
                        //选择差值影像导出位置
                        FrmExport E1 = new FrmExport("选择差值计算结果存储位置。");
                        if (E1.ShowDialog(this) == DialogResult.OK)
                        {
                            //选择比值影像导出位置
                            FrmExport E2 = new FrmExport("选择比值计算结果存储位置。");
                            if (E2.ShowDialog(this) == DialogResult.OK)
                            {
                                string tmpD1Gray = Tools.Common.GetTempFileName();
                                string tmpD2Gray = Tools.Common.GetTempFileName();

                                string tmpMinus  = Tools.Common.GetTempFileName();
                                string tmpDivide = Tools.Common.GetTempFileName();
                                bool   divSucc   = false;
                                bool   minusSucc = false;

                                //灰度化
                                if (Tools.Common.RGB2GrayScale(FIS1.SelectedImg, new double[3] {
                                    0.299, 0.587, 0.114
                                }, DataType.GDT_Float32, tmpD1Gray))
                                {
                                    OSGeo.GDAL.Dataset tmpD1GrayDS = OSGeo.GDAL.Gdal.Open(tmpD1Gray, OSGeo.GDAL.Access.GA_ReadOnly);
                                    if (Tools.Common.RGB2GrayScale(FIS2.SelectedImg, new double[3] {
                                        0.299, 0.587, 0.114
                                    }, DataType.GDT_Float32, tmpD2Gray))
                                    {
                                        OSGeo.GDAL.Dataset tmpD2GrayDS = OSGeo.GDAL.Gdal.Open(tmpD2Gray, OSGeo.GDAL.Access.GA_ReadOnly);

                                        //相减
                                        if (Tools.BaseProcess.Minus(tmpD2GrayDS, tmpD1GrayDS, DataType.GDT_Float32, tmpMinus))
                                        {
                                            OSGeo.GDAL.Dataset tmpMinusDS = OSGeo.GDAL.Gdal.Open(tmpMinus, OSGeo.GDAL.Access.GA_ReadOnly);
                                            if (Tools.ImageSplit.Binarize(tmpMinusDS, Tools.ImageSplit.IterateThreshold(tmpMinusDS), 0, 1, E1.OutDataType, E1.OutPath))
                                            {
                                                minusSucc = true;
                                            }
                                            tmpMinusDS.Dispose();
                                            if (File.Exists(tmpMinus))
                                            {
                                                File.Delete(tmpMinus);
                                            }
                                        }

                                        //相除
                                        if (Tools.BaseProcess.Divide(tmpD2GrayDS, tmpD1GrayDS, DataType.GDT_Float32, tmpDivide))
                                        {
                                            OSGeo.GDAL.Dataset tmpDivideDS = OSGeo.GDAL.Gdal.Open(tmpDivide, OSGeo.GDAL.Access.GA_ReadOnly);
                                            if (Tools.ImageSplit.Binarize(tmpDivideDS, Tools.ImageSplit.IterateThreshold(tmpDivideDS), 0, 1, E2.OutDataType, E2.OutPath))
                                            {
                                                divSucc = true;
                                            }
                                            tmpDivideDS.Dispose();
                                            if (File.Exists(tmpDivide))
                                            {
                                                File.Delete(tmpDivide);
                                            }
                                        }
                                        tmpD2GrayDS.Dispose();
                                        if (File.Exists(tmpD2Gray))
                                        {
                                            File.Delete(tmpD2Gray);
                                        }
                                    }
                                    tmpD1GrayDS.Dispose();
                                    if (File.Exists(tmpD1Gray))
                                    {
                                        File.Delete(tmpD1Gray);
                                    }
                                }
                                if (minusSucc)
                                {
                                    CheckFile(E1.OutPath);
                                    ManageTreeView();
                                }
                                if (divSucc)
                                {
                                    CheckFile(E2.OutPath);
                                    ManageTreeView();
                                }
                            }
                            E2.Dispose();
                        }
                        E1.Dispose();
                    }
                    FIS2.Dispose();
                }
                FIS1.Dispose();
            }
            catch (Exception err)
            {
                MessageBox.Show(err.ToString());
            }
        }