C#ArcEngine二次开发影像去黑边问题
我的代码如下,通过设置nodata值进行去黑边,
ESRI.ArcGIS.DataManagementTools.CopyRaster rc = new ESRI.ArcGIS.DataManagementTools.CopyRaster();
rc.in_raster = fName;//
rc.out_rasterdataset = tifname;
rc.background_value = 0;
rc.nodata_value = "0";
rc.pixel_type = "32_BIT_FLOAT";
ESRI.ArcGIS.Geoprocessor.Geoprocessor GP = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
GP.Execute(rc, null);
}
但是效率很低,处理时间在5分钟以上,因为影像也比较大。请问有没有其他方法提高效率进行去黑边处理
引用chatGPT作答,您可以尝试使用基于像素值的遮罩来去除黑边。以下是一些建议:
1.计算图像的边界像元。您可以使用Con工具来实现这一点。例如,您可以将像素值为0的像元(黑色)设置为1,而其他像元(非黑色)设置为0。然后,您可以使用RasterToPolygon工具将该栅格转换为多边形要素。
2.缓冲区多边形要素。这将为每个多边形创建一个缓冲区,以便在稍后使用。缓冲区的大小应根据影像的黑边大小来设置。
3.将缓冲区要素转换为遮罩。使用FeatureToRaster工具将缓冲区要素转换为栅格遮罩。
4.将原始影像和栅格遮罩相乘。使用Times工具将原始影像和栅格遮罩相乘。这将移除黑边并创建一个新的栅格数据集。
以下是一个基于上述步骤的C#代码示例:
ESRI.ArcGIS.DataManagementTools.Con con = new ESRI.ArcGIS.DataManagementTools.Con();
con.in_conditional_raster = fName;
con.in_true_raster_or_constant = 0;
con.in_false_raster_or_constant = 1;
con.out_raster = "boundary.tif";
ESRI.ArcGIS.Geoprocessor.Geoprocessor GP = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
GP.Execute(con, null);
ESRI.ArcGIS.DataManagementTools.RasterToPolygon toPoly = new ESRI.ArcGIS.DataManagementTools.RasterToPolygon();
toPoly.in_raster = "boundary.tif";
toPoly.out_polygon_features = "boundary.shp";
toPoly.simplify = "NO_SIMPLIFY";
GP.Execute(toPoly, null);
ESRI.ArcGIS.AnalysisTools.Buffer buffer = new ESRI.ArcGIS.AnalysisTools.Buffer();
buffer.in_features = "boundary.shp";
buffer.out_feature_class = "buffer.shp";
buffer.buffer_distance_or_field = "10"; // 缓冲区大小根据黑边大小调整
buffer.line_side = "FULL";
buffer.line_end_type = "ROUND";
buffer.dissolve_option = "NONE";
GP.Execute(buffer, null);
ESRI.ArcGIS.ConversionTools.FeatureToRaster toRaster = new ESRI.ArcGIS.ConversionTools.FeatureToRaster();
toRaster.in_features = "buffer.shp";
toRaster.out_raster = "mask.tif";
toRaster.field = "GRIDCODE";
toRaster.cell_size = fName;
toRaster.setnull_values = "0";
GP.Execute(toRaster, null);
ESRI.ArcGIS.SpatialAnalystTools.Times times = new ESRI.ArcGIS.SpatialAnalystTools.Times();
times.in_raster_or_constant1 = fName;
times.in_raster_or_constant2 = "mask.tif";
times.out_raster = tifname;
GP.Execute(times, null);
以下回答参考GPT,并由JoseKe整理完成,希望您能采纳:
ESRI.ArcGIS.DataManagementTools.CopyRaster rc = new ESRI.ArcGIS.DataManagementTools.CopyRaster();
rc.in_raster = fName;//
rc.out_rasterdataset = tifname;
rc.background_value = 0;
rc.nodata_value = "0";
rc.pixel_type = "32_BIT_FLOAT";
ESRI.ArcGIS.Geoprocessor.Geoprocessor GP = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
//获取数据集范围
IRasterDataset2 rds = GP.Open(raster_path) as IRasterDataset2;
IRasterProps rProps = rds as IRasterProps;
IPnt tileSize = new PntClass();
tileSize.SetCoords(256, 256);
IGPValue TileSize = new GPValueClass();
TileSize.SetAsText(tileSize.X.ToString() + " " + tileSize.Y.ToString());
IRasterDataset3 rasterDs = rds as IRasterDataset3;
IRasterTypeProperties rasterTypeProps = rasterDs as IRasterTypeProperties;
IGPUtilities gpUtils = new GPUtilitiesClass();
List<string> BlockPaths = new List<string>();
int MinBlockNumber = gpUtils.GetCount(rds, tileSize)[0];
rasterTypeProps.MeanCellSizeProperties = rProps.MeanCellSize();
int tiles = 0;
while (tiles < MinBlockNumber)
{
try
{
string block = Path.GetDirectoryName(tifpath) + "\\" +Path.GetFileNameWithoutExtension(tifpath) + "_block_" + tiles.ToString() + ".tif";
ESRI.ArcGIS.DataManagementTools.ExtractSubDataset extractSubDataset = new ESRI.ArcGIS.DataManagementTools.ExtractSubDataset();
extractSubDataset.in_raster = raster_path;
extractSubDataset.out_raster = block;
extractSubDataset.where_clause = "OBJECTID >= " + ((tiles) * tileSize.X * tileSize.Y + 1) + " AND OBJECTID <= " + (((tiles + 1) * tileSize.X * tileSize.Y) >= rProps.Width * rProps.Height ? rProps.Width * rProps.Height : ((tiles + 1) * tileSize.X * tileSize.Y));
GP.Execute(extractSubDataset, null);
BlockPaths.Add(block);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
tiles++;
}
//新建多线程处理块数据
int maxThreads = 8;
int blockCount = BlockPaths.Count;
Semaphore sem = new Semaphore(maxThreads, maxThreads);
List<Thread> threads = new List<Thread>();
for (int i = 0; i < blockCount; i++)
{
sem.WaitOne();
Thread t = new Thread(new ParameterizedThreadStart(Execute));
t.Start(new object[] { BlockPaths[i], rc });
threads.Add(t);
}
//等待所有线程执行完毕
foreach (Thread t in threads)
{
t.Join();
}
private void Execute(object o)
{
object[] args = o as object[];
string raster = args[0].ToString();
ESRI.ArcGIS.DataManagementTools.CopyRaster rc = args[1] as ESRI.ArcGIS.DataManagementTools.CopyRaster;
ESRI.ArcGIS.Geoprocessor.Geoprocessor GP = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
GP.Execute(rc, null);
sem.Release();
}