PIE SDK过滤控制

Posted piesat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PIE SDK过滤控制相关的知识,希望对你有一定的参考价值。

 

1.  功能简介

    栅格数据前置过滤是在渲染之前对内存中的数据根据特定的规则进行处理,然后再进行数据渲染。本示例以定标为例进行示例代码编写。

    定标(校准)是将遥感器所得的测量值变换为绝对亮度或变换为与地表反射率、表面温度等物理量有关的相对值的处理过程。或者说,遥感器定标就是建立遥感器每个探测器输出值与该探测器对应的实际地物辐射亮度之间的定量关系。它是遥感定量化的前提。

    栅格后置过滤是对渲染过程的控制。本示例以曲线调整为例进行示例代码编写

    灰度拉伸又叫对比度拉伸,它是最基本的一种灰度变换,使用的是最简单的分段线性变换函数,它的主要思想是提高图像处理时灰度级的动态范围。

 技术分享图片

[灰度拉伸函数]

 

2. 功能实现说明

2.1  实现思路及原理说明

    本示例代码以FY-4A数据的定标为例,已经运用静止卫星数据读取方法,读取NOMChannel13波段数据为tiff。

前置过滤(以定标为例)

第一步

初始化前置过滤回调函数。

第二步

实现定标算法。

第三步

实例化自定义前置过滤对象。

第四步

为前置过滤对象设置前置过滤算法

第五步

接口转换

第六步

添加前置过滤器

后置过滤(以曲线拉伸为例)

第一步

初始化拉伸结果表。

第二步

添加折点。

第三步

根据折点,计算结果拉伸表。

第四步

实例化后置过滤器

第五步

设置对照表

第六步

接口转换,添加后置过滤条件

2.2 核心接口与方法

接口/类

方法

说明

前置过滤

Carto.PreFilterFunCallback

 

 

Carto.ICustomerPreRasterFilter

SetPreFilterFun

设置前置过滤算法

Carto.IrasterFilterProps

AddPreRasterFilter

添加前置过滤

后置过滤

Carto. ILutAfterFilter

SetLut

为指定波段设置对照表

Carto. IRasterFilterProps

AddAfterRasterFilter

添加后置过滤器

2.3 示例代码

项目路径

百度云盘地址下/PIE示例程序/07图层渲染/12.栅格过滤制

数据路径

百度云盘地址下/PIE示例数据/栅格数据/ FY/FY4A/

视频路径

百度云盘地址下/PIE视频教程/07图层渲染/12.栅格过滤控制.avi

示例代码

