88#include " iAToolsVTK.h"
99#include " iATypedCallHelper.h"
1010
11- #include < vtkImageAccumulate.h>
11+ // #define MODE_OWN 0 // use self-written code
12+ // #define MODE_VTK_ACC 1 // use vtkImageAccumulate
13+ // #define MODE_VTK_HIS 2 // use vtkImageHistogram
14+
15+ // #define HISTO_MODE MODE_VTK_HIS
16+
17+ // #if HISTO_MODE == MODE_VTK_ACC
18+ // #include <vtkImageAccumulate.h>
19+ // #elif HISTO_MODE == MODE_VTK_HIS
20+ #include < vtkIdTypeArray.h>
21+ #include < vtkImageHistogramStatistics.h>
22+ // #endif
1223#include < vtkImageCast.h>
1324#include < vtkImageData.h>
1425
@@ -243,10 +254,6 @@ void computeHistogram(std::shared_ptr<iAHistogramData> histData, vtkImageData* i
243254 }
244255}
245256
246-
247- #define MODE_VTK 0 // use self-written code above
248- // #define MODE_VTK 1 // use vtkImageAccumulate
249-
250257std::shared_ptr<iAHistogramData> iAHistogramData::create (QString const & name,
251258 vtkImageData* img, size_t desiredNumBin, iAImageStatistics* imgStatistics, int component)
252259{
@@ -264,40 +271,62 @@ std::shared_ptr<iAHistogramData> iAHistogramData::create(QString const& name,
264271
265272 // QElapsedTimer timer;
266273 // timer.start();
267- #if MODE_VTK
268- if (img->GetNumberOfScalarComponents () != 1 )
269- {
270- LOG (lvlDebug,
271- QString (" Image has %2 components, only computing histogram of first one!" )
272- .arg (img->GetNumberOfScalarComponents ()));
273- }
274- auto accumulate = vtkSmartPointer<vtkImageAccumulate>::New ();
275- accumulate->ReleaseDataFlagOn ();
276- accumulate->SetInputData (img);
277- accumulate->SetComponentOrigin (img->GetScalarRange ()[0 ], 0.0 , 0.0 );
278- // The check in finalNumBin guarantees that numBin is smaller than int max, so the cast to int below is safe!
279- accumulate->SetComponentExtent (0 , static_cast <int >(numBin - 1 ), 0 , 0 , 0 , 0 );
280- accumulate->SetComponentSpacing (histRange / numBin, 0.0 , 0.0 );
281- accumulate->Update ();
274+ // #if HISTO_MODE == MODE_VTK_ACC
275+ // if (img->GetNumberOfScalarComponents() != 1)
276+ // {
277+ // LOG(lvlDebug,
278+ // QString("Image has %2 components, only computing histogram of first one!")
279+ // .arg(img->GetNumberOfScalarComponents()));
280+ // }
281+ // vtkNew<vtkImageAccumulate> accumulate;
282+ // accumulate->ReleaseDataFlagOn();
283+ // accumulate->SetInputData(img);
284+ // accumulate->SetComponentOrigin(img->GetScalarRange()[0], 0.0, 0.0);
285+ // // The check in finalNumBin guarantees that numBins is smaller than int max, so the cast to int below is safe!
286+ // accumulate->SetComponentExtent(0, static_cast<int>(numBins - 1), 0, 0, 0, 0);
287+ // accumulate->SetComponentSpacing(histRange / numBins, 0.0, 0.0);
288+ // accumulate->Update();
289+ // int extent[6];
290+ // accumulate->GetComponentExtent(extent);
291+ // vtkNew<vtkImageCast> caster;
292+ // caster->SetInputData(accumulate->GetOutput());
293+ // caster->SetOutputScalarType(iAVtkDataType<DataType>::value);
294+ // caster->Update();
295+ // auto rawImg = caster->GetOutput();
296+ //
297+ // auto vtkRawData = static_cast<DataType*>(rawImg->GetScalarPointer());
298+ // std::copy(vtkRawData, vtkRawData + result->m_numBin, result->m_histoData);
299+ // if (imgStatistics)
300+ // {
301+ // *imgStatistics = iAImageStatistics{ *accumulate->GetMin(), *accumulate->GetMax(), *accumulate->GetMean(), *accumulate->GetStandardDeviation() };
302+ // }
303+ // LOG(lvlDebug, QString("VTK (vtkImageAccumulate): %1 seconds").arg(timer.elapsed() / 1000.0, 5, 'f', 3));
304+ // #elif HISTO_MODE == MODE_VTK_HIS
305+ vtkNew<vtkImageHistogramStatistics> histo;
306+ histo->SetInputData (img);
307+ histo->GenerateHistogramImageOff ();
308+ histo->AutomaticBinningOff ();
309+ histo->SetNumberOfBins (numBins);
310+ histo->SetBinOrigin (scalarRange[0 ]);
311+ histo->SetBinSpacing (histRange / numBins);
312+ histo->SetActiveComponent (component);
313+ histo->Update ();
282314 int extent[6 ];
283- accumulate->GetComponentExtent (extent);
284- auto caster = vtkSmartPointer<vtkImageCast>::New ();
285- caster->SetInputData (accumulate->GetOutput ());
286- caster->SetOutputScalarType (iAVtkDataType<DataType>::value);
287- caster->Update ();
288- auto rawImg = caster->GetOutput ();
289-
290- auto vtkRawData = static_cast <DataType*>(rawImg->GetScalarPointer ());
291- std::copy (vtkRawData, vtkRawData + result->m_numBin , result->m_histoData );
315+ histo->GetOutput ()->GetExtent (extent);
316+ auto vtkRawData = histo->GetHistogram ();
317+ // #pragma omp parallel for // no difference in runtimes
318+ for (size_t b=0 ; b<result->m_numBin ; ++b) {
319+ result->m_histoData [b] = vtkRawData->GetTuple1 (b);
320+ }
292321 if (imgStatistics)
293322 {
294- *imgStatistics = iAImageStatistics{ *accumulate-> GetMin (), *accumulate-> GetMax (), *accumulate ->GetMean (), *accumulate ->GetStandardDeviation () };
323+ *imgStatistics = iAImageStatistics{scalarRange[ 0 ], scalarRange[ 1 ], histo ->GetMean (), histo ->GetStandardDeviation () };
295324 }
296- // LOG(lvlDebug, QString("VTK: %1 seconds").arg(timer.elapsed() / 1000.0, 5, 'f', 3));
297- #else
298- VTK_TYPED_CALL (computeHistogram, img->GetScalarType (), result, img, imgStatistics, component);
299- // LOG(lvlDebug, QString("OpenMP: %1 seconds").arg(timer.elapsed() / 1000.0, 5, 'f', 3));
300- #endif
325+ // LOG(lvlDebug, QString("VTK (vtkImageHistogram) : %1 seconds").arg(timer.elapsed() / 1000.0, 5, 'f', 3));
326+ // #else // MODE_OWN
327+ // VTK_TYPED_CALL(computeHistogram, img->GetScalarType(), result, img, imgStatistics, component);
328+ // LOG(lvlDebug, QString("OpenMP: %1 seconds").arg(timer.elapsed() / 1000.0, 5, 'f', 3));
329+ // #endif
301330 result->m_spacing = histRange / result->m_numBin ;
302331 result->updateYBounds ();
303332
0 commit comments