ImageAnalysisCPU: Simplify + avoid allocating new 32-bit image for every iteration

This commit is contained in:
2025-10-04 14:19:06 +02:00
parent 8691d933f5
commit 5fc68b62f4
4 changed files with 32 additions and 35 deletions

View File

@@ -10,31 +10,32 @@
ImageAnalysisCPU::ImageAnalysisCPU(const DiffractionExperiment &in_experiment,
const AzimuthalIntegration &in_integration,
const PixelMask &in_mask)
: experiment(in_experiment),
integration(in_integration),
npixels(experiment.GetPixelsNum()),
xpixels(experiment.GetXPixelsNum()),
mask_1byte(npixels, false),
spotFinder(in_integration),
saturation_limit(experiment.GetSaturationLimit()),
roi_count(0),
mask(in_mask),
indexer(nullptr) {
const PixelMask &in_mask,
IndexerThreadPool *in_indexer)
: experiment(in_experiment),
integration(in_integration),
updated_image(experiment.GetPixelsNum()),
roi_count(0),
npixels(experiment.GetPixelsNum()),
xpixels(experiment.GetXPixelsNum()),
mask_1byte(npixels, false),
spotFinder(in_integration),
indexer(in_indexer),
saturation_limit(experiment.GetSaturationLimit()),
mask(in_mask) {
UpdateROI();
roi_map = experiment.ExportROIMap();
roi_count = experiment.ROI().size();
roi_names = experiment.ROI().GetROINameMap();
for (int i = 0; i < npixels; i++)
mask_1byte[i] = (in_mask.GetMask().at(i) != 0);
}
void ImageAnalysisCPU::UpdateROI() {
roi_map = experiment.ExportROIMap();
roi_count = experiment.ROI().size();
roi_names = experiment.ROI().GetROINameMap();
}
void ImageAnalysisCPU::Analyze(DataMessage &output, std::vector<uint8_t> &image, AzimuthalIntegrationProfile &profile,
const SpotFindingSettings &spot_finding_settings) {
std::unique_lock ul(m);
void ImageAnalysisCPU::Analyze(DataMessage &output, std::vector<uint8_t> &image, AzimuthalIntegrationProfile &profile, const SpotFindingSettings &spot_finding_settings) {
if ((output.image.GetWidth() != xpixels)
|| (output.image.GetWidth() * output.image.GetHeight() != npixels))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
@@ -66,15 +67,14 @@ void ImageAnalysisCPU::Analyze(DataMessage &output, std::vector<uint8_t> &image,
}
}
template <class T>
template<class T>
void ImageAnalysisCPU::Analyze(DataMessage &output,
const uint8_t *in_image,
T err_pixel_val,
T sat_pixel_val,
AzimuthalIntegrationProfile &profile,
const SpotFindingSettings &spot_finding_settings) {
auto image = (T *) in_image;
auto image = reinterpret_cast<const T *>(in_image);
std::vector<ROIMessage> roi(roi_count);
@@ -89,7 +89,6 @@ void ImageAnalysisCPU::Analyze(DataMessage &output,
auto &pixel_to_bin = integration.GetPixelToBin();
auto &corrections = integration.Corrections();
std::vector<int32_t> updated_image(experiment.GetPixelsNum());
profile.Clear(integration);
@@ -117,7 +116,7 @@ void ImageAnalysisCPU::Analyze(DataMessage &output,
int64_t y = i / xpixels;
for (int8_t r = 0; r < roi_count; r++) {
if ((roi_map[i] & (1<<r)) != 0) {
if ((roi_map[i] & (1 << r)) != 0) {
roi[r].sum += image[i];
roi[r].sum_square += image[i] * image[i];
roi[r].pixels += 1;
@@ -150,8 +149,3 @@ void ImageAnalysisCPU::Analyze(DataMessage &output,
for (const auto &[key, val]: roi_names)
output.roi[key] = roi[val];
}
ImageAnalysisCPU &ImageAnalysisCPU::SetIndexer(IndexerThreadPool *new_indexer) {
indexer = new_indexer;
return *this;
}

View File

@@ -4,6 +4,8 @@
#ifndef JFJOCH_IMAGEANALYSISCPU_H
#define JFJOCH_IMAGEANALYSISCPU_H
#include <mutex>
#include "../common/JFJochMessages.h"
#include "../common/DiffractionExperiment.h"
#include "../common/AzimuthalIntegration.h"
@@ -13,9 +15,11 @@
#include "indexing/IndexerThreadPool.h"
class ImageAnalysisCPU {
std::mutex m;
const DiffractionExperiment &experiment;
const AzimuthalIntegration &integration;
std::vector<int32_t> updated_image;
std::vector<uint16_t> roi_map;
std::map<std::string, uint16_t> roi_names;
size_t roi_count;
@@ -34,9 +38,9 @@ class ImageAnalysisCPU {
template <class T>
void Analyze(DataMessage &output, const uint8_t *image, T err_pixel_val, T sat_pixel_val, AzimuthalIntegrationProfile &profile, const SpotFindingSettings &spot_finding_settings);
public:
ImageAnalysisCPU(const DiffractionExperiment& experiment, const AzimuthalIntegration& integration, const PixelMask& mask);
void UpdateROI();
ImageAnalysisCPU& SetIndexer(IndexerThreadPool *input);
ImageAnalysisCPU(const DiffractionExperiment &experiment, const AzimuthalIntegration &integration,
const PixelMask &mask,
IndexerThreadPool *indexer = nullptr);
void Analyze(DataMessage &output, std::vector<uint8_t> &buffer, AzimuthalIntegrationProfile &profile, const SpotFindingSettings &spot_finding_settings);
};

View File

@@ -188,8 +188,7 @@ void JFJochReceiverLite::DataAnalysisThread(uint32_t id) {
measurement_started.wait();
try {
analysis = std::make_unique<ImageAnalysisCPU>(experiment, az_int_mapping, pixel_mask);
analysis->SetIndexer(indexer_thread_pool);
analysis = std::make_unique<ImageAnalysisCPU>(experiment, az_int_mapping, pixel_mask, indexer_thread_pool);
} catch (const JFJochException &e) {
Cancel(e);
return;

View File

@@ -97,8 +97,8 @@ void JFJochImageReadingWorker::CalcROI_i() {
void JFJochImageReadingWorker::UpdateAzint_i(const JFJochReaderDataset *dataset) {
if (dataset) {
azint_mapping = std::make_unique<AzimuthalIntegration>(curr_experiment, dataset->pixel_mask);
image_analysis = std::make_unique<ImageAnalysisCPU>(curr_experiment, *azint_mapping, dataset->pixel_mask);
image_analysis->SetIndexer(indexing.get());
image_analysis = std::make_unique<ImageAnalysisCPU>(curr_experiment, *azint_mapping, dataset->pixel_mask,
indexing.get());
}
}