![]() |
TurboWavelets.Net
Compact C# Implementation for very fast and flexible wavelet transformations
|
00001 // 00002 // Biorthogonal53Wavelet1DStatic.cs 00003 // 00004 // Author: 00005 // Stefan Moebius 00006 // Date: 00007 // 2016-04-09 00008 // 00009 // Copyright (c) 2016 Stefan Moebius 00010 // 00011 // Permission is hereby granted, free of charge, to any person obtaining a copy 00012 // of this software and associated documentation files (the "Software"), to deal 00013 // in the Software without restriction, including without limitation the rights 00014 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00015 // copies of the Software, and to permit persons to whom the Software is 00016 // furnished to do so, subject to the following conditions: 00017 // 00018 // The above copyright notice and this permission notice shall be included in 00019 // all copies or substantial portions of the Software. 00020 // 00021 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00022 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00023 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00024 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00025 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00026 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00027 // THE SOFTWARE. 00028 00029 using System; 00030 00031 namespace TurboWavelets 00032 { 00033 public class Biorthogonal53Wavelet1DStatic 00034 { 00043 public static void wavelet53_1d (float[] src, float[] dst, int length) 00044 { 00045 if (length >= 3) { 00046 int half = length >> 1; 00047 //if the length is even then subtract 1 from "half" 00048 //as there is the same number of low and high frequency values 00049 //(Note that "num_lf_values" is equal to "half+1") 00050 //For a odd length there is one additional low frequency value (so do not subtract 1) 00051 //"half" is one less than "num_lf_values" as we cannot directly 00052 //calculate the last value in the for-loop (array bounds) 00053 if ((length & 1) == 0) 00054 half--; 00055 int offsrc = 0; 00056 // starting offset for high frequency values (= number of low frequency values) 00057 int offdst = half + 1; 00058 int num_lf_values = offdst; 00059 00060 float last_hf = 0.0f; 00061 for (int i = 0; i < half; i++) { 00062 //calculate the high frequency value by 00063 //subtracting the mean of the immediate neighbors for every second value 00064 float hf = src [offsrc + 1] - (src [offsrc] + src [offsrc + 2]) * 0.5f; 00065 //smoothing the low frequency value, scale by factor 2 00066 //(instead of scaling low frequencies by factor sqrt(2) and 00067 //shrinking high frequencies by factor sqrt(2) 00068 //and reposition to have all low frequencies on the left side 00069 dst [i] = 2.0f * (src [offsrc] + (last_hf + hf) * 0.25f); 00070 dst [offdst++] = hf; 00071 last_hf = hf; 00072 offsrc += 2; 00073 } 00074 if ((length & 1) == 0) { 00075 //the secound last value in the array is our last low frequency value 00076 dst [num_lf_values - 1] = src [length - 2]; 00077 //the last value is a high frequency value 00078 //however here we just subtract the previos value (so not really a 00079 //biorthogonal 5/3 transformation) 00080 //This is done because the 5/3 wavelet cannot be calculated at the boundary 00081 dst [length - 1] = src [length - 1] - src [length - 2]; 00082 } else { 00083 dst [num_lf_values - 1] = src [length - 1]; 00084 } 00085 } else { 00086 //We cannot perform the biorthogonal 5/3 wavelet transformation 00087 //for lengths smaller than 3. We could do a simpler transformation... 00088 //Here however, we just copy the values from the source to the destination array 00089 for (int i = 0; i < length; i++) 00090 dst [i] = src [i]; 00091 } 00092 } 00093 00102 public static void wavelet53_1d_inverse (float[] src, float[] dst, int length) 00103 { 00104 if (length >= 3) { 00105 int half = length >> 1; 00106 //if the length is even then subtract 1 from "half" 00107 //as there is the same number of low and high frequency values 00108 //(Note that "num_lf_values" is equal to "half+1") 00109 //For a odd length there is one additional low frequency value (so do not subtract 1) 00110 //"half" is one less than "num_lf_values" as we cannot directly 00111 //calculate the last value in the for-loop (array bounds) 00112 if ((length & 1) == 0) 00113 half--; 00114 // number of low frequency values 00115 int num_lf_values = half + 1; 00116 00117 float last_lf = 0.5f * src [0] - src [num_lf_values] * 0.25f; 00118 float last_hf = src [num_lf_values]; 00119 //Calculate the first two values outside the for loop (array bounds) 00120 dst [0] = last_lf; 00121 dst [1] = last_hf + last_lf * 0.5f; 00122 for (int i = 1; i < half; i++) { 00123 float hf = src [num_lf_values + i]; 00124 float lf = 0.5f * src [i]; 00125 //reconstruct the original value by removing the "smoothing" 00126 float lf_reconst = lf - (hf + last_hf) * 0.25f; 00127 dst [2 * i] = lf_reconst; 00128 //add reconstructed low frequency value (left side) and high frequency value 00129 dst [2 * i + 1] = lf_reconst * 0.5f + hf; 00130 //add other low frequency value (right side) 00131 //This must be done one iteration later, as the 00132 //reconstructed values is not known earlier 00133 dst [2 * i - 1] += lf_reconst * 0.5f; 00134 last_hf = hf; 00135 last_lf = lf_reconst; 00136 } 00137 00138 if ((length & 1) == 0) { 00139 //restore the last 3 values outside the for loop 00140 //adding the missing low frequency value (right side) 00141 dst [length - 3] += src [num_lf_values - 1] * 0.5f; 00142 //copy the last low frequency value 00143 dst [length - 2] = src [num_lf_values - 1]; 00144 //restore the last value by adding last low frequency value 00145 dst [length - 1] = src [length - 1] + src [num_lf_values - 1]; 00146 } else { 00147 //restore the last 2 values outside the for loop 00148 //adding the missing low frequency value (right side) 00149 dst [length - 2] += src [num_lf_values - 1] * 0.5f; 00150 //copy the last low frequency value 00151 dst [length - 1] = src [num_lf_values - 1]; 00152 } 00153 } else { 00154 //We cannot perform the biorthogonal 5/3 wavelet transformation 00155 //for lengths smaller than 3. We could do a simpler transformation... 00156 //Here however, we just copy the values from the source to the destination array 00157 for (int i = 0; i < length; i++) 00158 dst [i] = src [i]; 00159 } 00160 } 00161 } 00162 } 00163