IDS peak ICV v1.0.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
261class DefaultPipeline final : public PipelineBase
262{
263public:
272
278 ~DefaultPipeline() override;
279
290 PEAK_COMMON_NO_DISCARD std::string ExportSettingsToString() const override;
291
301 void ImportSettingsFromString(const std::string& settings) override;
302
308 void ResetToDefault() override;
309
317 PEAK_COMMON_NO_DISCARD const char* GetType() const override;
318
335
351
364
377
391 void ReleaseBuffers() const;
392
403
414
425
436
447
458
469
480
491
502
513
529
540
556
565 {
566 return m_processingPolicy;
567 }
568
582 void SetAutoFeatureModule(const std::shared_ptr<modules::IAutoFeature>& autoFeatureModule);
583
584private:
585 static std::string GetCurrentIsoUtcTime();
586
587 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<modules::IModule>> GetModules() const override;
588 PEAK_COMMON_NO_DISCARD std::vector<std::shared_ptr<features::IFeature>> GetFeatures() const;
589
590 PEAK_COMMON_NO_DISCARD inline peak::common::Any Process(const peak::common::Any& input) const override;
591
592 ProcessingPolicy m_processingPolicy{ ProcessingPolicy::Fast };
593
594 std::shared_ptr<detail::UnpackModule> m_unpack{ std::make_shared<detail::UnpackModule>() };
595 std::shared_ptr<detail::HotpixelCorrectionModule> m_hotpixel{ std::make_shared<detail::HotpixelCorrectionModule>() };
596 std::shared_ptr<detail::DownsamplingModule> m_binning{ std::make_shared<detail::DownsamplingModule>(
598 std::shared_ptr<detail::DownsamplingModule> m_decimation{ std::make_shared<detail::DownsamplingModule>(
600 std::shared_ptr<detail::TransformationModule> m_transformation{ std::make_shared<detail::TransformationModule>() };
601 std::shared_ptr<detail::GainModule> m_gain{ std::make_shared<detail::GainModule>() };
602 std::shared_ptr<detail::DebayerModule> m_debayer{ std::make_shared<detail::DebayerModule>() };
603 std::shared_ptr<detail::ColorMatrixTransformationModule> m_colorCorrection{
604 std::make_shared<detail::ColorMatrixTransformationModule>()
605 };
606 std::shared_ptr<detail::MonoConversionModule> m_monoConversion{ std::make_shared<detail::MonoConversionModule>() };
607 std::shared_ptr<detail::SharpeningModule> m_sharpening{ std::make_shared<detail::SharpeningModule>() };
608 std::shared_ptr<detail::ToneCurveCorrectionModule> m_toneCurveCorrection{ std::make_shared<detail::ToneCurveCorrectionModule>() };
609 std::shared_ptr<detail::PixelFormatConversionModule> m_finalConversion{ std::make_shared<detail::PixelFormatConversionModule>() };
610
611 std::shared_ptr<features::HotpixelCorrectionFeature> m_hotpixelFeature{ new features::HotpixelCorrectionFeature{ *m_hotpixel } };
612 std::shared_ptr<features::BinningFeature> m_binningFeature{ new features::BinningFeature{ *m_binning } };
613 std::shared_ptr<features::DecimationFeature> m_decimationFeature{ new features::DecimationFeature{ *m_decimation } };
614 std::shared_ptr<features::MirrorFeature> m_mirrorFeature{ new features::MirrorFeature{ *m_transformation } };
615 std::shared_ptr<features::RotationFeature> m_rotationFeature{ new features::RotationFeature{ *m_transformation } };
616 std::shared_ptr<features::GainFeature> m_gainFeature{ new features::GainFeature{ *m_gain } };
617 std::shared_ptr<features::ColorCorrectionFeature> m_colorCorrectionFeature{ new features::ColorCorrectionFeature{
618 *m_colorCorrection } };
619 std::shared_ptr<features::SaturationFeature> m_saturationFeature{ new features::SaturationFeature{ *m_colorCorrection } };
620 std::shared_ptr<features::SharpeningFeature> m_sharpeningFeature{ new features::SharpeningFeature{ *m_sharpening } };
621 std::shared_ptr<features::GammaFeature> m_gammaFeature{ new features::GammaFeature{ *m_toneCurveCorrection } };
622 std::shared_ptr<features::DigitalBlackFeature> m_digitalBlackFeature{ new features::DigitalBlackFeature{ *m_toneCurveCorrection } };
623
624 std::shared_ptr<modules::IAutoFeature> m_autoFeatureModule;
625
626 constexpr static int pipelineVersion{ 1 };
627};
628
630{
631 m_monoConversion->SetEnabled(false);
632
633 const auto format = m_finalConversion->GetOutputPixelFormat();
634
635 const auto bitDepth = peak::common::PixelFormatInfo(format).GetStorageBitsPerChannel();
636 m_unpack->SetProcessingPolicy(m_processingPolicy);
637 m_unpack->SetTargetBitDepth(bitDepth);
638 m_debayer->SetProcessingPolicy(m_processingPolicy);
639 m_debayer->SetTargetBitDepth(bitDepth);
640}
641
643{
644 if (m_autoFeatureModule)
645 {
646 m_autoFeatureModule->SetGainModule(nullptr);
647 }
648}
649
651{
652 const auto archive = std::make_shared<peak::icv::Archive>();
653
654 const auto moduleList = GetModules();
655 std::vector<std::shared_ptr<peak::common::serialization::IArchive>> modules;
656 modules.reserve(moduleList.size());
657
658 for (const auto& module : moduleList)
659 {
660 if (module == nullptr)
661 {
662 continue;
663 }
664 auto moduleArchive = archive->CreateArchive();
665 moduleArchive->SetString("Type", module->GetType());
666
667 auto moduleDataArchive = moduleArchive->CreateArchive();
668 module->Serialize(*moduleDataArchive);
669 moduleArchive->SetArchive("Data", moduleDataArchive);
670 modules.push_back(moduleArchive);
671 }
672 archive->SetArchiveArray("Modules", modules);
673 archive->SetInt("Version", pipelineVersion);
674 archive->SetString("Type", GetType());
675 archive->SetString("Creation", GetCurrentIsoUtcTime());
676
677 peak::icv::Serializer serializer;
678
679 std::stringstream ss;
680 serializer.Write(*archive, ss);
681 return ss.str();
682}
683
684inline void DefaultPipeline::ImportSettingsFromString(const std::string& settings)
685{
686 peak::icv::Deserializer deserializer;
687
688 std::stringstream ss;
689 ss << settings;
690 const auto archive = deserializer.Read(ss);
691
692 const auto version = archive->GetInt("Version");
693
694 if (version < 1)
695 {
697 "The 'Version' entry " + std::to_string(version) + " in the settings string is invalid! Must be at least 1.");
698 }
699
700 const auto pipelineType = archive->GetString("Type");
701 if (pipelineType != GetType())
702 {
704 "The settings for " + pipelineType + " are not compatible with this pipeline (" + GetType() + ").");
705 }
706
707 std::vector<std::shared_ptr<modules::IModule>> modules;
708 if (m_autoFeatureModule == nullptr)
709 {
710 modules = { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_monoConversion,
711 m_sharpening, m_toneCurveCorrection, m_finalConversion };
712 }
713 else
714 {
715 modules = { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection,
716 m_autoFeatureModule, m_monoConversion, m_sharpening, m_toneCurveCorrection, m_finalConversion };
717 }
718
719 std::unordered_map<std::string, std::shared_ptr<peak::common::serialization::IArchive>> archiveMap;
720 auto moduleArchives = archive->GetArchiveArray("Modules");
721
722 for (const auto& moduleArchive : moduleArchives)
723 {
724 const auto moduleType = moduleArchive->GetString("Type");
725 const auto data = moduleArchive->GetArchive("Data");
726 archiveMap.emplace(moduleType, data);
727 }
728
729 for (const auto& module : modules)
730 {
731 const auto found = archiveMap.find(module->GetType());
732 if (found == archiveMap.end())
733 {
734 throw peak::common::IOException(std::string("The settings for module ") + module->GetType() + " are missing!");
735 }
736
737 module->Deserialize(*found->second);
738 }
739}
740
742{
743 for (const auto& module : GetModules())
744 {
745 module->ResetToDefault();
746 module->SetEnabled(true);
747 }
748 for (const auto& feature : GetFeatures())
749 {
750 feature->ResetToDefault();
751 feature->SetEnabled(true);
752 }
753 m_monoConversion->SetEnabled(false);
754}
755
756inline const char* DefaultPipeline::GetType() const
757{
758 return "DefaultPipeline";
759}
760
762{
763 m_unpack->ReleaseBuffers();
764 m_debayer->ReleaseBuffers();
765 m_monoConversion->ReleaseBuffers();
766 m_finalConversion->ReleaseBuffers();
767}
768
770{
771 return *m_mirrorFeature;
772}
773
775{
776 return *m_rotationFeature;
777}
778
780{
781 return *m_gainFeature;
782}
783
785{
786 return *m_colorCorrectionFeature;
787}
788
790{
791 return *m_saturationFeature;
792}
793
795{
796 return *m_gammaFeature;
797}
798
800{
801 return *m_digitalBlackFeature;
802}
803
805{
806 return *m_sharpeningFeature;
807}
808
810{
811 return *m_hotpixelFeature;
812}
813
815{
816 return *m_binningFeature;
817}
818
820{
821 return *m_decimationFeature;
822}
823
825{
826 auto data = input;
827
828 for (const auto& mod : GetModules())
829 {
830 if (!mod)
831 {
832 continue;
833 }
834
835 try
836 {
837 data = mod->Process(data);
838 }
839 catch (const peak::icv::Exception& e)
840 {
841 const auto errorCode = e.GetStatus();
842 const auto* const what = e.what();
843 const auto* const moduleType = mod->GetType();
844
845 const auto errorText = std::string{ "[" } + moduleType + "] " + what;
846 switch (errorCode)
847 {
848 case PEAK_ICV_STATUS_LIBRARY_NOT_INITIALIZED:
849 case PEAK_ICV_STATUS_DYNAMIC_DEPENDENCY_MISSING:
850 throw peak::icv::InvalidConfigurationException(errorText, errorCode);
851 case PEAK_ICV_STATUS_INVALID_HANDLE:
852 case PEAK_ICV_STATUS_INVALID_BUFFER_SIZE:
853 case PEAK_ICV_STATUS_MISMATCH:
854 case PEAK_ICV_STATUS_NULL_POINTER:
855 case PEAK_ICV_STATUS_NOT_SUPPORTED:
856 case PEAK_ICV_STATUS_NOT_POSSIBLE:
857 throw peak::icv::NotSupportedException(errorText);
858 case PEAK_ICV_STATUS_CORRUPTED:
859 throw peak::icv::CorruptedException(errorText);
860 case PEAK_ICV_STATUS_OUT_OF_RANGE:
861 throw peak::icv::OutOfRangeException(errorText);
862 case PEAK_ICV_STATUS_INTERNAL_ERROR:
863 throw peak::icv::Exception(errorText, errorCode);
864 default:
865 throw peak::icv::Exception("Generic Error!", errorCode);
866 }
867 }
868 }
869
870 if (input.AnyCast<peak::icv::Image>().GetData() == data.AnyCast<peak::icv::Image>().GetData())
871 {
872 return peak::common::Any(data.AnyCast<peak::icv::Image>().Copy());
873 }
874 return data;
875}
876
878{
879 return Process(peak::common::Any(image)).AnyCast<peak::icv::Image>();
880}
881
883{
884 return Process(peak::icv::Image(imageView));
885}
886
888{
889 return Process(image);
890}
891
893{
894 return Process(imageView);
895}
896
898{
899 return m_finalConversion->GetOutputPixelFormat();
900}
901
903{
904 const peak::common::PixelFormatInfo info(format);
905
906 const bool isBayerFormat = info.IsSingleChannel() && info.HasChannel(peak::common::Channel::Bayer);
907 const bool isMonoFormat = info.IsSingleChannel() && info.HasIntensityChannel();
908
909 if (isBayerFormat)
910 {
911 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::Bypass);
912 }
913 else if (isMonoFormat)
914 {
915 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerOnly);
916 m_debayer->SetChannelLayout(DebayerChannelLayout::RGB);
917 }
918 else
919 {
920 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerAndMono);
921
924 {
925 m_debayer->SetConversionPolicy(detail::DebayerConversionPolicy::BayerAndMono);
926 switch (format)
927 {
931 m_debayer->SetChannelLayout(DebayerChannelLayout::RGB);
932 break;
936 m_debayer->SetChannelLayout(DebayerChannelLayout::RGBA);
937 break;
941 m_debayer->SetChannelLayout(DebayerChannelLayout::BGR);
942 break;
946 m_debayer->SetChannelLayout(DebayerChannelLayout::BGRA);
947 break;
948 default:
949 break;
950 }
951 }
952 }
953
954 m_monoConversion->SetEnabled(isMonoFormat);
955
956 m_finalConversion->SetOutputPixelFormat(format);
957
958 const auto bitDepth = info.GetStorageBitsPerChannel();
959 m_unpack->SetProcessingPolicy(m_processingPolicy);
960 m_unpack->SetTargetBitDepth(bitDepth);
961 m_debayer->SetProcessingPolicy(m_processingPolicy);
962 m_debayer->SetTargetBitDepth(bitDepth);
963}
964
966{
967 m_processingPolicy = policy;
968
969 m_unpack->SetProcessingPolicy(m_processingPolicy);
970 m_debayer->SetProcessingPolicy(m_processingPolicy);
971
972 const auto bitDepth = peak::common::PixelFormatInfo(m_finalConversion->GetOutputPixelFormat()).GetStorageBitsPerChannel();
973 m_unpack->SetTargetBitDepth(bitDepth);
974 m_debayer->SetTargetBitDepth(bitDepth);
975}
976
977inline void DefaultPipeline::SetAutoFeatureModule(const std::shared_ptr<modules::IAutoFeature>& autoFeatureModule)
978{
979 if (m_autoFeatureModule != nullptr)
980 {
981 m_autoFeatureModule->SetGainModule(nullptr);
982 }
983
984 m_autoFeatureModule = autoFeatureModule;
985
986 m_colorCorrection->SetAutoFeatureModule(m_autoFeatureModule);
987
988 if (m_autoFeatureModule != nullptr)
989 {
990 m_autoFeatureModule->SetGainModule(m_gain);
991 }
992}
993
994inline std::string DefaultPipeline::GetCurrentIsoUtcTime()
995{
996 const auto now = std::chrono::system_clock::now();
997 const std::time_t nowC = std::chrono::system_clock::to_time_t(now);
998 std::tm tm{};
999
1000#if defined(_WIN32) || defined(_WIN64)
1001 gmtime_s(&tm, &nowC);
1002#else
1003 gmtime_r(&nowC, &tm);
1004#endif
1005
1006 std::ostringstream oss;
1007 oss << std::put_time(&tm, "%Y-%m-%dT%H:%M:%SZ");
1008 return oss.str();
1009}
1010
1011inline std::vector<std::shared_ptr<modules::IModule>> DefaultPipeline::GetModules() const
1012{
1013 if (m_autoFeatureModule == nullptr)
1014 {
1015 return { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_monoConversion,
1016 m_sharpening, m_toneCurveCorrection, m_finalConversion };
1017 }
1018
1019 return { m_unpack, m_hotpixel, m_binning, m_decimation, m_transformation, m_gain, m_debayer, m_colorCorrection, m_autoFeatureModule,
1020 m_monoConversion, m_sharpening, m_toneCurveCorrection, m_finalConversion };
1021}
1022
1023inline std::vector<std::shared_ptr<features::IFeature>> DefaultPipeline::GetFeatures() const
1024{
1025 return { m_hotpixelFeature, m_binningFeature, m_decimationFeature, m_mirrorFeature, m_rotationFeature, m_gainFeature,
1026 m_colorCorrectionFeature, m_saturationFeature, m_sharpeningFeature, m_gammaFeature, m_digitalBlackFeature };
1027}
1028
1029} // namespace pipeline
1030} // 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.
Thrown when an input, output, file or device communication error occurs.
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.
A deserializer that reads serialized data and converts it to IArchive objects.
std::shared_ptr< peak::common::serialization::IArchive > Read(std::istream &stream) override
Reads and deserializes data from an input stream.
The base class for all exceptions thrown by the IDS peak ICV library.
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.
A serializer that serializes IArchive objects.
void Write(const peak::common::serialization::IArchive &archive, std::ostream &stream) override
Writes the serialized archive data to an output 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 used in the pipeline.
peak::icv::Image Process(const peak::icv::Image &image) const
Processes the input 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)
Configures the pipeline for output format.
const char * GetType() const override
Returns the type of the module for serialization purposes.
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
Retrieves the output pixel format of the pipeline.
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.
ProcessingPolicy GetProcessingPolicy() const
Retrieves the current processing policy of the image processing pipeline.
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.
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.
#define PEAK_COMMON_NO_DISCARD
Compatability macro for the nodiscard attribute.
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.
@ 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.
@ BayerOnly
Convert only Bayer-pattern images.
@ BayerAndMono
Convert both Bayer-pattern and monochrome images.
Enum holding the possible pixel format names.