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); } }
/// <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); } }
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); } }
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); }
/// <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); }
/// <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); } }
/// <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); } }
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; }
/// <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); } }
/// <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); } }
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); }
//变化检测 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()); } }