IDS Peak comfortSDK, genericSDK, IPL, and AFL developer manuals are external documents. Please contact us if you need them.
Debayering in the camera
Fig. 282: Debayering in the camera
Debayering in the software (IDS peak IPL)
Fig. 283: Debayering in IDS peak IPL
Image conversion in the camera
To get already converted color images from the camera, the source pixel format must be set to an appropriate color format. For example, if an RGB format with 8 bits per color channel is selected, then this is 24 bits of data per pixel (= 3 bytes). The required bandwidth on the transfer line is thus 3 times as high as for the transfer of a Bayer format.
Querying supported source pixel formats in the camera as strings
genericC++
|
for (const auto& entry : nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("PixelFormat")->Entries())
{
if ((peak::core::nodes::NodeAccessStatus::NotAvailable == entry->AccessStatus()) ||
(peak::core::nodes::NodeAccessStatus::NotImplemented == entry->AccessStatus()))
{
// Format not available (at the moment)
}
else
{
std::string format = entry->SymbolicValue();
}
}
|
Querying the current source pixel format as string
genericC++
|
std::string format = nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("PixelFormat")->CurrentEntry()->SymbolicValue();
|
Setting the source pixel format as string
genericC++
|
nodemapRemoteDevice->FindNode<peak::core::nodes::EnumerationNode>("PixelFormat")->SetCurrentEntry("RGB8");
|
Image conversion in IDS peak IPL
The conversion of Bayer images can be done in IDS peak IPL. For this, the function library offers useful conversion functions. In the following example, Bayer images are received in the image acquisition loop and then converted to RBG format (see Receiving images). The ConvertTo() function creates a new IDS peak image with the desired target pixel format (IDS peak IPL::Image). Afterwards, the buffer can be returned to the buffer pool.
|
Note that only with the "ConvertTo()" function a copy of the buffer is created. Before this, the buffer must not be returned to the buffer pool, otherwise the data may be overwritten!
|
The quality and speed of the conversion can also be set.
Conversion Modes
Fast
|
Conversion mode optimized for minimum processing effort with slightly lower quality
|
HighQuality
|
Conversion mode optimized for quality, with slightly higher processing effort
|
Classic
|
Conversion mode with compatibility to uEye camera models. In terms of speed, comparable to "Fast".
|
Creating an image with target pixel format (BGRa8) directly from buffer
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
const auto image = peak::BufferTo<IDS peak IPL::Image>(buffer).ConvertTo(
peak::ipl::PixelFormatName::BGRa8, peak::ipl::ConversionMode::Fast);
// Queue buffer again
m_dataStream->QueueBuffer(buffer);
}
catch (const std::exception& e)
{
// ...
}
}
|
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
var buffer = m_dataStream.WaitForFinishedBuffer(5000);
var image = new peak.ipl.Image((peak.ipl.PixelFormatName)buffer.PixelFormat(), buffer.BasePtr(),
buffer.Size(), buffer.Width(), buffer.Height(), buffer.Timestamp_ns());
image = image.ConvertTo(peak.ipl.PixelFormatName.BGRa8, peak.ipl.ConversionMode.Fast);
// Queue buffer again
m_dataStream.QueueBuffer(buffer);
}
catch (Exception e)
{
// ...
}
}
|
while m_running:
try:
# Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
buffer = m_data_stream.WaitForFinishedBuffer(5000)
image = ids_peak_ipl.Image.CreateFromSizeAndBuffer(
buffer.PixelFormat(),
buffer.BasePtr(),
buffer.Size(),
buffer.Width(),
buffer.Height()
)
image = image.ConvertTo(ids_peak_ipl.PixelFormatName_BGRa8, ids_peak_ipl.ConversionMode_Fast)
# Queue buffer again
m_data_stream.QueueBuffer(buffer)
except Exception as e:
# ...
str_error = str(e)
|
Alternative 1: Creating a peak::ipl::image first and converting it later
This method will be needed later on, if further operations are to be done on the Bayer image before the Bayer conversion.
genericC++
|
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
// Create IDS peak IPL image from buffer
const auto image = peak::ipl::Image(peak::BufferTo<Image>(buffer));
const auto imageProcessed = image.ConvertTo(peak::ipl::PixelFormatName::BGRa8, peak::ipl::ConversionMode::Fast);
// Queue buffer again
m_dataStream->QueueBuffer(buffer);
}
catch (const std::exception& e)
{
// ...
}
}
|
Alternative 2: Specifying a previously created image buffer as the target for conversion
Prerequisite The created buffer has the correct size. In case of a BGRA8 conversion, this means 4x the size of the original Bayer buffer. The following example creates a QImage that can be easily displayed in a QWidget application. The image data area of the QImage is passed directly to the "ConvertTo()" function. The converted data will be written there. In addition to the pixel format, the "ConvertTo" function requires a pointer to the destination buffer and the size of this buffer. The function also creates a peak::ipl::Image from the image data and returns it.
m_imageWidth and m_imageHeight are the known values for the image width and height.
genericC++
|
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
// Create QImage with the correct image size
QImage qImage(m_imageWidth, m_imageHeight, QImage::Format_RGB32);
// Create IDS peak IPL image for debayering and convert it to RGBa8 format
const auto image = peak::BufferTo<peak::ipl::Image>(buffer).ConvertTo(
peak::ipl::PixelFormatName::BGRa8, qImage.bits(), static_cast<size_t>(qImage.byteCount()), peak::ipl::ConversionMode::Fast);
// Queue buffer again
m_dataStream->QueueBuffer(buffer);
}
catch (const std::exception& e)
{
// ...
}
}
|
Alternative 3: Mix of alternative 1 and 2
genericC++
|
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
// Create peak::ipl image from buffer
const auto image = peak::ipl::Image(peak::BufferTo<Image>(buffer));
// Create QImage with the correct image size
QImage qImage(m_imageWidth, m_imageHeight, QImage::Format_RGB32);
// Create IDS peak IPL image for debayering and convert it to RGBa8 format
const auto imageProcessed = image.ConvertTo(
peak::ipl::PixelFormatName::BGRa8, qImage.bits(), static_cast<size_t>(qImage.byteCount()), peak::ipl::ConversionMode::Fast);
// Queue buffer again
m_dataStream->QueueBuffer(buffer);
}
catch (const std::exception& e)
{
// ...
}
}
|
Alternative 4: Setting the conversion mode first via a Converter object
The conversion mode can also be preset independently of the image acquisition loop. For this, a so-called ImageConverter must be created and then the parameter must be set.
genericC++
|
peak::ipl::ImageConverter m_imageConverterIPL;
m_imageConverterIPL->SetConversionMode(peak::ipl::ConversionMode::Fast)
|
The conversion in the image acquisition loop is subsequently performed via the ImageConverter.
genericC++
|
while (m_running)
{
try
{
// Get buffer from device's DataStream. Wait 5000 ms. The buffer is automatically locked until it is queued again.
const auto buffer = m_dataStream->WaitForFinishedBuffer(5000);
// Create IDS peak IPL image from buffer
const auto image = peak::ipl::Image(peak::BufferTo<Image>(buffer));
// Create QImage with the correct image size
QImage qImage(m_imageWidth, m_imageHeight, QImage::Format_RGB32);
auto imageProcessed = m_imageConverterIPL->Convert(image, peak::ipl::PixelFormatName::BGRa8, qImage.bits(), static_cast<size_t>(qImage.byteCount()));
// Queue buffer again
m_dataStream->QueueBuffer(buffer);
}
catch (const std::exception& e)
{
// ...
}
}
|