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:\Users\zhangyiwei\Desktop\TestData\ICV-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過濾控制