技术分享图片
  1 方法(一)
  2     //前置过滤本示例以定标为例
  3     //风云4A数据为例
  4     IRasterLayer rasterLayer = mapControlMain.ActiveView.CurrentLayer as IRasterLayer;
  5     IRasterRender rasterRender = RenderFactory.ImportFromFile(@"C:UserszhangyiweiDesktopTestDataICV-BD.xml");
  6 
  7     //实例化定标函数
  8     CaliCommon common = new CaliCommon();
  9     string hdfpath = (rasterLayer as ILayer).DataSourcePath;
 10     common.Initialize(hdfpath, "NOMChannel13");
 11 
 12     //添加前置过滤
 13     PIE.Carto.ICustomerPreRasterFilter preFilter = new PIE.Carto.CustomerPreRasterFilter();
 14     preFilter.SetPreFilterFun(common.CaliFunCallBack);
 15 
 16     IRasterClassifyColorRampRender classRender = rasterRender as IRasterClassifyColorRampRender;
 17     (classRender as IRasterFilterProps).AddPreRasterFilter(preFilter as IPreRasterFilter);
 18 
 19     //地图刷新
 20     rasterLayer.Render = rasterRender;
 21 mapControlMain.ActiveView.PartialRefresh(ViewDrawPhaseType.ViewAll);
 22 方法(二)
 23 /// <summary>
 24 /// 定标方法接口
 25 /// </summary>
 26 public interface ICaliFunction
 27 {
 28 /// <summary>
 29 /// 定标回调函数
 30 /// </summary>
 31 PreFilterFunCallback CaliFunCallBack
 32 {
 33     get;
 34 }
 35 
 36 /// <summary>
 37 /// 数据定标
 38 /// </summary>
 39 /// <param name="dataNeedCali">原始数据</param>
 40 /// <param name="width">宽度</param>
 41 /// <param name="height">高度</param>
 42 /// <param name="bandCount">波段</param>
 43 /// <returns>定标后数据</returns>
 44 float[] Cali<T>(T[] dataNeedCali, int width, int height, int bandCount);
 45 
 46 /// <summary>
 47 /// 定标算法函数
 48 /// </summary>
 49 unsafe bool CaliFilter(IntPtr valuesA, IntPtr valuesB);
 50 }
 51 
 52 /// <summary>
 53 /// 风云4A数据的定标方法
 54 /// </summary>
 55 public class CaliCommon : ICaliFunction
 56 {
 57 /// <summary>
 58 /// 定标数据
 59 /// </summary>
 60 private float[] m_DBDatas = null;
 61 
 62 /// <summary>
 63 /// 定标数据长度
 64 /// </summary>
 65 private int m_Count = 0;
 66 
 67 /// <summary>
 68 /// 定标回调函数
 69 /// </summary>
 70 private PreFilterFunCallback m_CaliFunCallBack = null;
 71 
 72 /// <summary>
 73 /// 构造函数
 74 /// </summary>
 75 public CaliCommon()
 76 {
 77 }
 78 
 79 /// <summary>
 80 /// 定标回调函数
 81 /// </summary>
 82 public PreFilterFunCallback CaliFunCallBack
 83 {
 84     get
 85     {
 86         return m_CaliFunCallBack;
 87     }
 88 }
 89 
 90 /// <summary>
 91 /// 初始化定标方法
 92 /// </summary>
 93 /// <param name="strFilePath_HDF">hdf文件路径</param>
 94 /// <param name="chanelName">通道名称</param>
 95 /// <returns></returns>
 96 public bool Initialize(string strFilePath_HDF, string chanelName)
 97 {
 98     string calName = chanelName.Replace("NOM", "CAL");
 99     string calFilePath = System.IO.Path.GetDirectoryName(strFilePath_HDF) + "\\" + calName+".tiff";
100     IRasterDataset rasterDataset = PIE.DataSource.DatasetFactory.OpenRasterDataset(calFilePath, OpenMode.ReadOnly);
101 
102     int height = rasterDataset.GetRasterYSize();
103 
104     m_DBDatas = new float[height];
105     int[] bandMap = { 1 };
106     rasterDataset.Read(0, 0, 1, height, m_DBDatas, 1, height, PixelDataType.Float32, 1, bandMap);
107 
108     (rasterDataset as IDisposable).Dispose();
109 
110     m_Count = m_DBDatas.Length;
111     m_CaliFunCallBack = new PreFilterFunCallback(CaliFilter);
112     GC.KeepAlive(m_CaliFunCallBack);
113     return true;
114 }
115 
116 /// <summary>
117 /// 数据定标
118 /// </summary>
119 /// <param name="dataNeedCali">原始数据</param>
120 /// <param name="width">宽度</param>
121 /// <param name="height">高度</param>
122 /// <param name="bandCount">波段</param>
123 /// <returns>定标后数据</returns>
124 public float[] Cali<T>(T[] dataNeedCali, int width, int height, int bandCount)
125 {
126     if (dataNeedCali == null || dataNeedCali.Length < 1)
127     {
128         return null;
129     }
130 
131     float[] dataCali = new float[width * height * bandCount];
132     for (int j = 0; j < height; j++)
133     {
134         for (int i = 0; i < width; i++)
135         {
136             for (int m = 0; m < bandCount; m++)
137             {
138                 int nIndex = (j * width + i) * bandCount + m;
139                 int value = Convert.ToInt32(dataNeedCali[nIndex]);
140                 if (value < 0 || value >= m_Count)
141                 {
142                     dataCali[nIndex] = 0;
143                 }
144                 else
145                 {
146                     dataCali[nIndex] = m_DBDatas[value];
147                 }
148             }
149         }
150     }
151     return dataCali;
152 }
153 
154 /// <summary>
155 /// 定标算法
156 /// </summary>
157 /// <param name="valuesA">定标前</param>
158 /// <param name="valuesB">定标后</param>
159 /// <returns></returns>
160 public unsafe bool CaliFilter(IntPtr valuesA, IntPtr valuesB)
161 {
162     if (m_DBDatas == null)
163     {
164         return false;
165     }
166     IPixelBuffer pixelBuffer = PIE.DataSource.DatasetFactory.ConstructCLRPixelBuffer(valuesA.ToPointer());
167     int width = pixelBuffer.Width;
168     int height = pixelBuffer.Height;
169     int bandCount = pixelBuffer.BandMap.Length;
170 
171     float[] valuesData = new float[width * height * bandCount];
172 
173     short* byteValues = (short*)(pixelBuffer.GetData_Ref().ToPointer());
174     for (int j = 0; j < height; j++)
175     {
176         for (int i = 0; i < width; i++)
177         {
178             for (int m = 0; m < bandCount; m++)
179             {
180                 int nIndex = (j * width + i) * bandCount + m;
181                 int value = *(byteValues + nIndex);
182                 if (value < 0 || value >= m_Count)
183                 {
184                     valuesData[nIndex] = 0;
185                 }
186                 else
187                 {
188                     valuesData[nIndex] = m_DBDatas[value];
189                 }
190             }
191         }
192     }
193     pixelBuffer.SetData(PixelDataType.Float32, valuesData);
194     return true;
195 }
196 }
View Code

2.4  示例截图

(一)   前置过滤

技术分享图片

(二)   后置过滤

 

以上是关于PIE SDK过滤控制的主要内容,如果未能解决你的问题,请参考以下文章

PIE SDK矢量数据的创建

PIE SDK内存矢量数据的创建

PIE SDK应用掩膜中将二值图像的0和1值进行转换

PIE SDK 监督分类对话框类(SupervisedClassificaitonDialog)使用经验

PIE SDK图像旋转

PIE SDK打开GDBDwg数据