Mercurial > hg > orthanc-stone
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) |