IDS peak ICV v1.2.0
Loading...
Searching...
No Matches
peak_icv_default_pipeline.hpp
Go to the documentation of this file.
1
11#pragma once
12
42
43#include <unordered_map>
44#include <chrono>
45#include <ctime>
46#include <iomanip>
47
163namespace peak
164{
165namespace pipeline
166{
167
264class DefaultPipeline final : public PipelineBase
265{
266public:
275
281 ~DefaultPipeline() override;
282
293 PEAK_COMMON_NO_DISCARD std::string ExportSettingsToString() const override;
294
304 void ImportSettingsFromString(const std::string& settings) override;
305
311 void ResetToDefault() override;
312
318 PEAK_COMMON_NO_DISCARD const char* GetType() const override;
319
336 PEAK_COMMON_NO_DISCARD peak::icv::Image Process(const peak::icv::Image& image) const;
337
356 PEAK_COMMON_NO_DISCARD peak::icv::Image Process(const peak::common::IImageView& imageView) const;
357
369 PEAK_COMMON_NO_DISCARD peak::icv::Image operator<<(const peak::icv::Image& image) const;
370
382 PEAK_COMMON_NO_DISCARD peak::icv::Image operator<<(const peak::common::IImageView& imageView) const;
383
397 void ReleaseBuffers() const;
398
409 PEAK_COMMON_NO_DISCARD features::MirrorFeature& Mirror() const;
410
421 PEAK_COMMON_NO_DISCARD features::RotationFeature& Rotation() const;
422
433 PEAK_COMMON_NO_DISCARD features::GainFeature& Gain() const;
434
445 PEAK_COMMON_NO_DISCARD features::ColorCorrectionFeature& ColorCorrection() const;
446
457 PEAK_COMMON_NO_DISCARD features::SaturationFeature& Saturation() const;
458
469 PEAK_COMMON_NO_DISCARD features::GammaFeature& Gamma() const;
470
481 PEAK_COMMON_NO_DISCARD features::DigitalBlackFeature& DigitalBlack() const;
482
493 PEAK_COMMON_NO_DISCARD features::SharpeningFeature& Sharpening() const;
494
505 PEAK_COMMON_NO_DISCARD features::HotpixelCorrectionFeature& HotpixelCorrection() const;
506
517 PEAK_COMMON_NO_DISCARD features::BinningFeature& Binning() const;
518
529 PEAK_COMMON_NO_DISCARD features::DecimationFeature& Decimation() const;
530
550
556 PEAK_COMMON_NO_DISCARD peak::common::PixelFormat GetOutputPixelFormat() const;
557
573
579 PEAK_COMMON_NO_DISCARD ProcessingPolicy GetProcessingPolicy() const
580 {
581 return m_processingPolicy;
582 }
583
600 void SetAutoFeatureModule(const std::shared_ptr<modules::IAutoFeature>& autoFeatureModule);
601
602private:
603 static std::string GetCurrentIsoUtcTime();
604
605 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<modules::IModule>> GetModules() const override;
606 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<features::IFeature>> GetFeatures() const;
607
608 PEAK_COMMON_NO_DISCARD inline peak::common::Any Process(const peak::common::Any& input) const override;
609
610 peak::common::Any operator<<(const peak::common::Any& input) override
611 {
612 return Process(input);
613 }
614
615 ProcessingPolicy m_processingPolicy{ ProcessingPolicy::Fast };
616
617 std::shared_ptr<detail::UnpackModule> m_unpack{ std::make_shared<detail::UnpackModule>() };
618 std::shared_ptr<detail::HotpixelCorrectionModule> m_hotpixel{ std::make_shared<detail::HotpixelCorrectionModule>() };
619 std::shared_ptr<detail::DownsamplingModule> m_binning{ std::make_shared<detail::DownsamplingModule>(
621 std::shared_ptr<detail::DownsamplingModule> m_decimation{ std::make_shared<detail::DownsamplingModule>(
623 std::shared_ptr<detail::TransformationModule> m_transformation{ std::make_shared<detail::TransformationModule>() };
624 std::shared_ptr<detail::GainModule> m_gain{ std::make_shared<detail::GainModule>() };
625 std::shared_ptr<detail::DebayerModule> m_debayer{ std::make_shared<detail::DebayerModule>() };
626 std::shared_ptr<detail::ColorMatrixTransformationModule> m_colorCorrection{
627 std::make_shared<detail::ColorMatrixTransformationModule>()
628 };
629 std::shared_ptr<detail::MonoConversionModule> m_monoConversion{ std::make_shared<detail::MonoConversionModule>() };
630 std::shared_ptr<detail::SharpeningModule> m_sharpening{ std::make_shared<detail::SharpeningModule>() };
631 std::shared_ptr<detail::ToneCurveCorrectionModule> m_toneCurveCorrection{ std::make_shared<detail::ToneCurveCorrectionModule>() };
632 std::shared_ptr<detail::PixelFormatConversionModule> m_finalConversion{ std::make_shared<detail::PixelFormatConversionModule>() };
633
634 std::shared_ptr<features::HotpixelCorrectionFeature> m_hotpixelFeature{ new features::HotpixelCorrectionFeature{ *m_hotpixel } };
635 std::shared_ptr<features::BinningFeature> m_binningFeature{ new features::BinningFeature{ *m_binning } };
636 std::shared_ptr<features::DecimationFeature> m_decimationFeature{ new features::DecimationFeature{ *m_decimation } };
637 std::shared_ptr<features::MirrorFeature> m_mirrorFeature{ new features::MirrorFeature{ *m_transformation } };
638 std::shared_ptr<features::RotationFeature> m_rotationFeature{ new features::RotationFeature{ *m_transformation } };
639 std::shared_ptr<features::GainFeature> m_gainFeature{ new features::GainFeature{ *m_gain } };
640 std::shared_ptr<features::ColorCorrectionFeature> m_colorCorrectionFeature{ new features::ColorCorrectionFeature{
641 *m_colorCorrection } };
642 std::shared_ptr<features::SaturationFeature> m_saturationFeature{ new features::SaturationFeature{ *m_colorCorrection } };
643 std::shared_ptr<features::SharpeningFeature> m_sharpeningFeature{ new features::SharpeningFeature{ *m_sharpening } };
644 std::shared_ptr<features::GammaFeature> m_gammaFeature{ new features::GammaFeature{ *m_toneCurveCorrection } };
645 std::shared_ptr<features::DigitalBlackFeature> m_digitalBlackFeature{ new features::DigitalBlackFeature{ *m_toneCurveCorrection } };
646
647 std::shared_ptr<modules::IAutoFeature> m_autoFeatureModule;
648
649 constexpr static int pipelineVersion{ 1 };
650};
651
653{
654 m_monoConversion->SetEnabled(false);
655
656 const auto format = m_finalConversion->GetOutputPixelFormat();
657
658 const auto bitDepth = peak::common::PixelFormatInfo(format).GetStorageBitsPerChannel();
659 m_unpack->SetProcessingPolicy(m_processingPolicy);
660 m_unpack->SetTargetBitDepth(bitDepth);
661 m_debayer->SetProcessingPolicy(m_processingPolicy);
662 m_debayer->SetTargetBitDepth(bitDepth);
663}
664
666{
667 if (m_autoFeatureModule)
668 {
669 m_autoFeatureModule->SetGainModule(nullptr);
670 }
671}
672
674{
675 const auto archive = std::make_shared<peak::icv::Archive>();
676
677 const auto moduleList = GetModules();
678 std::vector<std::shared_ptr<peak::common::serialization::IArchive>> modules;
679 modules.reserve(moduleList.size());
680
681 for (const auto& module : moduleList)
682 {
683 if (module == nullptr)
684 {
685 continue;
686 }
687 auto moduleArchive = archive->CreateArchive();
688 moduleArchive->SetString("Type", module->GetType());
689
690 auto moduleDataArchive = moduleArchive->CreateArchive();
691 module->Serialize(*moduleDataArchive);
692 moduleArchive->SetArchive("Data", moduleDataArchive);
693 modules.push_back(moduleArchive);
694 }
695 archive->SetArchiveArray("Modules", modules);
696 archive->SetInt("Version", pipelineVersion);
697 archive->SetString("Type", GetType());
698 archive->SetString("Creation", GetCurrentIsoUtcTime());
699
700 peak::icv::Serializer serializer;
701
702 std::stringstream ss;
703 serializer.Write(*archive, ss);
704 return ss.str();
705}
706
707inline void DefaultPipeline::ImportSettingsFromString(const std::string& settings)
708{
709 peak::icv::Deserializer deserializer;
710
711 std::stringstream ss;
712 ss << settings;
713 const auto archive = deserializer.Read(ss);
714
715 const auto version = archive->GetInt("Version");
716
717 if (version < 1)
718 {
720 "The 'Version' entry " + std::to_string(version) + " in the settings string is invalid! Must be at least 1.");
721 }
722
723 const auto pipelineType = archive->GetString("Type");
724 if (pipelineType != GetType())
725 {
727 "The settings for " + pipelineType + " are not compatible with this pipeline (" + GetType() + ").");
728 }
729
730 std::vector<std::shared_ptr<modules::IModule>> modules;
731 if (m_autoFeatureModule == nullptr)
732 {
733 modules = { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_monoConversion,
734 m_sharpening, m_toneCurveCorrection, m_finalConversion };
735 }
736 else
737 {
738 modules = { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection,
739 m_autoFeatureModule, m_monoConversion, m_sharpening, m_toneCurveCorrection, m_finalConversion };
740 }
741
742 std::unordered_map<std::string, std::shared_ptr<peak::common::serialization::IArchive>> archiveMap;
743 auto moduleArchives = archive->GetArchiveArray("Modules");
744
745 for (const auto& moduleArchive : moduleArchives)
746 {
747 const auto moduleType = moduleArchive->GetString("Type");
748 const auto data = moduleArchive->GetArchive("Data");
749 archiveMap.emplace(moduleType, data);
750 }
751
752 for (const auto& module : modules)
753 {
754 const auto found = archiveMap.find(module->GetType());
755 if (found == archiveMap.end())
756 {
757 throw peak::icv::IOException(std::string("The settings for module ") + module->GetType() + " are missing!");
758 }
759
760 module->Deserialize(*found->second);
761 }
762}
763
765{
766 for (const auto& module : GetModules())
767 {
768 module->ResetToDefault();
769 module->SetEnabled(true);
770 }
771 for (const auto& feature : GetFeatures())
772 {
773 feature->ResetToDefault();
774 feature->SetEnabled(true);
775 }
776 m_monoConversion->SetEnabled(false);
777}
778
779inline const char* DefaultPipeline::GetType() const
780{
781 return "DefaultPipeline";
782}
783
785{
786 m_unpack->ReleaseBuffers();
787 m_debayer->ReleaseBuffers();
788 m_monoConversion->ReleaseBuffers();
789 m_finalConversion->ReleaseBuffers();
790}
791
793{
794 return *m_mirrorFeature;
795}
796
798{
799 return *m_rotationFeature;
800}
801
803{
804 return *m_gainFeature;
805}
806
808{
809 return *m_colorCorrectionFeature;
810}
811
813{
814 return *m_saturationFeature;
815}
816
818{
819 return *m_gammaFeature;
820}
821
823{
824 return *m_digitalBlackFeature;
825}
826
828{
829 return *m_sharpeningFeature;
830}
831
833{
834 return *m_hotpixelFeature;
835}
836
838{
839 return *m_binningFeature;
840}
841
843{
844 return *m_decimationFeature;
845}
846
848{
849 auto data = input;
850
851 for (const auto& mod : GetModules())
852 {
853 if (!mod)
854 {
855 continue;
856 }
857
858 try
859 {
860 data = mod->Process(data);
861 }
862 catch (const peak::icv::Exception& e)
863 {
864 const auto errorCode = e.GetStatus();
865 const auto* const what = e.what();
866 const auto* const moduleType = mod->GetType();
867
868 const auto errorText = std::string{ "[" } + moduleType + "] " + what;
869 switch (errorCode)
870 {
871 case PEAK_ICV_STATUS_LIBRARY_NOT_INITIALIZED:
872 case PEAK_ICV_STATUS_DYNAMIC_DEPENDENCY_MISSING:
873 throw peak::icv::InvalidConfigurationException(errorText, errorCode);
874 case PEAK_ICV_STATUS_INVALID_HANDLE:
875 case PEAK_ICV_STATUS_INVALID_BUFFER_SIZE:
876 case PEAK_ICV_STATUS_MISMATCH:
877 case PEAK_ICV_STATUS_NULL_POINTER:
878 case PEAK_ICV_STATUS_NOT_SUPPORTED:
879 case PEAK_ICV_STATUS_NOT_POSSIBLE:
880 throw peak::icv::NotSupportedException(errorText);
881 case PEAK_ICV_STATUS_CORRUPTED:
882 throw peak::icv::CorruptedException(errorText);
883 case PEAK_ICV_STATUS_OUT_OF_RANGE:
884 throw peak::icv::OutOfRangeException(errorText);
885 case PEAK_ICV_STATUS_INTERNAL_ERROR:
886 throw peak::icv::Exception(errorText, errorCode);
887 default:
888 throw peak::icv::Exception("Generic Error!", errorCode);
889 }
890 }
891 }
892
893 if (input.AnyCast<peak::icv::Image>().GetData() == data.AnyCast<peak::icv::Image>().GetData())
894 {
895 return peak::common::Any(data.AnyCast<peak::icv::Image>().Copy());
896 }
897 return data;
898}
899
901{
902 return Process(peak::common::Any(image)).AnyCast<peak::icv::Image>();
903}
904
906{
907 return Process(peak::icv::Image(imageView));
908}
909
911{
912 return Process(image);
913}
914
916{
917 return Process(imageView);
918}
919
921{
922 return m_finalConversion->GetOutputPixelFormat();
923}
924
926{
927 const peak::common::PixelFormatInfo info(format);
928
929 const bool isBayerFormat = info.IsSingleChannel() && info.HasChannel(peak::common::Channel::Bayer);
930 const bool isMonoFormat = info.IsSingleChannel() && info.HasIntensityChannel();
931
932 if (isBayerFormat)
933 {
934 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::Bypass);
935 }
936 else if (isMonoFormat)
937 {
938 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerOnly);
939 m_debayer->SetChannelLayout(DebayerChannelLayout::RGB);
940 }
941 else
942 {
943 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerAndMono);
944
947 {
948 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerAndMono);
949 switch (format)
950 {
954 m_debayer->SetChannelLayout(DebayerChannelLayout::RGB);
955 break;
959 m_debayer->SetChannelLayout(DebayerChannelLayout::RGBA);
960 break;
964 m_debayer->SetChannelLayout(DebayerChannelLayout::BGR);
965 break;
969 m_debayer->SetChannelLayout(DebayerChannelLayout::BGRA);
970 break;
971 default:
972 break;
973 }
974 }
975 }
976
977 m_monoConversion->SetEnabled(isMonoFormat);
978
979 m_finalConversion->SetOutputPixelFormat(format);
980
981 const auto bitDepth = info.GetStorageBitsPerChannel();
982 m_unpack->SetTargetBitDepth(bitDepth);
983 m_debayer->SetTargetBitDepth(bitDepth);
984}
985
987{
988 m_processingPolicy = policy;
989
990 m_unpack->SetProcessingPolicy(m_processingPolicy);
991 m_debayer->SetProcessingPolicy(m_processingPolicy);
992}
993
994inline void DefaultPipeline::SetAutoFeatureModule(const std::shared_ptr<modules::IAutoFeature>& autoFeatureModule)
995{
996 if (m_autoFeatureModule != nullptr)
997 {
998 m_autoFeatureModule->SetGainModule(nullptr);
999 }
1000
1001 m_autoFeatureModule = autoFeatureModule;
1002
1003 m_colorCorrection->SetAutoFeatureModule(m_autoFeatureModule);
1004
1005 if (m_autoFeatureModule != nullptr)
1006 {
1007 m_autoFeatureModule->SetGainModule(m_gain);
1008 }
1009}
1010
1011inline std::string DefaultPipeline::GetCurrentIsoUtcTime()
1012{
1013 const auto now = std::chrono::system_clock::now();
1014 const std::time_t nowC = std::chrono::system_clock::to_time_t(now);
1015 std::tm tm{};
1016
1017#if defined(_WIN32) || defined(_WIN64)
1018 gmtime_s(&tm, &nowC);
1019#else
1020 gmtime_r(&nowC, &tm);
1021#endif
1022
1023 std::ostringstream oss;
1024 oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ");
1025 return oss.str();
1026}
1027
1028inline std::vector<std::shared_ptr<modules::IModule>> DefaultPipeline::GetModules() const
1029{
1030 if (m_autoFeatureModule == nullptr)
1031 {
1032 return { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_monoConversion,
1033 m_sharpening, m_toneCurveCorrection, m_finalConversion };
1034 }
1035
1036 return { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_autoFeatureModule,
1037 m_monoConversion, m_sharpening, m_toneCurveCorrection, m_finalConversion };
1038}
1039
1040inline std::vector<std::shared_ptr<features::IFeature>> DefaultPipeline::GetFeatures() const
1041{
1042 return { m_hotpixelFeature, m_binningFeature, m_decimationFeature, m_mirrorFeature, m_rotationFeature, m_gainFeature,
1043 m_colorCorrectionFeature, m_saturationFeature, m_sharpeningFeature, m_gammaFeature, m_digitalBlackFeature };
1044}
1045
1046} // namespace pipeline
1047} // namespace peak
A type-erased container for any copyable value.
T & AnyCast()
Casts the stored value to the specified type.
Interface for viewing image pixel data from arbitrary sources.
Provides information and utility functions for pixel formats.
bool HasIntensityChannel() const
Checks whether the pixel format includes an intensity channel.
bool HasChannel(Channel channel) const
Checks whether a specific channel is present in the pixel format.
size_t GetStorageBitsPerChannel() const
Returns the number of bits used per channel for storage.
bool IsSingleChannel() const
Checks whether the pixel format contains only a single channel.
Thrown when input data or a file is malformed, unreadable, or otherwise corrupted.
Deserializer for reading serialized data and converting it into an IArchive object.
std::shared_ptr< peak::common::serialization::IArchive > Read(std::istream &stream) override
Reads serialized data from the specified stream and deserializes it into an archive.
The base class for all exceptions thrown by the IDS peak ICV library.
Thrown when a file input/output operation fails.
For detailed information about the use of ids_peak_icv Image refer to the Image Guide.
uint8_t * GetData() const
Provides a pointer to the image data buffer.
Image Copy() const
Creates a deep copy of the current Image.
Thrown when the library configuration is invalid.
Thrown when a requested operation is not implemented or supported.
Thrown when a value is outside the allowed range.
Serializer for writing IArchive objects to an output stream.
void Write(const peak::common::serialization::IArchive &archive, std::ostream &stream) override
Serializes an archive and writes it to a stream.
Image processing pipeline for sequential transformation of raw image frames.
features::MirrorFeature & Mirror() const
Provides access to the mirror feature for image mirroring operations.
void SetAutoFeatureModule(const std::shared_ptr< modules::IAutoFeature > &autoFeatureModule)
Sets an auto feature module for automatic image adjustments.
peak::icv::Image Process(const peak::icv::Image &image) const
Applies the pipeline to the given image and returns the result as a new image.
peak::icv::Image operator<<(const peak::icv::Image &image) const
Convenience operator for processing input using the pipeline.
features::SharpeningFeature & Sharpening() const
Provides access to the sharpening feature for image detail enhancement.
void SetOutputPixelFormat(peak::common::PixelFormat format)
Defines the desired pixel format for processed images.
features::DecimationFeature & Decimation() const
Provides access to the decimation feature for resolution reduction by pixel skipping.
void ImportSettingsFromString(const std::string &settings) override
Restores pipeline settings from a previously serialized string.
features::BinningFeature & Binning() const
Provides access to the binning feature for resolution reduction and noise improvement.
features::DigitalBlackFeature & DigitalBlack() const
Provides access to the digital black feature for sensor offset correction.
void ReleaseBuffers() const
Frees unused internal buffers.
features::SaturationFeature & Saturation() const
Provides access to the saturation feature for color intensity adjustments.
peak::common::PixelFormat GetOutputPixelFormat() const
features::ColorCorrectionFeature & ColorCorrection() const
Provides access to the color correction feature for color space transformations.
features::HotpixelCorrectionFeature & HotpixelCorrection() const
Provides access to the hot pixel correction feature for defective pixel repair.
features::GammaFeature & Gamma() const
Provides access to the gamma feature for brightness and contrast adjustments.
DefaultPipeline()
Creates a DefaultPipeline with default module settings.
features::GainFeature & Gain() const
Provides access to the gain feature for brightness and white balance adjustments.
std::string ExportSettingsToString() const override
Converts the current pipeline settings into a string format.
void SetProcessingPolicy(ProcessingPolicy policy)
Sets the processing policy for the image processing pipeline.
features::RotationFeature & Rotation() const
Provides access to the rotation feature for image rotation operations.
void ResetToDefault() override
Resets all modules in the pipeline to their default state. Also resets their enabled state.
Base class for implementing a custom pipeline.
Binning is used to decrease the image size.
Color correction applies a 3x3 ColorCorrectionMatrix to the image.
Decimation is used to decrease the image size.
Digital black applies digital black correction to an image.
The GainFeature applies gain to the image.
Gamma applies an inverse gamma transformation to an image.
HotpixelCorrection detects and corrects hot pixels in camera images.
Mirror provides functionality to flip the image left-right or up-down.
Rotation provides fixed-angle rotation functionality.
Adjusts the saturation of an image by modifying a 3x3 ColorCorrectionMatrix.
Sharpening applies a sharpening filter to enhance image detail.
PixelFormat
Enum listing all supported pixel formats and their internal IDs.
@ RGBa10
RGBA 10-Bit pixel format.
@ RGB8
RGB 8-Bit pixel format.
@ RGBa8
RGBA 8-Bit pixel format.
@ RGBa12
RGBA 12-Bit pixel format.
@ BGRa12
BGRA 12-Bit pixel format.
@ BGR12
BGR 12-Bit pixel format.
@ RGB10
RGB 10-Bit pixel format.
@ BGR10
BGR 10-Bit pixel format.
@ RGB12
RGB 12-Bit pixel format.
@ BGRa8
BGRA 8-Bit pixel format.
@ BGRa10
BGRA 10-Bit pixel format.
@ BGR8
BGR 8-Bit pixel format.
@ BinningAverage
The averaged pixel values of neighboring rows and/or columns are computed during binning.
@ Decimation
The additional pixel values of neighboring rows and/or columns are skipped during decimation.
ProcessingPolicy
Specifies the processing policy.
@ BayerOnly
Convert only Bayer-pattern images.
@ BayerAndMono
Convert both Bayer-pattern and monochrome images.
@ BGR
Blue-Green-Red format with 3 channels.
@ BGRA
Blue-Green-Red-Alpha format with 4 channels.
@ RGB
Red-Green-Blue format with 3 channels.
@ RGBA
Red-Green-Blue-Alpha format with 4 channels.
Enum holding the possible pixel format names.