diff --git a/image_analysis/CMakeLists.txt b/image_analysis/CMakeLists.txt index ae5450be..cac33e00 100644 --- a/image_analysis/CMakeLists.txt +++ b/image_analysis/CMakeLists.txt @@ -4,7 +4,9 @@ ADD_LIBRARY(JFJochImageAnalysis STATIC MXAnalysisAfterFPGA.h MXAnalysisAfterFPGA.cpp SpotAnalyze.cpp - SpotAnalyze.h) + SpotAnalyze.h + mask_dark_analysis/MaskDarkAnalysis.cpp + mask_dark_analysis/MaskDarkAnalysis.h) FIND_PACKAGE(Eigen3 3.4 REQUIRED NO_MODULE) # provides Eigen3::Eigen diff --git a/image_analysis/mask_dark_analysis/MaskDarkAnalysis.cpp b/image_analysis/mask_dark_analysis/MaskDarkAnalysis.cpp new file mode 100644 index 00000000..8b09195a --- /dev/null +++ b/image_analysis/mask_dark_analysis/MaskDarkAnalysis.cpp @@ -0,0 +1,55 @@ +// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute +// SPDX-License-Identifier: GPL-3.0-only + +#include "MaskDarkAnalysis.h" +#include "../../common/JFJochException.h" + +MaskDarkAnalysis::MaskDarkAnalysis(size_t det_size) : mask(det_size, 0) {} + +template +void MaskDarkAnalysis::check(const T *ptr) { + std::unique_lock ul(m); + for (int i = 0; i < mask.size(); i++) { + auto v64 = static_cast(ptr[i]); + if (v64 > max_allowed_value) + mask[i]++; + } +} + +void MaskDarkAnalysis::AnalyzeImage(const DataMessage &data, std::vector buffer) { + if (data.image.GetWidth() * data.image.GetHeight() != mask.size()) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid size of input image"); + + auto ptr = data.image.GetUncompressedPtr(buffer); + + switch (data.image.GetMode()) { + case CompressedImageMode::Int8: + check(reinterpret_cast(ptr)); + break; + case CompressedImageMode::Uint8: + check(reinterpret_cast(ptr)); + break; + case CompressedImageMode::Int16: + check(reinterpret_cast(ptr)); + break; + case CompressedImageMode::Uint16: + check(reinterpret_cast(ptr)); + break; + case CompressedImageMode::Int32: + check(reinterpret_cast(ptr)); + break; + case CompressedImageMode::Uint32: + check(reinterpret_cast(ptr)); + break; + default: + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "RGB/float image mode not supported"); + } +} + +void MaskDarkAnalysis::ApplyMask(PixelMask &in_mask) const { + std::unique_lock ul(m); + std::vector tmp(mask.size(), 0); + for (int i = 0; i < mask.size(); i++) + tmp[i] = (mask[i] > max_allowed_freq) ? 1 : 0; + in_mask.LoadDarkBadPixelMask(tmp); +} diff --git a/image_analysis/mask_dark_analysis/MaskDarkAnalysis.h b/image_analysis/mask_dark_analysis/MaskDarkAnalysis.h new file mode 100644 index 00000000..b223015f --- /dev/null +++ b/image_analysis/mask_dark_analysis/MaskDarkAnalysis.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute +// SPDX-License-Identifier: GPL-3.0-only + +#ifndef JFJOCH_MASKDARKANALYSIS_H +#define JFJOCH_MASKDARKANALYSIS_H + +#include +#include +#include +#include "../common/CompressedImage.h" +#include "../common/PixelMask.h" + +class MaskDarkAnalysis { + mutable std::mutex m; + + const int64_t max_allowed_value = 1; + const int64_t max_allowed_freq = 10; + + std::vector mask; + + + template void check(const T *ptr); +public: + explicit MaskDarkAnalysis(size_t det_size); + void AnalyzeImage(const DataMessage &msg, std::vector buffer); + void ApplyMask(PixelMask &mask) const; +}; + + +#endif //JFJOCH_MASKDARKANALYSIS_H \ No newline at end of file