Commit 35a7195f62dc2428df5f4b6024956ebdb8713e1b
1 parent
1b2858a2
added median spectra to ENVI files, updated mean spectra in interleave formats
Showing
9 changed files
with
140 additions
and
79 deletions
Show diff stats
matlab/enviLoadRaw.m
matlab/enviSaveRaw.m
stim/cuda/cudatools/error.h
... | ... | @@ -11,12 +11,7 @@ using namespace std; |
11 | 11 | //handle error macro |
12 | 12 | static void HandleError( cudaError_t err, const char *file, int line ) { |
13 | 13 | if (err != cudaSuccess) { |
14 | - //FILE* outfile = fopen("cudaErrorLog.txt", "w"); | |
15 | - //fprintf(outfile, "%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); | |
16 | - //fclose(outfile); | |
17 | 14 | printf("%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); |
18 | - //exit( EXIT_FAILURE ); | |
19 | - | |
20 | 15 | } |
21 | 16 | } |
22 | 17 | #define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ )) | ... | ... |
stim/envi/bil.h
... | ... | @@ -992,32 +992,35 @@ public: |
992 | 992 | |
993 | 993 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
994 | 994 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
995 | - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ | |
995 | + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){ | |
996 | 996 | unsigned long long XZ = X() * Z(); |
997 | 997 | unsigned long long XY = X() * Y(); |
998 | 998 | T* temp = (T*)malloc(sizeof(T) * XZ); |
999 | - for (unsigned long long j = 0; j < Z(); j++){ | |
1000 | - p[j] = 0; | |
1001 | - } | |
999 | + memset(m, 0, Z() * sizeof(double)); //initialize the mean to zero | |
1000 | + double* e_x2 = (double*)malloc(Z() * sizeof(double)); //allocate space for E[x^2] | |
1001 | + memset(e_x2, 0, Z() * sizeof(double)); //initialize E[x^2] to zero | |
1002 | 1002 | //calculate vaild number in a band |
1003 | - unsigned long long count = 0; | |
1004 | - for (unsigned long long j = 0; j < XY; j++){ | |
1005 | - if (mask == NULL || mask[j] != 0){ | |
1006 | - count++; | |
1007 | - } | |
1008 | - } | |
1003 | + size_t count = nnz(mask); //count the number of pixels in the mask | |
1004 | + | |
1005 | + double x; //create a register to store the pixel value | |
1009 | 1006 | for (unsigned long long k = 0; k < Y(); k++){ |
1010 | 1007 | read_plane_y(temp, k); |
1011 | 1008 | unsigned long long kx = k * X(); |
1012 | 1009 | for (unsigned long long i = 0; i < X(); i++){ |
1013 | 1010 | if (mask == NULL || mask[kx + i] != 0){ |
1014 | 1011 | for (unsigned long long j = 0; j < Z(); j++){ |
1015 | - p[j] += temp[j * X() + i] / (double)count; | |
1012 | + x = temp[j * X() + i]; | |
1013 | + m[j] += x / (double)count; | |
1014 | + e_x2[j] += x*x / (double)count; | |
1016 | 1015 | } |
1017 | 1016 | } |
1018 | 1017 | } |
1019 | 1018 | if(PROGRESS) progress = (double)(k+1) / Y() * 100; |
1020 | 1019 | } |
1020 | + | |
1021 | + for(size_t i = 0; i < Z(); i++) //calculate the standard deviation | |
1022 | + std[i] = sqrt(e_x2[i] - m[i] * m[i]); | |
1023 | + | |
1021 | 1024 | free(temp); |
1022 | 1025 | return true; |
1023 | 1026 | } | ... | ... |
stim/envi/bip.h
... | ... | @@ -954,26 +954,31 @@ public: |
954 | 954 | |
955 | 955 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
956 | 956 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
957 | - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ | |
957 | + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){ | |
958 | 958 | unsigned long long XY = X() * Y(); //calculate the total number of pixels in the HSI |
959 | 959 | T* temp = (T*)malloc(sizeof(T) * Z()); //allocate space for the current spectrum to be read |
960 | - memset(p, 0, sizeof(double) * Z()); //initialize the average spectrum to zero (0) | |
961 | - //for (unsigned j = 0; j < Z(); j++){ | |
962 | - // p[j] = 0; | |
963 | - //} | |
960 | + memset(m, 0, Z() * sizeof(double)); //set the mean spectrum to zero | |
961 | + double* e_x2 = (double*)malloc(Z() * sizeof(double)); //allocate space for E[x^2] | |
962 | + memset(e_x2, 0, Z() * sizeof(double)); //set all values for E[x^2] to zero | |
964 | 963 | |
965 | 964 | unsigned long long count = nnz(mask); //calculate the number of masked pixels |
966 | - | |
965 | + double x; | |
967 | 966 | for (unsigned long long i = 0; i < XY; i++){ //for each pixel in the HSI |
968 | 967 | if (mask == NULL || mask[i] != 0){ //if the pixel is masked |
969 | 968 | pixel(temp, i); //get the spectrum |
970 | 969 | for (unsigned long long j = 0; j < Z(); j++){ //for each spectral component |
971 | - p[j] += (double)temp[j] / (double)count; //add the weighted value to the average | |
970 | + x = temp[j]; | |
971 | + m[j] += x / (double)count; //add the weighted value to the average | |
972 | + e_x2[j] += x*x / (double)count; | |
972 | 973 | } |
973 | 974 | } |
974 | 975 | if(PROGRESS) progress = (double)(i+1) / XY * 100; //increment the progress |
975 | 976 | } |
976 | 977 | |
978 | + //calculate the standard deviation | |
979 | + for(size_t i = 0; i < Z(); i++) | |
980 | + std[i] = sqrt(e_x2[i] - m[i] * m[i]); | |
981 | + | |
977 | 982 | free(temp); |
978 | 983 | return true; |
979 | 984 | } | ... | ... |
stim/envi/bsq.h
... | ... | @@ -561,12 +561,12 @@ public: |
561 | 561 | free(src[1]); |
562 | 562 | free(dst[0]); |
563 | 563 | free(dst[1]); |
564 | - //if(VERBOSE){ | |
564 | + if(VERBOSE){ | |
565 | 565 | std::cout<<"total time to execute bsq::bip(): "<<t_total<<" ms"<<std::endl; |
566 | 566 | std::cout<<" total time spent processing: "<<pt_total<<" ms"<<std::endl; |
567 | 567 | std::cout<<" total time spent reading: "<<rt_total<<" ms"<<std::endl; |
568 | 568 | std::cout<<" total time spent writing: "<<wt_total<<" ms"<<std::endl; |
569 | - //} | |
569 | + } | |
570 | 570 | return true; //return true |
571 | 571 | } |
572 | 572 | |
... | ... | @@ -1120,27 +1120,61 @@ public: |
1120 | 1120 | |
1121 | 1121 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
1122 | 1122 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
1123 | - bool avg_band(double* p, unsigned char* mask = NULL, bool PROGRESS = false){ | |
1123 | + bool mean_spectrum(double* m, double* std, unsigned char* mask = NULL, bool PROGRESS = false){ | |
1124 | 1124 | unsigned long long XY = X() * Y(); |
1125 | - unsigned long long count = 0; //count will store the number of masked pixels | |
1125 | + unsigned long long count = nnz(mask); //count will store the number of masked pixels | |
1126 | 1126 | T* temp = (T*)malloc(sizeof(T) * XY); |
1127 | - //calculate this loop counts the number of true pixels in the mask | |
1128 | - for (unsigned j = 0; j < XY; j++){ | |
1129 | - if (mask == NULL || mask[j] != 0){ | |
1130 | - count++; | |
1131 | - } | |
1132 | - } | |
1127 | + | |
1133 | 1128 | //this loops goes through each band in B (Z()) |
1134 | 1129 | // masked (or valid) pixels from that band are averaged and the average is stored in p |
1130 | + double e_x; //stores E[x]^2 | |
1131 | + double e_x2; //stores E[x^2] | |
1132 | + double x; | |
1135 | 1133 | for (unsigned long long i = 0; i < Z(); i++){ |
1136 | - p[i] = 0; | |
1134 | + e_x = 0; | |
1135 | + e_x2 = 0; | |
1137 | 1136 | band_index(temp, i); //get the band image and store it in temp |
1138 | 1137 | for (unsigned long long j = 0; j < XY; j++){ //loop through temp, averaging valid pixels |
1139 | 1138 | if (mask == NULL || mask[j] != 0){ |
1140 | - p[i] += (double)temp[j] / (double)count; | |
1139 | + x = (double)temp[j]; | |
1140 | + e_x += x / (double)count; //sum the expected value of x | |
1141 | + e_x2 += (x * x) / (double)count; //sum the expected value of x^2 | |
1142 | + } | |
1143 | + } | |
1144 | + m[i] = e_x; //store the mean | |
1145 | + std[i] = sqrt(e_x2 - e_x * e_x); //calculate the standard deviation | |
1146 | + if(PROGRESS) progress = (double)(i+1) / Z() * 100; //update the progress counter | |
1147 | + } | |
1148 | + free(temp); | |
1149 | + return true; | |
1150 | + } | |
1151 | + | |
1152 | + /// Calculate the median value for all masked (or valid) pixels in a band and returns the median spectrum | |
1153 | + | |
1154 | + /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | |
1155 | + /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | |
1156 | + bool median_spectrum(double* m, unsigned char* mask = NULL, bool PROGRESS = false){ | |
1157 | + size_t XY = X() * Y(); | |
1158 | + size_t count = nnz(mask); //count will store the number of masked pixels | |
1159 | + T* temp = (T*)malloc(sizeof(T) * XY); | |
1160 | + | |
1161 | + std::vector<T> band_values(count); //create an STD vector of band values | |
1162 | + | |
1163 | + //this loops goes through each band in B (Z()) | |
1164 | + // masked (or valid) pixels from that band are averaged and the average is stored in p | |
1165 | + size_t k; | |
1166 | + for (size_t i = 0; i < Z(); i++){ //for each band | |
1167 | + band_index(temp, i); //get the band image and store it in temp | |
1168 | + k = 0; //initialize the band_value index to zero | |
1169 | + for (size_t j = 0; j < XY; j++){ //loop through temp, averaging valid pixels | |
1170 | + if (mask == NULL || mask[j] != 0){ | |
1171 | + band_values[k] = temp[j]; //store the value in the band_values array | |
1172 | + k++; //increment the band_values index | |
1141 | 1173 | } |
1142 | 1174 | } |
1143 | - if(PROGRESS) progress = (double)(i+1) / Z() * 100; | |
1175 | + std::sort(band_values.begin(), band_values.end()); //sort all of the values in the band | |
1176 | + m[i] = band_values[ count/2 ]; //store the center value in the array | |
1177 | + if(PROGRESS) progress = (double)(i+1) / Z() * 100; //update the progress counter | |
1144 | 1178 | } |
1145 | 1179 | free(temp); |
1146 | 1180 | return true; | ... | ... |
stim/envi/envi.h
... | ... | @@ -1380,12 +1380,12 @@ public: |
1380 | 1380 | |
1381 | 1381 | /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum |
1382 | 1382 | /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location |
1383 | - bool avg_band(double * p, unsigned char* mask, bool PROGRESS = false){ | |
1383 | + bool mean_spectrum(double * p, double* std, unsigned char* mask, bool PROGRESS = false){ | |
1384 | 1384 | if (header.interleave == envi_header::BSQ){ |
1385 | 1385 | if (header.data_type == envi_header::float32) |
1386 | - return ((bsq<float>*)file)->avg_band(p, mask, PROGRESS); | |
1386 | + return ((bsq<float>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1387 | 1387 | else if (header.data_type == envi_header::float64) |
1388 | - return ((bsq<double>*)file)->avg_band(p, mask, PROGRESS); | |
1388 | + return ((bsq<double>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1389 | 1389 | else{ |
1390 | 1390 | std::cout << "ERROR: unidentified data type" << std::endl; |
1391 | 1391 | exit(1); |
... | ... | @@ -1393,9 +1393,9 @@ public: |
1393 | 1393 | } |
1394 | 1394 | else if (header.interleave == envi_header::BIL){ |
1395 | 1395 | if (header.data_type == envi_header::float32) |
1396 | - return ((bil<float>*)file)->avg_band(p, mask, PROGRESS); | |
1396 | + return ((bil<float>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1397 | 1397 | else if (header.data_type == envi_header::float64) |
1398 | - return ((bil<double>*)file)->avg_band(p, mask, PROGRESS); | |
1398 | + return ((bil<double>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1399 | 1399 | else{ |
1400 | 1400 | std::cout << "ERROR: unidentified data type" << std::endl; |
1401 | 1401 | exit(1); |
... | ... | @@ -1403,9 +1403,9 @@ public: |
1403 | 1403 | } |
1404 | 1404 | else if (header.interleave == envi_header::BIP){ |
1405 | 1405 | if (header.data_type == envi_header::float32) |
1406 | - return ((bip<float>*)file)->avg_band(p, mask, PROGRESS); | |
1406 | + return ((bip<float>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1407 | 1407 | else if (header.data_type == envi_header::float64) |
1408 | - return ((bip<double>*)file)->avg_band(p, mask, PROGRESS); | |
1408 | + return ((bip<double>*)file)->mean_spectrum(p, std, mask, PROGRESS); | |
1409 | 1409 | else{ |
1410 | 1410 | std::cout << "ERROR: unidentified data type" << std::endl; |
1411 | 1411 | exit(1); |
... | ... | @@ -1414,6 +1414,28 @@ public: |
1414 | 1414 | return false; |
1415 | 1415 | } |
1416 | 1416 | |
1417 | + /// Calculate the mean value for all masked (or valid) pixels in a band and returns the average spectrum | |
1418 | + | |
1419 | + /// @param p is a pointer to pre-allocated memory of size [B * sizeof(T)] that stores the mean spectrum | |
1420 | + /// @param mask is a pointer to memory of size [X * Y] that stores the mask value at each pixel location | |
1421 | + bool median_spectrum(double* m, unsigned char* mask, bool PROGRESS = false){ | |
1422 | + if (header.interleave == envi_header::BSQ){ | |
1423 | + if (header.data_type == envi_header::float32) | |
1424 | + return ((bsq<float>*)file)->median_spectrum(m, mask, PROGRESS); | |
1425 | + else if (header.data_type == envi_header::float64) | |
1426 | + return ((bsq<double>*)file)->median_spectrum(m, mask, PROGRESS); | |
1427 | + else{ | |
1428 | + std::cout << "ERROR: unidentified data type" << std::endl; | |
1429 | + exit(1); | |
1430 | + } | |
1431 | + } | |
1432 | + else{ | |
1433 | + std::cout<<"ERROR: median calculation is only supported for BSQ interleave types. Convert to process."<<std::endl; | |
1434 | + exit(1); | |
1435 | + } | |
1436 | + return false; | |
1437 | + } | |
1438 | + | |
1417 | 1439 | /// Calculate the covariance matrix for all masked pixels in the image. |
1418 | 1440 | |
1419 | 1441 | /// @param co is a pointer to pre-allocated memory of size [B * B] that stores the resulting covariance matrix | ... | ... |
stim/gl/gl_spider.h
... | ... | @@ -473,7 +473,7 @@ class gl_spider // : public virtual gl_texture<T> |
473 | 473 | glEndList(); ///finilize the display list. |
474 | 474 | #ifdef DEBUG |
475 | 475 | for(int i = 0; i < numSamplesPos; i++) |
476 | - std::cout << pV[i] << std::endl; | |
476 | + std::cout << pV[i].str() << std::endl; | |
477 | 477 | #endif |
478 | 478 | } |
479 | 479 | |
... | ... | @@ -1145,8 +1145,8 @@ class gl_spider // : public virtual gl_texture<T> |
1145 | 1145 | out[3] = temp[2]; |
1146 | 1146 | } |
1147 | 1147 | #ifdef DEBUG |
1148 | - std::cout << "out is " << out << std::endl; | |
1149 | - std::cout << "when rotating from " << from << " to " << dir << std::endl; | |
1148 | + std::cout << "out is " << out.str() << std::endl; | |
1149 | + std::cout << "when rotating from " << from.str() << " to " << dir.str() << std::endl; | |
1150 | 1150 | #endif |
1151 | 1151 | return out; |
1152 | 1152 | } |
... | ... | @@ -1531,7 +1531,7 @@ class gl_spider // : public virtual gl_texture<T> |
1531 | 1531 | setMagnitude(curSeedMag); |
1532 | 1532 | |
1533 | 1533 | #ifdef DEBUG |
1534 | - std::cout << "The new seed " << curSeed << curSeedVec << curSeedMag << std::endl; | |
1534 | + std::cout << "The new seed " << curSeed.str() << curSeedVec.str() << curSeedMag << std::endl; | |
1535 | 1535 | #endif |
1536 | 1536 | |
1537 | 1537 | // Bind(direction_texID, direction_buffID, numSamples, n_pixels); | ... | ... |
stim/math/vector.h
... | ... | @@ -74,11 +74,11 @@ struct vec : public std::vector<T> |
74 | 74 | at(i) = other[i]; |
75 | 75 | } |
76 | 76 | } |
77 | - | |
77 | + | |
78 | 78 | // vec( vec3<T>& other){ |
79 | 79 | // resize(3); //resize the current vector to match the copy |
80 | 80 | // for(size_t i=0; i<3; i++){ //copy each element |
81 | -// at(i) = other[i]; | |
81 | +// at(i) = other[i]; | |
82 | 82 | // } |
83 | 83 | // } |
84 | 84 | |
... | ... | @@ -139,16 +139,16 @@ struct vec : public std::vector<T> |
139 | 139 | |
140 | 140 | } |
141 | 141 | |
142 | - | |
143 | - vec<T> cyl2cart() const | |
144 | - { | |
145 | - vec<T> cyl; | |
146 | - cyl.push_back(at(0)*std::sin(at(1))); | |
147 | - cyl.push_back(at(0)*std::cos(at(1))); | |
148 | - cyl.push_back(at(2)); | |
149 | - return(cyl); | |
150 | - | |
151 | - } | |
142 | + | |
143 | + vec<T> cyl2cart() const | |
144 | + { | |
145 | + vec<T> cyl; | |
146 | + cyl.push_back(at(0)*std::sin(at(1))); | |
147 | + cyl.push_back(at(0)*std::cos(at(1))); | |
148 | + cyl.push_back(at(2)); | |
149 | + return(cyl); | |
150 | + | |
151 | + } | |
152 | 152 | /// Convert the vector from cartesian to spherical coordinates (x, y, z -> r, theta, phi where theta = [0, 2*pi]) |
153 | 153 | vec<T> cart2sph() const |
154 | 154 | { |
... | ... | @@ -335,16 +335,16 @@ struct vec : public std::vector<T> |
335 | 335 | return *this; |
336 | 336 | } |
337 | 337 | |
338 | - /// Cast to a vec3 | |
339 | - operator stim::vec3<T>(){ | |
340 | - stim::vec3<T> r; | |
341 | - size_t N = std::min<size_t>(size(), 3); | |
342 | - for(size_t i = 0; i < N; i++) | |
343 | - r[i] = at(i); | |
344 | - return r; | |
345 | - } | |
346 | - | |
347 | - | |
338 | + /// Cast to a vec3 | |
339 | + operator stim::vec3<T>(){ | |
340 | + stim::vec3<T> r; | |
341 | + size_t N = min(size(), (size_t)3); | |
342 | + for(size_t i = 0; i < N; i++) | |
343 | + r[i] = at(i); | |
344 | + return r; | |
345 | + } | |
346 | + | |
347 | + | |
348 | 348 | /// Casting and assignment |
349 | 349 | template<typename Y> |
350 | 350 | vec<T> & operator=(vec<Y> rhs){ |
... | ... | @@ -355,16 +355,16 @@ struct vec : public std::vector<T> |
355 | 355 | at(i) = rhs[i]; |
356 | 356 | return *this; |
357 | 357 | } |
358 | - | |
359 | - /// Assign a vec = vec3 | |
360 | - template<typename Y> | |
361 | - vec<T> & operator=(vec3<Y> rhs) | |
362 | - { | |
363 | - resize(3); | |
364 | - for(size_t i=0; i<3; i++) | |
365 | - at(i) = rhs[i]; | |
366 | - return *this; | |
367 | - } | |
358 | + | |
359 | + /// Assign a vec = vec3 | |
360 | + template<typename Y> | |
361 | + vec<T> & operator=(vec3<Y> rhs) | |
362 | + { | |
363 | + resize(3); | |
364 | + for(size_t i=0; i<3; i++) | |
365 | + at(i) = rhs[i]; | |
366 | + return *this; | |
367 | + } | |
368 | 368 | |
369 | 369 | /// Unary minus (returns the negative of the vector) |
370 | 370 | vec<T> operator-() const{ | ... | ... |