Commit bb61cb180faaa27979de16da534fab2ce295b57f

Authored by David Mayerich
1 parent 2781a48c

added subimage function to BSQ

Showing 2 changed files with 82 additions and 0 deletions   Show diff stats
stim/envi/bsq.h
... ... @@ -1237,6 +1237,53 @@ public:
1237 1237 return true;
1238 1238 }
1239 1239  
  1240 + ///Crop out several subimages and assemble a new image from these concatenated subimages
  1241 +
  1242 + /// @param outfile is the file name for the output image
  1243 + /// @param sx is the width of each subimage
  1244 + /// @param sy is the height of each subimage
  1245 + /// @mask is the mask used to define subimage positions extracted from the input file
  1246 + void subimages(std::string outfile, size_t sx, size_t sy, unsigned char* mask, bool PROGRESS = false){
  1247 +
  1248 + size_t N = nnz(mask); //get the number of subimages
  1249 + T* dst = (T*) malloc(N * sx * sy * sizeof(T)); //allocate space for a single band of the output image
  1250 + memset(dst, 0, N*sx*sy*sizeof(T)); //initialize the band image to zero
  1251 +
  1252 + std::ofstream out(outfile, std::ios::binary); //open a file for writing
  1253 +
  1254 + T* src = (T*) malloc(X() * Y() * sizeof(T));
  1255 +
  1256 + for(size_t b = 0; b < Z(); b++){ //for each band
  1257 + band_index(src, b); //load the band image
  1258 + size_t i = 0; //create an image index and initialize it to zero
  1259 + size_t n = 0;
  1260 + while(n < N){ //for each subimage
  1261 + if(mask[i]){ //if the pixel is masked, copy the surrounding pixels into the destination band
  1262 + size_t yi = i / X(); //determine the y position of the current pixel
  1263 + size_t xi = i - yi * X(); //determine the x position of the current pixel
  1264 + if( xi > sx/2 && xi < X() - sx/2 && //if the subimage is completely within the bounds of the original image
  1265 + yi > sy/2 && yi < Y() - sy/2){
  1266 + size_t cx = xi - sx/2; //calculate the corner position for the subimage
  1267 + size_t cy = yi - sy/2;
  1268 + size_t cxi, cyi;
  1269 + for(size_t syi = 0; syi < sy; syi++){ //for each line in the subimage
  1270 + size_t src_i = (cy + syi) * X() + cx;
  1271 + //size_t dst_i = syi * (N * sx) + n * sx;
  1272 + size_t dst_i = (n * sy + syi) * sx;
  1273 + memcpy(&dst[dst_i], &src[src_i], sx * sizeof(T)); //copy one line from the subimage to the destination image
  1274 + }
  1275 + n++;
  1276 + }
  1277 + }
  1278 + i++;
  1279 + if(PROGRESS) progress = (double)( (n+1) * (b+1) ) / (N * Z()) * 100;
  1280 + }//end while n
  1281 + out.write((const char*)dst, N * sx * sy * sizeof(T)); //write the band to memory
  1282 + }
  1283 + free(dst); //free memory
  1284 + free(src);
  1285 + }
  1286 +
1240 1287 /// Remove a list of bands from the ENVI file
1241 1288  
1242 1289 /// @param outfile is the file name for the output hyperspectral image (with trimmed bands)
... ...
stim/envi/envi.h
... ... @@ -1558,6 +1558,41 @@ public:
1558 1558 return false;
1559 1559 }
1560 1560  
  1561 + void subimages(std::string outfile, size_t nx, size_t ny, unsigned char* mask, bool PROGRESS = false){
  1562 +
  1563 + size_t nnz = 0; //initialize the number of subimages to zero
  1564 + for(size_t i = 0; i < header.lines * header.samples; i++) //for each pixel in the mask
  1565 + if(mask[i]) nnz++; //if the pixel is valid, add a subimage
  1566 +
  1567 +
  1568 + //save the header for the cropped file
  1569 + stim::envi_header new_header = header;
  1570 + new_header.samples = nx; //calculate the width of the output image (concatenated subimages)
  1571 + new_header.lines = nnz * ny; //calculate the height of the output image (height of subimages)
  1572 +
  1573 +
  1574 + if (header.interleave == envi_header::BSQ){
  1575 + if (header.data_type == envi_header::float32)
  1576 + ((bsq<float>*)file)->subimages(outfile, nx, ny, mask, PROGRESS);
  1577 + else if (header.data_type == envi_header::float64)
  1578 + ((bsq<double>*)file)->subimages(outfile, nx, ny, mask, PROGRESS);
  1579 + else{
  1580 + std::cout << "ERROR: unidentified data type" << std::endl;
  1581 + exit(1);
  1582 + }
  1583 + }
  1584 + else if (header.interleave == envi_header::BIL){
  1585 + std::cout << "ERROR: unidentified data type" << std::endl;
  1586 + exit(1);
  1587 + }
  1588 + else if (header.interleave == envi_header::BIP){
  1589 + std::cout << "ERROR: unidentified data type" << std::endl;
  1590 + exit(1);
  1591 + }
  1592 +
  1593 + new_header.save(outfile + ".hdr"); //save the header for the output file
  1594 + }
  1595 +
1561 1596 /// Remove a list of bands from the ENVI file
1562 1597  
1563 1598 /// @param outfile is the file name for the output hyperspectral image (with trimmed bands)
... ...