Isis 3.0 Application Source Code Reference |
Home |
00001 #include <cmath> 00002 #include "Isis.h" 00003 #include "ProcessByBoxcar.h" 00004 #include "Constants.h" 00005 #include "SpecialPixel.h" 00006 00007 using namespace std; 00008 using namespace Isis; 00009 00010 double pixelResolution; 00011 double saz; 00012 double zenith; 00013 00014 void shade(Buffer &in, double &v); 00015 00016 void IsisMain() { 00017 00018 const double DEG2RAD = PI / 180.0; 00019 ProcessByBoxcar p; 00020 00021 UserInterface &ui = Application::GetUserInterface(); 00022 00023 // Open the input cube 00024 Cube *inCube = p.SetInputCube("FROM"); 00025 00026 // Allocate the output cube 00027 p.SetOutputCube("TO"); 00028 00029 p.SetBoxcarSize(3, 3); 00030 00031 // Read user parameters 00032 // This parameter as used by the algorithm is 0-360 with 0 at 3 o'clock, 00033 // increasing in the clockwise direction. The value taken in from the user is 00034 // 0-360 with 0 at 12 o'clock increasing in the clockwise direction. 00035 saz = ui.GetDouble("AZIMUTH"); 00036 saz += 270; 00037 if(saz > 360) saz -= 360; 00038 saz *= DEG2RAD; 00039 00040 // This parameter as used by the algorithm is 0-90 as the angle to the light source, 00041 // this means 90 is at the horizon and 0 is directly overhead. 00042 zenith = ui.GetDouble("ZENITH"); 00043 zenith *= DEG2RAD; 00044 00045 // Get from labels or from user 00046 if(ui.WasEntered("PIXELRESOL")) { 00047 pixelResolution = ui.GetDouble("PIXELRESOL"); 00048 } 00049 else { 00050 if(inCube->getLabel()->FindObject("IsisCube").HasGroup("Mapping")) { 00051 pixelResolution = inCube->getLabel()->FindObject("IsisCube").FindGroup("Mapping")["PixelResolution"]; 00052 } 00053 else { 00054 string msg = "The file [" + ui.GetFilename("FROM") + "] does not have a mapping group," 00055 + " you must enter a Pixel Resolution"; 00056 throw iException::Message(iException::User, msg, _FILEINFO_); 00057 } 00058 } 00059 00060 p.StartProcess(shade); 00061 p.EndProcess(); 00062 00063 } 00064 00065 // Shade processing routine 00066 void shade(Buffer &in, double &v) { 00067 00068 // first we just check to make sure that we don't have any special pixels 00069 bool specials = false; 00070 for(int i = 0; i < in.size(); ++i) { 00071 if(IsSpecial(in[i])) { 00072 specials = true; 00073 } 00074 } 00075 00076 // if we have any special pixels we bail out (well ok just set to null) 00077 if(specials) { 00078 v = Isis::Null; 00079 } 00080 else { 00081 /* if we have a 3x3 section that doesn't have an special pixels we hit that 3x3 00082 / against two gradients 00083 00084 [-1 0 1 ] [-1 -1 -1 ] 00085 [-1 0 1 ] [ 0 0 0 ] 00086 [-1 0 1 ] [ 1 1 1 ] 00087 00088 These two gradients are not special in any way aside from that they are 00089 are orthogonal. they can be replaced if someone has reason as long as they 00090 stay orthogonal to eachoher. (for those that don't know orthoginal means 00091 for matrix A: A * transpose(A) = I where I is the identity matrix). 00092 00093 */ 00094 00095 double p = ((-1) * in[0] + (0) * in[1] + (1) * in[2] 00096 + (-1) * in[3] + (0) * in[4] + (1) * in[5] 00097 + (-1) * in[6] + (0) * in[7] + (1) * in[8]) / (3.0 * pixelResolution); 00098 00099 double q = ((-1) * in[0] + (-1) * in[1] + (-1) * in[2] 00100 + (0) * in[3] + (0) * in[4] + (0) * in[5] 00101 + (1) * in[6] + (1) * in[7] + (1) * in[8]) / (3.0 * pixelResolution); 00102 00103 /* after we hit them by the gradients the formula in order to make the shade is 00104 00105 1 + p0*p + q0*q 00106 shade = ------------------------------------------------- 00107 sqrt(1 + p*p + Q*q) + sqrt(1 + p0*p0 + q0*q0) 00108 00109 where p0 = -cos( sun azimuth ) * tan( solar elevation ) and 00110 q0 = -sin( sun azimuth ) * tan( solar elevation ) 00111 00112 and p and q are the two orthogonal gradients of the data (calculated above) 00113 00114 this equation comes from 00115 Horn, B.K.P. (1982). "Hill shading and the reflectance map". Geo-processing, v. 2, no. 1, p. 65-146. 00116 00117 It is avaliable online at http://people.csail.mit.edu/bkph/papers/Hill-Shading.pdf 00118 */ 00119 double p0 = -cos(saz) * tan(zenith); 00120 double q0 = -sin(saz) * tan(zenith); 00121 00122 double numerator = 1.0 + p0 * p + q0 * q; 00123 00124 double denominator = sqrt(1 + p * p + q * q) + sqrt(1 + p0 * p0 + q0 * q0); 00125 00126 v = numerator / denominator; 00127 00128 } 00129 }