Polarizasyon Verilerinin Baumer GAPI SDK Kullanılarak Hesaplanması [AN201904]
Baumer Kameralar: VCXU-50MP, VCXG-50MP
Yazılım: Baumer GAPI SDK v2.9.2 ve üzeri
Baumer polarizasyon kameraları, alınan görüntünün yoğunluğunu ve polarizasyonunu ölçme yeteneği sağlar. Bu sayede, uygulamanızda polarizasyon bilgilerini kullanmanıza olanak tanır. Bu Uygulama Notu, polarizasyon bilgilerini nasıl elde edeceğinizi açıklar.
Teknik Arka Plan
Baumer polarizasyon kameraları, Sony IMC250MZR sensörüne dayanır. Bu sensör, 4 bitişik pikseldeki polarizasyon bilgilerini filtreleyen bir metal ağ ile kaplanmıştır. Polarizasyon açısı, 0°, 45°, 90° ve 135° hizalanmasıyla filtrelenir.
Bu bilgilerle aşağıdaki veriler hesaplanabilir:
- Polarizasyon Açısı (Angle-Of-Polarization, AOP)
- Doğrusal Polarizasyon Derecesi (Degree-Of-Linear-Polarization, DOLP)
- Doğrusal Polarizasyon Açısı ve Derecesi (Angle-And-Degree-Of-Linear-Polarization, ADOLP)
- Görüntü Yoğunluğu
Baumer GAPI SDK ile Polarizasyon Kamerasının Kullanımı
Kamera, yalnızca polarizasyon hakkında ham verileri sağlar. Farklı polarizasyon formatlarının hesaplanması, Baumer GAPI SDK ile ana bilgisayar sisteminde yapılır. Bu, verilerin her polarizasyon formatı (AOP, DOLP, ADOLP, Yoğunluk) için ayrı ayrı değil, sadece bir kez aktarılması sayesinde gerekli bant genişliğini azaltır.
Polarizasyon Kamera Özelliklerinin Açıklaması
Standartlaştırılmış SFNC özellikleri olan “ComponentSelector” ve “ComponentEnable” kullanılarak, GenICam™ uyumlu bir yazılım kameranın ham polarize veri sağladığını tanıyabilir. Bu özellikler değiştirilemez (salt okunur).
Tanımlama için aşağıdaki özellikler kontrol edilmelidir:
ComponentSelector = PolarizedRaw
ComponentEnable = True
Üçüncü taraf yazılımlara geniş uyumluluk sağlamak amacıyla, Baumer özel görüntü formatları tanıtmamıştır. Ham polarize veriler, standart formatlar olan Mono8, Mono10, Mono12 veya Mono12p kullanılarak aktarılır.
Ayrıca, kamera “Calibration Control” kategorisi altında kalibrasyon için gerekli özellikler sunar. Bu özellikler Baumer tarafından kalibre edilmiş değerlerle doldurulmuştur. Gerekirse, “DeviceResetToDeliveryState” komutu bu değerleri Baumer’in sağladığı kalibre edilmiş değerlere sıfırlar.
| GenICam Özel Baumer Özellikleri | |
|---|---|
| KalibrasyonKontrol | Kategori |
| CalibrationAngleOfPolarizationOffset (R/W) |
“CalibrationAngleOfPolarizationOffset” özelliği, üretim toleranslarını ve kamera sistemindeki sapmaları düzeltmek amacıyla polarizasyon açısının ofsetini değiştirmek için kullanılabilir. |
| CalibrationMatrixValue (R/W) CalibrationMatrixValueSelector (R/W) |
Kalibre edilmiş matris, sensör etkilerini düzeltmek ve polarizasyon ölçümlerinin doğruluğunu artırmak için kullanılır. Genellikle bu değerler müşteri tarafından değiştirilmemelidir. |
Not
“CalibrationAngleOfPolarizationOffset” ve “CalibrationMatrixValue” özellikleri doğrudan kamera flaş belleğine yazılır. Bu, normal bir özellik erişimiyle karşılaştırıldığında oldukça yavaştır. Bu değerleri çok sık değiştirmek, flaş belleğin maksimum ömrünü de kısaltabilir.
Baumer GAPI SDK Özelliklerinin Açıklaması: Polarizasyon Verilerini Hesaplamak İçin
Farklı polarizasyon formatlarının hesaplanması, Baumer GAPI SDK kullanılarak ana sistemde yapılır.
Aşağıdaki örnekler:
- 020_Polarized_SinglePart
- 021_Polarized_MultiPart
bu işlemin adım adım nasıl yapıldığını gösterir.
Not
Polarizasyon formatlarının hesaplanması oldukça zorlayıcıdır. İyi bir performans elde etmek için işlemcinin AVX2 vektör uzantısı kullanılır. Bu özellik, Intel Haswell ve AMD Excavator mimarilerinden itibaren mevcuttur. AVX2 olmadan algoritmanın performansı önemli ölçüde azalacaktır.
Hesaplamanın mümkün olduğunca az kaynak kullanmasını sağlamak ve yüksek kare hızlarına ulaşmak için verilerin nasıl işleneceğine dair iki yöntem bulunmaktadır. Burada en önemli yapılandırmalar ve yazılım özelliklerinin kullanımı açıklanmıştır.
Eğer bir uygulama için yalnızca bir polarizasyon formatına (AOP, DOLP veya ADOLP) ihtiyaç duyuluyorsa, tek parçalı bir görüntü nesnesi kullanmak en iyisidir. Tek parçalı görüntü nesnesi tam olarak bir görüntü içerir.
// Acquire an image to a buffer
BGAPI2::Buffer* pBufferFilled = pDataStream->GetFilledBuffer(1000);
bo_uint width = static_cast<bo_uint>(pBufferFilled->GetWidth());
bo_uint height = static_cast<bo_uint>(pBufferFilled->GetHeight());
void* pImageData = pBufferFilled->GetMemPtr();
bo_uint64 imageDataSize = pBufferFilled->GetMemSize();
// Create an Image object using the ImageProcessor
pImageProcessor = new BGAPI2::ImageProcessor();
pImage = pImageProcessor->CreateImage(bufferWidth, bufferHeight, "BaumerPolarized8", pImageData, imageDataSize);
// or
pImage->Init(bufferWidth, bufferHeight, "BaumerPolarized8", pImageData, imageDataSize);
// Enable all polarized formats (AOP, DOLP, ADOLP, Intensity)
BGAPI2::Node* pCompSelector = pImage->GetNode("ComponentSelector");
BGAPI2::NodeMap*pComponents = pCompSelector->GetEnumNodeList();
for (bo_uint64 i = 0; i < pComponents->GetNodeCount(); i++)
{
pCompSelector->SetInt(i);
pImage->GetNode("ComponentEnable")->SetBool( true );
}
// Calculate all the polarization formats from the raw image to a multi-part Image object.
BGAPI2::Image* pMultiPartImage = pImageProcessor->CreateTransformedImage(pImage, "Mono8");
// Get necessary information about each multi-part
BGAPI2::Node* pComponentSelector = pMultiPartImage->GetNode("ComponentSelector");
BGAPI2::Node* pComponentEnable = pMultiPartImage->GetNode("ComponentEnable");
BGAPI2::Node* pComponentOffset = pMultiPartImage->GetNode("ComponentOffset");
BGAPI2::Node* pComponentLength = pMultiPartImage->GetNode("ComponentLength");
const void* const pImageBuffer = pMultiPartImage->GetBuffer();
// Loop through the multi-part Image object to extract all the parts
for (std::set<std::string>::const_iterator it = sComponents.begin(); it != sComponents.end(); it++)
{
pComponentSelector->SetValue(it->c_str());
std::string sComponent = pComponentSelector->GetValue().get();
if (pComponentEnable->GetBool()) {
bo_uint64 partLength = pComponentLength->GetInt();
BGAPI2::Image* pComponent = NULL;
if (partLength > 0)
{
// Part is valid
bo_uint64 partOffset = pComponentOffset->GetInt();
pComponent = pImageProcessor->CreateImage(width, height, "Mono8"
, (char*)(pImageBuffer)+partOffset, partLength);
}
else
{
// Part is empty
if (sComponent == "ADOLP") {
// ADOLP is calculated from the AOP and DOLP images, therefore this
// second transformation is necessary.
pComponent = pImageProcessor->CreateTransformedImage(pMultiPartImage, "RGB8");
}
}
if (pComponent)
{
// Whatever needs to be done with the polarization data goes here
// doCustomCalculation(pComponent, sComponent);
// Release the data when not needed anymore
pComponent->Release();
}
}
}
Eğer bir uygulamada birden fazla polarizasyon formatı (örneğin, AOP ve DOLP) gerekiyorsa, çok parçalı bir görüntü nesnesi kullanmak daha iyidir. Bu şekilde, her formatı ayrı ayrı hesaplamak yerine tüm hesaplamalar tek seferde yapılabilir.
// Acquire an image to a buffer
BGAPI2::Buffer* pBufferFilled = pDataStream->GetFilledBuffer(1000);
bo_uint width = static_cast(pBufferFilled->GetWidth());
bo_uint height = static_cast(pBufferFilled->GetHeight());
void* pImageData = pBufferFilled->GetMemPtr();
bo_uint64 imageDataSize = pBufferFilled->GetMemSize();
// Create an Image object using the ImageProcessor
pImageProcessor = new BGAPI2::ImageProcessor();
pImage = pImageProcessor->CreateImage(bufferWidth, bufferHeight, "BaumerPolarized8", pImageData, imageDataSize);
// or
pImage->Init(bufferWidth, bufferHeight, "BaumerPolarized8", pImageData, imageDataSize);
// Enable all polarized formats (AOP, DOLP, ADOLP, Intensity)
BGAPI2::Node* pCompSelector = pImage->GetNode("ComponentSelector");
BGAPI2::NodeMap* pComponents = pCompSelector->GetEnumNodeList();
for (bo_uint64 i = 0; i < pComponents->GetNodeCount(); i++)
{
pCompSelector->SetInt(i);
pImage->GetNode("ComponentEnable")->SetBool(true);
}
// Calculate all the polarization formats from the raw image to a multi-part Image object.
BGAPI2::Image* pMultiPartImage = pImageProcessor->CreateTransformedImage(pImage, "Mono8");
// Get necessary information about each multi-part
BGAPI2::Node* pComponentSelector = pMultiPartImage->GetNode("ComponentSelector");
BGAPI2::Node* pComponentEnable = pMultiPartImage->GetNode("ComponentEnable");
BGAPI2::Node* pComponentOffset = pMultiPartImage->GetNode("ComponentOffset");
BGAPI2::Node* pComponentLength = pMultiPartImage->GetNode("ComponentLength");
const void* const pImageBuffer = pMultiPartImage->GetBuffer();
// Loop through the multi-part Image object to extract all the parts
for (std::set::const_iterator it = sComponents.begin(); it != sComponents.end(); it++)
{
pComponentSelector->SetValue(it->c_str());
std::string sComponent = pComponentSelector->GetValue().get();
if (pComponentEnable->GetBool()) {
bo_uint64 partLength = pComponentLength->GetInt();
BGAPI2::Image* pComponent = NULL;
if (partLength > 0)
{
// Part is valid
bo_uint64 partOffset = pComponentOffset->GetInt();
pComponent = pImageProcessor->CreateImage(width, height, "Mono8"
, (char*)(pImageBuffer) + partOffset, partLength);
}
else
{
// Part is empty
if (sComponent == "ADOLP") {
// ADOLP is calculated from the AOP and DOLP images, therefore this
// second transformation is necessary.
pComponent = pImageProcessor->CreateTransformedImage(pMultiPartImage, "RGB8");
}
}
if (pComponent)
{
// Whatever needs to be done with the polarization data goes here
// doCustomCalculation(pComponent, sComponent);
// Release the data when not needed anymore
pComponent->Release();
}
}
}
Baumer Camera Explorer ile Polarizasyon Kamerasının Kullanımı
Camera Explorer, polarizasyon verilerini AOP, DOLP, ADOLP ve yoğunluk formatlarında görüntülemek ve kaydetmek için de kullanılabilir.
Yapılandırma, Basic View (Temel Görünüm) içinde, polarization (polarizasyon) kategorisi kullanılarak yapılır.
