IDS peak ICV v1.2.0
Loading...
Searching...
No Matches
peak_icv_image.ipp
Go to the documentation of this file.
1
11#pragma once
12
16#include <algorithm>
17#include <cstring>
18#include <utility>
19
20#ifdef WITH_peak_ipl
21# include <peak_ipl/types/peak_ipl_pixel_format.hpp>
22#endif
23
24namespace peak
25{
26namespace icv
27{
28inline peak_icv_image_handle Image::CreateFromFile(const std::string& path)
29{
30 peak_icv_image_handle handle{};
32 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_CreateFromFile(&handle, path.c_str());
33 });
34 return handle;
35}
36
37inline peak_icv_image_handle Image::CreateFromFile(const std::string& path, peak::common::PixelFormat name)
38{
39 peak_icv_image_handle handle{};
41 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_CreateFromFileWithPixelFormat(
42 &handle, path.c_str(), peak::common::detail::CppPixelFormatToCPixelFormat(name));
43 });
44 return handle;
45}
46
47inline peak_icv_image_info Image::CreateFromHandle(peak_icv_image_handle handle)
48{
49 peak_icv_image_info imageInfo{};
51 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_GetInfo(handle, &imageInfo, sizeof(imageInfo));
52 });
53
54 return imageInfo;
55}
56
57inline peak_icv_image_handle Image::CreateFromSize(peak::common::PixelFormat pixelFormat, const peak::common::Size& size)
58{
59 peak_icv_image_handle handle{};
61 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Create(
62 &handle, peak::common::detail::CppPixelFormatToCPixelFormat(pixelFormat), { size.GetWidth(), size.GetHeight() });
63 });
64 return handle;
65}
66
67inline peak_icv_image_handle Image::CreateFromBuffer(
68 peak::common::PixelFormat pixelFormat, const peak::common::Size& size, const uint8_t* buffer, size_t bufferSize)
69{
70 peak_icv_image_handle handle{};
72 peak_icv_image_info info{ peak::common::detail::CppPixelFormatToCPixelFormat(pixelFormat),
73 { size.GetWidth(), size.GetHeight() }, bufferSize, const_cast<uint8_t*>(buffer) };
74 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_CreateFromImageInfo(&handle, info, sizeof(info));
75 });
76 return handle;
77}
78
79inline peak::common::Metadata Image::AddCaptureInformationDataToMetadata(
80 peak_icv_capture_information captureInformationC, peak::common::Metadata metadata)
81{
82 metadata.SetValueByKey<peak::common::MetadataKey::DeviceTimestamp>(captureInformationC.relative_timestamp);
83 metadata.SetValueByKey<peak::common::MetadataKey::BinningHorizontal>(captureInformationC.binning_factor.x);
84 metadata.SetValueByKey<peak::common::MetadataKey::BinningVertical>(captureInformationC.binning_factor.y);
86 peak::common::RectangleU{ captureInformationC.region_of_interest.x, captureInformationC.region_of_interest.y,
87 captureInformationC.region_of_interest.width, captureInformationC.region_of_interest.height });
88 metadata.SetValueByKey<peak::common::MetadataKey::DeviceExposureTime>(captureInformationC.exposure_time);
89 return metadata;
90}
91
92inline Image::Image(peak_icv_image_handle handle, peak_icv_image_info info)
93 : m_imageHandle{ handle }
94 , m_size{ info.size.width, info.size.height }
95 , m_buffer{ info.buffer }
96 , m_pixelFormatInfo{ peak::common::detail::CPixelFormatToCppPixelFormat(info.pixelFormat) }
97{}
98
99#ifdef WITH_peak_ipl
100inline Image::Image(const peak::ipl::Image& image)
101 : Image(CreateFromBuffer(peak::common::detail::CPixelFormatToCppPixelFormat(
102 static_cast<peak_common_pixel_format>(image.PixelFormat().PixelFormatName())), // NOLINT
103 peak::common::Size{ static_cast<uint32_t>(image.Width()), static_cast<uint32_t>(image.Height()) }, image.Data(),
104 image.ByteCount()))
105{
106 peak_icv_capture_information captureInformationC{ { 1, 1 }, image.Timestamp(), {}, {}, {} };
107 detail::ExecuteAndMapReturnCodes([&] {
108 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_SetCaptureInformation(m_imageHandle, captureInformationC, sizeof(captureInformationC));
109 });
110
111 m_metaData = std::make_unique<peak::common::Metadata>(
112 AddCaptureInformationDataToMetadata(captureInformationC, peak::common::Metadata{}));
113 m_image = image;
114}
115#endif
116
117inline Image::Image(const peak::common::IImageView& imageView)
118 : Image(CreateFromBuffer(imageView.GetPixelFormat(), imageView.GetSize(), imageView.GetData(), imageView.GetSizeInBytes()))
119{
120 const auto metadata = imageView.GetMetadata();
121 SetMetadata(*metadata);
122}
123
124inline Image::Image(const std::string& path)
125 : Image{ CreateFromFile(path) }
126{}
127
128inline Image::Image(const std::string& path, peak::common::PixelFormat name)
129 : Image{ CreateFromFile(path, name) }
130{}
131
132inline Image::Image(peak::common::PixelFormat pixelFormat, uint8_t* buffer, size_t bufferSize, const peak::common::Size& imageSize)
133 : Image{ CreateFromBuffer(pixelFormat, imageSize, buffer, bufferSize),
134 { peak::common::detail::CppPixelFormatToCPixelFormat(pixelFormat), { imageSize.GetWidth(), imageSize.GetHeight() }, bufferSize,
135 buffer } }
136{}
137
138inline Image::Image(peak::common::PixelFormat pixelFormat, const peak::common::Size& imageSize)
139 : Image{ CreateFromSize(pixelFormat, imageSize) }
140{}
141
142inline Image::Image(peak_icv_image_handle imageHandle)
143 : Image{ imageHandle, CreateFromHandle(imageHandle) }
144{}
145
146inline Image::Image(const Image& other)
147 : Image{ other.m_imageHandle, CreateFromHandle(other.m_imageHandle) }
148{
149 if (other.m_metaData)
150 {
151 m_metaData = std::make_unique<peak::common::Metadata>(*other.m_metaData);
152 }
154 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_IncreaseUseCount(other.m_imageHandle);
155 });
156#ifdef WITH_peak_ipl
157 m_image = other.m_image;
158#endif
159}
160
161inline Image::Image(Image&& other) noexcept
162 : Image{ other.m_imageHandle, CreateFromHandle(other.m_imageHandle) }
163{
164 m_metaData = std::move(other.m_metaData);
165#ifdef WITH_peak_ipl
166 m_image = std::move(other.m_image);
167#endif
168 other.m_imageHandle = nullptr;
169}
170
171inline Image& Image::operator=(const Image& other)
172{
173 if (this->m_imageHandle != other.m_imageHandle)
174 {
175 if (m_imageHandle)
176 {
178 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Destroy(m_imageHandle);
179 });
180 }
181
183 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_IncreaseUseCount(other.m_imageHandle);
184 });
185 m_imageHandle = other.m_imageHandle;
186 m_size = other.m_size;
187 m_pixelFormatInfo = other.m_pixelFormatInfo;
188 m_buffer = other.m_buffer;
189 m_metaData = std::make_unique<peak::common::Metadata>(other.GetMetadata());
190#ifdef WITH_peak_ipl
191 m_image = other.m_image;
192#endif
193 }
194
195 return *this;
196}
197
198inline Image& Image::operator=(Image&& other) noexcept
199{
200 if (this->m_imageHandle != other.m_imageHandle)
201 {
202 if (m_imageHandle)
203 {
205 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Destroy(m_imageHandle);
206 });
207 }
208
209 m_imageHandle = std::exchange(other.m_imageHandle, nullptr);
210 m_size = other.m_size;
211 m_pixelFormatInfo = other.m_pixelFormatInfo;
212 m_buffer = std::exchange(other.m_buffer, nullptr);
213 m_metaData = std::exchange(other.m_metaData, nullptr);
214#ifdef WITH_peak_ipl
215 m_image = std::move(other.m_image);
216#endif
217 }
218
219 return *this;
220}
221
223{
224 if (m_imageHandle != nullptr)
225 {
226 std::ignore = PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Destroy(m_imageHandle);
227 }
228}
229
230inline bool Image::operator==(const Image& rhs) const
231{
232 if (rhs.GetSizeInBytes() != this->GetSizeInBytes())
233 {
234 return false;
235 }
236 if (rhs.GetSize() != this->GetSize())
237 {
238 return false;
239 }
240 if (rhs.GetPixelFormat() != this->GetPixelFormat())
241 {
242 return false;
243 }
244 if (rhs.GetRegion() != this->GetRegion())
245 {
246 return false;
247 }
248 bool isSame{};
250 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Compare(
251 m_imageHandle, peak::common::detail::BackendAccessor<Image>::BackendHandle(rhs), &isSame);
252 });
253 return isSame;
254}
255
256inline Image Image::Copy() const
257{
258 Image tmpImg(m_pixelFormatInfo.GetPixelFormat(), m_size);
259#if _MSC_VER
260 memcpy_s(tmpImg.GetData(), tmpImg.GetSizeInBytes(), GetData(), GetSizeInBytes());
261#else
262 std::memcpy(tmpImg.GetData(), GetData(), GetSizeInBytes());
263#endif
264 tmpImg.SetMetadata(GetMetadata());
265 return tmpImg;
266}
267
269{
270 return m_size;
271}
272
273inline uint8_t* Image::GetData() const
274{
275 return m_buffer;
276}
277
278inline size_t Image::GetSizeInBytes() const
279{
280 return m_pixelFormatInfo.GetSizeInBytes(m_size);
281}
282
283inline size_t Image::GetBytesPerLine() const
284{
285 return GetSizeInBytes() / m_size.GetHeight();
286}
287
288inline detail::handle_of_t<Image> Image::GetHandle() const
289{
290 return m_imageHandle;
291}
292
294{
295 return m_pixelFormatInfo.GetPixelFormat();
296}
297
298#ifdef WITH_peak_ipl
299inline peak::ipl::Image Image::GetIPLImage() const
300{
301 if (!m_image.Empty())
302 {
303 return m_image;
304 }
305
306 constexpr std::array<peak::ipl::PixelFormatName, 59> possibleValues{ peak::ipl::PixelFormatName::BayerGR8,
307 peak::ipl::PixelFormatName::BayerGR10, peak::ipl::PixelFormatName::BayerGR12, peak::ipl::PixelFormatName::BayerRG8,
308 peak::ipl::PixelFormatName::BayerRG10, peak::ipl::PixelFormatName::BayerRG12, peak::ipl::PixelFormatName::BayerGB8,
309 peak::ipl::PixelFormatName::BayerGB10, peak::ipl::PixelFormatName::BayerGB12, peak::ipl::PixelFormatName::BayerBG8,
310 peak::ipl::PixelFormatName::BayerBG10, peak::ipl::PixelFormatName::BayerBG12, peak::ipl::PixelFormatName::Mono8,
311 peak::ipl::PixelFormatName::Mono10, peak::ipl::PixelFormatName::Mono12, peak::ipl::PixelFormatName::Mono16,
312 peak::ipl::PixelFormatName::Confidence8, peak::ipl::PixelFormatName::Confidence16,
313 peak::ipl::PixelFormatName::Coord3D_C8, peak::ipl::PixelFormatName::Coord3D_C16,
314 peak::ipl::PixelFormatName::Coord3D_C32f, peak::ipl::PixelFormatName::Coord3D_ABC32f,
315 peak::ipl::PixelFormatName::YUV420_8_YY_UV_SemiplanarIDS, peak::ipl::PixelFormatName::YUV420_8_YY_VU_SemiplanarIDS,
316 peak::ipl::PixelFormatName::YUV422_8_UYVY, peak::ipl::PixelFormatName::RGB8, peak::ipl::PixelFormatName::RGB10,
317 peak::ipl::PixelFormatName::RGB12, peak::ipl::PixelFormatName::BGR8, peak::ipl::PixelFormatName::BGR10,
318 peak::ipl::PixelFormatName::BGR12, peak::ipl::PixelFormatName::RGBa8, peak::ipl::PixelFormatName::RGBa10,
319 peak::ipl::PixelFormatName::RGBa12, peak::ipl::PixelFormatName::BGRa8, peak::ipl::PixelFormatName::BGRa10,
320 peak::ipl::PixelFormatName::BGRa12, peak::ipl::PixelFormatName::BayerBG10p, peak::ipl::PixelFormatName::BayerBG12p,
321 peak::ipl::PixelFormatName::BayerGB10p, peak::ipl::PixelFormatName::BayerGB12p, peak::ipl::PixelFormatName::BayerGR10p,
322 peak::ipl::PixelFormatName::BayerGR12p, peak::ipl::PixelFormatName::BayerRG10p, peak::ipl::PixelFormatName::BayerRG12p,
323 peak::ipl::PixelFormatName::Mono10p, peak::ipl::PixelFormatName::Mono12p, peak::ipl::PixelFormatName::RGB10p32,
324 peak::ipl::PixelFormatName::BGR10p32, peak::ipl::PixelFormatName::BayerRG10g40IDS,
325 peak::ipl::PixelFormatName::BayerGB10g40IDS, peak::ipl::PixelFormatName::BayerGR10g40IDS,
326 peak::ipl::PixelFormatName::BayerBG10g40IDS, peak::ipl::PixelFormatName::BayerRG12g24IDS,
327 peak::ipl::PixelFormatName::BayerGB12g24IDS, peak::ipl::PixelFormatName::BayerGR12g24IDS,
328 peak::ipl::PixelFormatName::BayerBG12g24IDS, peak::ipl::PixelFormatName::Mono10g40IDS,
329 peak::ipl::PixelFormatName::Mono12g24IDS };
330
331 const auto currentPixelFormat = m_pixelFormatInfo.GetPixelFormat();
332 const auto foundIt = std::find_if(possibleValues.begin(), possibleValues.end(), [&](const peak::ipl::PixelFormatName& name) {
333 return static_cast<std::underlying_type<peak::ipl::PixelFormatName>::type>(name)
334 == static_cast<std::underlying_type<peak::ipl::PixelFormatName>::type>(currentPixelFormat);
335 });
336 if (foundIt == possibleValues.end())
337 {
338 throw peak::icv::NotSupportedException("The pixelformat " + m_pixelFormatInfo.GetName()
339 + " has no equivalent in the ids_peak_ipl. As a result, it cannot be converted to an ids_peak_ipl Image!");
340 }
341
342 m_image = peak::ipl::Image{ static_cast<peak::ipl::PixelFormatName>(currentPixelFormat), m_buffer,
343 m_pixelFormatInfo.GetSizeInBytes(m_size), m_size.GetWidth(), m_size.GetHeight(),
345
346 return m_image;
347}
348#endif
349
351{
352 Region region;
354 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_GetRegion(
355 m_imageHandle, peak::common::detail::BackendAccessor<Region>::BackendHandleAddress(region));
356 });
357 return region;
358}
359
360inline void Image::SetRegion(const Region& region) const
361{
362 const peak_icv_region_handle regionHandle = peak::common::detail::BackendAccessor<Region>::BackendHandle(region);
363
365 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_SetRegion(m_imageHandle, regionHandle);
366 });
367}
368
369inline void Image::ResetRegion() const
370{
372 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_ResetRegion(m_imageHandle);
373 });
374}
375
377{
378 Image outputImage(pixelFormat, GetSize());
379 const auto imageHandle = peak::common::detail::BackendAccessor<Image>::BackendHandle(outputImage);
381 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_ConvertPixelFormat(
382 m_imageHandle, peak::common::detail::CppPixelFormatToCPixelFormat(pixelFormat), imageHandle);
383 });
384 return outputImage;
385}
386
387inline Image Image::ConvertPixelFormatWithFactor(peak::common::PixelFormat pixelFormat, const double factor) const
388{
389 Image outputImage(pixelFormat, GetSize());
390 const auto imageHandle = peak::common::detail::BackendAccessor<Image>::BackendHandle(outputImage);
392 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_ConvertPixelFormatWithFactor(
393 m_imageHandle, peak::common::detail::CppPixelFormatToCPixelFormat(pixelFormat), factor, imageHandle);
394 });
395 return outputImage;
396}
397
398inline void Image::SetMetadata(const peak::common::Metadata& metadata)
399{
400 auto captureInformationC = peak::icv::detail::CreateCCaptureInformationFromMetadata(metadata, m_size);
401
403 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_SetCaptureInformation(m_imageHandle, captureInformationC, sizeof(captureInformationC));
404 });
405
406 m_metaData = std::make_unique<peak::common::Metadata>(AddCaptureInformationDataToMetadata(captureInformationC, metadata));
407}
408
410{
411 peak_icv_capture_information captureInformationC;
413 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_GetCaptureInformation(
414 m_imageHandle, &captureInformationC, sizeof(captureInformationC));
415 });
416
417 if (!m_metaData)
418 {
419 m_metaData = std::make_unique<peak::common::Metadata>(
420 AddCaptureInformationDataToMetadata(captureInformationC, peak::common::Metadata{}));
421 }
422 else
423 {
424 m_metaData = std::make_unique<peak::common::Metadata>(AddCaptureInformationDataToMetadata(captureInformationC, *m_metaData));
425 }
426
427
428 return *m_metaData;
429}
430
431inline Image Image::Subtract(const peak::icv::Image& subtrahend) const
432{
433 Image difference{ GetPixelFormat(), GetSize() };
434
436 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Subtract(GetHandle(), subtrahend.GetHandle(), difference.GetHandle());
437 });
438
439
440 return difference;
441}
442
443inline Image Image::operator-(const peak::icv::Image& subtrahend) const
444{
445 return Subtract(subtrahend);
446}
447
449{
450 Image croppedImage{ GetPixelFormat(), { rect.GetWidth(), rect.GetHeight() } };
451
453 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Crop(GetHandle(), croppedImage.GetHandle(),
454 peak::common::detail::BackendAccessor<peak::common::Rectangle>::CreateCType(rect));
455 });
456 return croppedImage;
457}
458
459inline Image Image::Scale(const peak::common::Size& targetImageSize, const Interpolation& interpolation) const
460{
461 Image scaledImage{ GetPixelFormat(), targetImageSize };
463 return PEAK_ICV_C_ABI_PREFIX peak_icv_Image_Scale(
464 GetHandle(), scaledImage.GetHandle(), static_cast<peak_icv_interpolation>(interpolation));
465 });
466 return scaledImage;
467}
468
469#ifdef WITH_peak_ipl
470inline Image::operator peak::ipl::Image() const
471{
472 return GetIPLImage();
473}
474#endif
475} /* namespace icv */
476} /* namespace peak */
Interface for viewing image pixel data from arbitrary sources.
virtual std::shared_ptr< peak::common::Metadata > GetMetadata()=0
Returns the metadata object which can be used to retrieve or set metadata belonging to the image.
Type-safe container for image acquisition metadata.
void SetValueByKey(T &&value)
Stores a value using a strongly typed metadata key.
detail::MetadataKeyTraits< metadataKey >::type GetValueByKey() const
Retrieves the value of a strongly typed metadata key.
size_t GetSizeInBytes(const Size &size) const
Calculates the memory size in bytes for a given image size.
peak::common::PixelFormat GetPixelFormat() const
Returns the underlying pixel format enumeration value.
std::string GetName() const
Returns the human-readable name of the pixel format.
A generic rectangle defined by a point and a size.
constexpr SizeType GetWidth() const
Returns the width of the rectangle.
constexpr SizeType GetHeight() const
Returns the height of the rectangle.
Represents a two-dimensional size with non-negative width and height.
constexpr T GetWidth() const
Returns the width.
constexpr T GetHeight() const
Returns the height.
For detailed information about the use of ids_peak_icv Image refer to the Image Guide.
peak::common::Size GetSize() const
Provides the size of the image in pixels.
void ResetRegion() const
Resets the region on the image to the complete image.
Image operator-(const Image &subtrahend) const
Subtracts the specified subtrahend image pixelwise from the current image and returns the resulting i...
Image & operator=(const Image &other)
uint8_t * GetData() const
Provides a pointer to the image data buffer.
Image Subtract(const Image &subtrahend) const
Subtracts the specified subtrahend image pixelwise from the current image and returns the resulting i...
Region GetRegion() const
Provides the region of the image.
Image(const peak::common::IImageView &imageView)
Constructs an Image from an IImageView Instance.
peak::common::PixelFormat GetPixelFormat() const
Provides the pixel format of the image.
Image Crop(const peak::common::Rectangle &rect) const
Crops the image to the given rectangle.
peak::common::Metadata GetMetadata() const
Returns the Metadata of an image which contains information about the image capture information.
peak::icv::Image ConvertPixelFormat(peak::common::PixelFormat pixelFormat) const
Converts the image to a different pixel format.
void SetMetadata(const peak::common::Metadata &metadata)
Updates the Metadata of an image which is used to store and manage capture information.
Image Copy() const
Creates a deep copy of the current Image.
peak::icv::Image ConvertPixelFormatWithFactor(peak::common::PixelFormat pixelFormat, const double factor) const
Converts an image into another pixel format with a factor multiplied to every pixel.
Image Scale(const peak::common::Size &targetImageSize, const Interpolation &interpolation=Interpolation::NearestNeighbor) const
Returns an image scaled to the given image size.
size_t GetSizeInBytes() const
Provides the size of the image data in bytes.
bool operator==(const Image &rhs) const
size_t GetBytesPerLine() const
Computes the number of bytes required to store one line of pixel data (no padding).
void SetRegion(const Region &region) const
Updates the region on the image.
Thrown when a requested operation is not implemented or supported.
Represents a region defined by a set of points in the image plane.
PixelFormat
Enum listing all supported pixel formats and their internal IDs.
Interpolation
Enumeration of interpolation methods used in image transformations.
constexpr peak_common_pixel_format CppPixelFormatToCPixelFormat(PixelFormat pixelFormat) noexcept
constexpr PixelFormat CPixelFormatToCppPixelFormat(peak_common_pixel_format pixelFormat) noexcept
@ Roi
Region of interest applied to the image.
@ DeviceExposureTime
Device exposure time the image was captured with.
@ BinningHorizontal
Horizontal pixel binning factor.
@ DeviceTimestamp
Device-provided image acquisition timestamp in nanoseconds.
@ BinningVertical
Vertical pixel binning factor.
peak_icv_capture_information CreateCCaptureInformationFromMetadata(const peak::common::Metadata &metadata)
void ExecuteAndMapReturnCodes(const CallableType &callableObject)
peak::common::detail::c_type_of_t< Type > * handle_of_t
peak_icv_image * peak_icv_image_handle