comparison OrthancStone/Sources/Loaders/OrthancMultiframeVolumeLoader.cpp @ 1757:28979b77ce90

Suppressed one pass on the dose distribution computation
author bgo@SHARKNADO.localdomain
date Mon, 26 Apr 2021 17:37:54 +0200
parents 946eb7200b82
children 4ee11b8773e2
comparison
equal deleted inserted replaced
1755:1a775f4ee672 1757:28979b77ce90
267 CopyPixel(*targetUp, source); 267 CopyPixel(*targetUp, source);
268 } 268 }
269 269
270 template <typename T> 270 template <typename T>
271 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution( 271 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeDistribution(
272 const std::string& pixelData, std::map<T,uint64_t>& distribution) 272 const std::string& pixelData, std::map<T, PixelCount>& distribution)
273 { 273 {
274 #if STONE_TIME_BLOCKING_OPS 274 #if STONE_TIME_BLOCKING_OPS
275 boost::posix_time::ptime timerStart = boost::posix_time::microsec_clock::universal_time(); 275 boost::posix_time::ptime timerStart = boost::posix_time::microsec_clock::universal_time();
276 #endif 276 #endif
277 277
292 { 292 {
293 return; 293 return;
294 } 294 }
295 295
296 // first pass to initialize map 296 // first pass to initialize map
297 #if 0
297 { 298 {
298 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str()); 299 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str());
299 300
300 for (unsigned int z = 0; z < depth; z++) 301 for (unsigned int z = 0; z < depth; z++)
301 { 302 {
309 source += bpp; 310 source += bpp;
310 } 311 }
311 } 312 }
312 } 313 }
313 } 314 }
315 #endif
314 316
315 { 317 {
316 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str()); 318 const uint8_t* source = reinterpret_cast<const uint8_t*>(pixelData.c_str());
317 319
318 for (unsigned int z = 0; z < depth; z++) 320 for (unsigned int z = 0; z < depth; z++)
349 T* targetAddrPix = targetAddrLine; 351 T* targetAddrPix = targetAddrLine;
350 for (unsigned int x = 0; x < width; x++) 352 for (unsigned int x = 0; x < width; x++)
351 { 353 {
352 CopyPixel(*targetAddrPix, source); 354 CopyPixel(*targetAddrPix, source);
353 355
354 distribution[*targetAddrPix] += 1; 356 distribution[*targetAddrPix].count_ += 1;
355 357
356 targetAddrPix++; 358 targetAddrPix++;
357 source += bpp; 359 source += bpp;
358 } 360 }
359 uint8_t* targetAddrLineBytes = reinterpret_cast<uint8_t*>(targetAddrLine) + pitch; 361 uint8_t* targetAddrLineBytes = reinterpret_cast<uint8_t*>(targetAddrLine) + pitch;
370 #endif 372 #endif
371 } 373 }
372 374
373 template <typename T> 375 template <typename T>
374 void OrthancMultiframeVolumeLoader::ComputeMinMaxWithOutlierRejection( 376 void OrthancMultiframeVolumeLoader::ComputeMinMaxWithOutlierRejection(
375 const std::map<T, uint64_t>& distribution) 377 const std::map<T, PixelCount>& distribution)
376 { 378 {
377 if (distribution.size() == 0) 379 if (distribution.size() == 0)
378 { 380 {
379 LOG(ERROR) << "ComputeMinMaxWithOutlierRejection -- Volume image empty."; 381 LOG(ERROR) << "ComputeMinMaxWithOutlierRejection -- Volume image empty.";
380 } 382 }
389 391
390 // now that we have distribution[pixelValue] == numberOfPixelsWithValue 392 // now that we have distribution[pixelValue] == numberOfPixelsWithValue
391 // compute number of values and check (assertion) that it is equal to 393 // compute number of values and check (assertion) that it is equal to
392 // width * height * depth 394 // width * height * depth
393 { 395 {
394 typename std::map<T, uint64_t>::const_iterator it = distribution.begin(); 396 typename std::map<T, PixelCount>::const_iterator it = distribution.begin();
395 uint64_t totalCount = 0; 397 uint64_t totalCount = 0;
396 distributionRawMin_ = static_cast<float>(it->first); 398 distributionRawMin_ = static_cast<float>(it->first);
397 399
398 while (it != distribution.end()) 400 while (it != distribution.end())
399 { 401 {
400 T pixelValue = it->first; 402 T pixelValue = it->first;
401 uint64_t count = it->second; 403 totalCount += it->second.count_;
402 totalCount += count;
403 ++it; 404 ++it;
404 if (it == distribution.end()) 405 if (it == distribution.end())
405 distributionRawMax_ = static_cast<float>(pixelValue); 406 distributionRawMax_ = static_cast<float>(pixelValue);
406 } 407 }
407 LOG(INFO) << "Volume image. First distribution value = " 408 LOG(INFO) << "Volume image. First distribution value = "
434 T resultMin = 0; 435 T resultMin = 0;
435 436
436 // then start from start and remove pixel values up to 437 // then start from start and remove pixel values up to
437 // endRejectionCount voxels rejected 438 // endRejectionCount voxels rejected
438 { 439 {
439 typename std::map<T, uint64_t>::const_iterator it = distribution.begin(); 440 typename std::map<T, PixelCount>::const_iterator it = distribution.begin();
440 441
441 uint64_t currentCount = 0; 442 uint64_t currentCount = 0;
442 443
443 while (it != distribution.end()) 444 while (it != distribution.end())
444 { 445 {
445 T pixelValue = it->first; 446 T pixelValue = it->first;
446 uint64_t count = it->second; 447 uint64_t count = it->second.count_;
447 448
448 // if this pixelValue crosses the rejection threshold, let's set it 449 // if this pixelValue crosses the rejection threshold, let's set it
449 // and exit the loop 450 // and exit the loop
450 if ((currentCount <= endRejectionCount) && 451 if ((currentCount <= endRejectionCount) &&
451 (currentCount + count > endRejectionCount)) 452 (currentCount + count > endRejectionCount))
466 // rejection 467 // rejection
467 T resultMax = 0; 468 T resultMax = 0;
468 // now start from END and remove pixel values up to 469 // now start from END and remove pixel values up to
469 // endRejectionCount voxels rejected 470 // endRejectionCount voxels rejected
470 { 471 {
471 typename std::map<T, uint64_t>::const_reverse_iterator it = distribution.rbegin(); 472 typename std::map<T, PixelCount>::const_reverse_iterator it = distribution.rbegin();
472 473
473 uint64_t currentCount = 0; 474 uint64_t currentCount = 0;
474 475
475 while (it != distribution.rend()) 476 while (it != distribution.rend())
476 { 477 {
477 T pixelValue = it->first; 478 T pixelValue = it->first;
478 uint64_t count = it->second; 479 uint64_t count = it->second.count_;
479 480
480 if ((currentCount <= endRejectionCount) && 481 if ((currentCount <= endRejectionCount) &&
481 (currentCount + count > endRejectionCount)) 482 (currentCount + count > endRejectionCount))
482 { 483 {
483 resultMax = pixelValue; 484 resultMax = pixelValue;
504 505
505 template <typename T> 506 template <typename T>
506 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeMinMax( 507 void OrthancMultiframeVolumeLoader::CopyPixelDataAndComputeMinMax(
507 const std::string& pixelData) 508 const std::string& pixelData)
508 { 509 {
509 std::map<T, uint64_t> distribution; 510 std::map<T, PixelCount> distribution;
510 CopyPixelDataAndComputeDistribution(pixelData, distribution); 511 CopyPixelDataAndComputeDistribution(pixelData, distribution);
511 ComputeMinMaxWithOutlierRejection(distribution); 512 ComputeMinMaxWithOutlierRejection(distribution);
512 } 513 }
513 514
514 void OrthancMultiframeVolumeLoader::SetUncompressedPixelData(const std::string& pixelData) 515 void OrthancMultiframeVolumeLoader::SetUncompressedPixelData(const std::string& pixelData)