Baumer industrial camera Baumer camera how to use the polarization function (polarization camera advantages and industry applications) (C#)

 Project scenario:

Baumer Industrial Cameras Baumer cameras are high-performance, high-quality industrial cameras that can be used in various application scenarios, such as object detection, counting and recognition, motion analysis and image processing.  

Baumer's 10 Gigabit cameras have excellent image processing performance and can transmit high-resolution images in real time. In addition, the camera features fast data transfer, low power consumption, easy integration, and high scalability.  

The special features of the polarization cameras in the Baumer camera series facilitate their use in some special applications.


technical background

Polarized Industrial Camera Cameras are designed to capture polarized light to improve image quality and reduce glare in various industrial applications.

These cameras have polarizing filters integrated into their lenses that can help improve image contrast, increase color saturation, and reduce reflections from shiny surfaces.

Some of the key features of polarized industrial cameras might include high resolution, fast frame rates, rugged design for industrial environments, and compatibility with different lighting conditions.

Additionally, they may have features such as triggering, exposure control, and image processing capabilities that help capture clear and detailed images for inspection and analysis purposes.

  

  


code analysis

Baumer Industrial Camera 020_Polarized.cpp in the Baumer Camera SDK sample describes in detail how to configure the camera polarization function.

The address of the software SDK example is as follows: Baumer_GAPI_SDK_2.9.2_win_x86_64_cpp\examples\src\0_Common\020_Polarized_SinglePart\020_Polarized_SinglePart.cpp

VCXU-50MP and VCXG-50MP in the Baumer industrial camera series are polarization industrial cameras. 

Model

Resolution

Sensor

Frame rate           GigE          USB3

VCXG-50MP

5 MP

2448 × 2048

Sony IMX250MZR (2/3″, 3.45 µm)

35|24

-

VCXU-50MP

5 MP

2448 × 2048

Sony IMX250MZR (2/3″, 3.45 µm)

-

77

This example describes how to use the provided Baumer GAPI API functions to configure the camera and calculate the required polarization data (AOL, DOP, ADOLP, Intensity)

The following example describes how to obtain polarization data from the VCXU-50MP and VCXG-50MP.

Describes all how to use the provided Baumer GAPI API functions to configure the camera and calculate the required polarization data (AOL, DOP, ADOLP, Brightness) If more than one available polarization data format is required, it is better to use multipart images for calculations efficient.

This is described in example 021_Polalization_MultiPart

The overall structure of the code is relatively simple. After the camera is initialized, the polarization function of the camera is used. The following part of the core code is mainly described as follows: 

/*
    This example describes how to obtain polarisation data from the Baumer VCXU-50MP and VCXG-50MP.
    The example describes all how to use the provided Baumer GAPI API functionality to configure
    the camera and calculate the required polarisation data (AOL, DOP, ADOLP, Intensity)

    If more than one of the available polarisation data format is needed it is more efficient to use
    a multi-part image for the calculation. This is described in the example 021_Polarized_MultiPart.cpp
*/

#include <stdio.h>
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include "bgapi2_genicam/bgapi2_genicam.hpp"

// handles the command line argument parsing
#include "Arguments.h"

using namespace BGAPI2;

//------------------------------------------------------------------------------
static double g_aopOffset = 0.0;
static bool   g_bAopOffset = false;

struct DeviceMatch {
    BGAPI2::System* pSystem;
    BGAPI2::Interface* pInterface;
    BGAPI2::Device* pDevice;
};

//------------------------------------------------------------------------------
/* Read the polarization calibration matrix and angle of polarization offset from the camera
   used to calculated the required polarisation data in the Baumer GAPI image processor */
static void SetDeviceCalibrationToImageProcessor(BGAPI2::Device* const pDevice, BGAPI2::ImageProcessor* const pImageProcessor);

/* Setup the Baumer GAPI to calculate the requested polarization component from the raw
   polarized image */
static void EnableSingleComponent(BGAPI2::Image* const pImage, const std::string sComponent);

/* Get the Angle Offset from the command line parameter (if provided) and use it for the calculation */
static void argumentAopOffset(const Argument& argument, const ArgumentMode mode, const char* const pParam);

/* connect to the first polarisation camera found on the system */
static int GetFirstDevice(DeviceMatch* const pMatch
    , bool(*pSystemFilter)(BGAPI2::System* pSystem)
    , bool(*pInterfaceFilter)(BGAPI2::Interface* pInterface)
    , bool(*pDeviceFilter)(BGAPI2::Device* pDevice)
    , std::ostream& log);

/* Helper to Display various information of the camera */
static void GetDeviceInfo(std::ostream& log, BGAPI2::Device* const pDevice, const bool bOpen);

/* Helper to filter found cameras devices and select only polarization camera for this example */
static bool PolarizationDeviceFilter(BGAPI2::Device* const pDevice);

/* Release all allocated resources */
static int ReleaseAllResources(BGAPI2::System* pSystem, BGAPI2::Interface* pInterface, BGAPI2::Device* pDevice
    , BGAPI2::DataStream* pDataStream, BGAPI2::ImageProcessor* pImageProcessor);

//------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
    // Declaration of variables
    BGAPI2::System* pSystem = NULL;
    BGAPI2::Interface* pInterface = NULL;
    BGAPI2::Device* pDevice = NULL;
    BGAPI2::ImageProcessor* pImageProcessor = NULL;

    BGAPI2::DataStreamList *datastreamList = NULL;
    BGAPI2::DataStream * pDataStream = NULL;
    BGAPI2::String sDataStreamID;

    BGAPI2::BufferList *bufferList = NULL;
    BGAPI2::Buffer * pBuffer = NULL;
    BGAPI2::String sBufferID;
    int returncode = 0;

    std::string sComponent = "ADOLP";
    bool bBufferedLog = true;


    std::cout << std::endl;
    std::cout << "###########################################################" << std::endl;
    std::cout << "# PROGRAMMER'S GUIDE Example 020_Polarized_SinglePart.cpp #" << std::endl;
    std::cout << "###########################################################" << std::endl;
    std::cout << std::endl << std::endl;

    static const Argument argumentList[] = {
        { &sComponent, "c", "component", false, argumentString,    0, "<component>",  "enable component (Intensity/AOP/DOLP/ADOLP)" },
        { NULL,        "o", "offsetAOP", false, argumentAopOffset, 0, "<aop offset>", "angle of polarization offset" },
    };

    parseArguments(argumentList, sizeof(argumentList) / sizeof(argumentList[0]), argc, argv);

    // Check if the polarisation format provided as command line parameter is a valid polarisation format
    try
    {
        pImageProcessor = new BGAPI2::ImageProcessor();

        // Create dummy image to check if requested component is available
        char dummyBuffer[1];
        BGAPI2::Image* pImage = pImageProcessor->CreateImage(1, 1, "BaumerPolarized8", dummyBuffer, sizeof(dummyBuffer));

        BGAPI2::Node* pComponentSelector = pImage->GetNode("ComponentSelector");
        pComponentSelector->SetValue(sComponent.c_str());

        pImage->Release();
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;

        std::cout << std::endl << "Component '" << sComponent << "' not supported" << std::endl;
        std::cout << std::endl << "Supported Formats are Intensity, AOP, DOP and ADOLP" << std::endl;
        std::cout << std::endl << "End" << std::endl << "Input any number to close the program:";
        int endKey = 0;
        std::cin >> endKey;

        ReleaseAllResources(pSystem, pInterface, pDevice, pDataStream, pImageProcessor);
        return returncode;
    }


    // Find and open the first polarisation camera
    DeviceMatch match = { NULL, NULL, NULL };
    std::stringstream bufferedLog;

    const int code = GetFirstDevice(&match, NULL, NULL, PolarizationDeviceFilter, bBufferedLog ? bufferedLog : std::cout);

    pSystem    = match.pSystem;
    pInterface = match.pInterface;
    pDevice    = match.pDevice;

    if ((code != 0) || (pDevice == NULL))
    {
        // Error or no device found
        if (bBufferedLog != false)
        {
            // Display full device search
            std::cout << bufferedLog.str();
        }

        returncode = (returncode == 0) ? code : returncode;
        if (returncode == 0)
        {
            std::cout << " No Polarized Device found " << sDataStreamID << std::endl;
        }

        std::cout << std::endl << "End" << std::endl << "Input any number to close the program:";
        int endKey = 0;
        std::cin >> endKey;

        ReleaseAllResources(pSystem, pInterface, pDevice, pDataStream, pImageProcessor);
        return returncode;
    }

    GetDeviceInfo(std::cout, pDevice, false);

    /* Determine the polarized pixel format for processing
       As the camera sends the raw polarized data as a Mono8/10/12 pixelformat we need to pick the
       corresponding Baumer polarized pixelformat depending on the camera setting for the
       calculation of the polarized image.
    */
    std::string sPixelFormatRaw = "";
    try {
        BGAPI2::String sPixelFormat = pDevice->GetRemoteNode("PixelFormat")->GetValue();
        if (sPixelFormat == "Mono8")
        {
            sPixelFormatRaw = "BaumerPolarized8";
        }
        else if (sPixelFormat == "Mono10")
        {
            sPixelFormatRaw = "BaumerPolarized10";
        }
        else if (sPixelFormat == "Mono12")
        {
            sPixelFormatRaw = "BaumerPolarized12";
        }
        else if (sPixelFormat == "Mono12p")
        {
            sPixelFormatRaw = "BaumerPolarized12p";
        }
        else
        {
            std::cout << " Pixel format not supported" << sDataStreamID << std::endl;
        }
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    if (sPixelFormatRaw == "")
    {
        returncode = (returncode == 0) ? 1 : returncode;

        std::cout << std::endl << "End" << std::endl << "Input any number to close the program:";
        int endKey = 0;
        std::cin >> endKey;

        ReleaseAllResources(pSystem, pInterface, pDevice, pDataStream, pImageProcessor);
        return returncode;
    }

    std::cout << "DEVICE PARAMETER SETUP" << std::endl;
    std::cout << "######################" << std::endl << std::endl;

    // Set angle of polarization offset to device, if command line parameter passed
    if (g_bAopOffset)
    {
        try
        {
            BGAPI2::Node* const pAngleOfPolarizationOffset = pDevice->GetRemoteNode("CalibrationAngleOfPolarizationOffset");
            pAngleOfPolarizationOffset->SetDouble(g_aopOffset);
            std::cout << "         AngleOfPolarizationOffset:  " << pAngleOfPolarizationOffset->GetValue() << std::endl;
        }
        catch (BGAPI2::Exceptions::IException& ex)
        {
            returncode = (returncode == 0) ? 1 : returncode;
            std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
            std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
            std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
        }
    }

    try
    {
        // Set trigger mode to off (FreeRun)
        pDevice->GetRemoteNode("TriggerMode")->SetString("Off");
        std::cout << "         TriggerMode:             " << pDevice->GetRemoteNode("TriggerMode")->GetValue() << std::endl;
        std::cout << std::endl;
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }


    std::cout << "IMAGE PROCESSOR SETUP" << std::endl;
    std::cout << "#####################" << std::endl << std::endl;

    // Configure the Image Processor to use the calibration values from the camera device
    try
    {
        SetDeviceCalibrationToImageProcessor(pDevice, pImageProcessor);
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }
    std::cout << std::endl << std::endl;


    std::cout << "DATA STREAM LIST" << std::endl;
    std::cout << "################" << std::endl << std::endl;

    try
    {
        // Get information for all available data streams
        datastreamList = pDevice->GetDataStreams();
        datastreamList->Refresh();
        std::cout << "5.1.8   Detected datastreams:     " << datastreamList->size() << std::endl;

        for (DataStreamList::iterator dstIterator = datastreamList->begin(); dstIterator != datastreamList->end(); dstIterator++)
        {
            std::cout << "  5.2.4   DataStream ID:          " << dstIterator->first << std::endl << std::endl;
        }
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }


    std::cout << "DATA STREAM" << std::endl;
    std::cout << "###########" << std::endl << std::endl;

    // Open the first datastream
    try
    {
        for (DataStreamList::iterator dstIterator = datastreamList->begin(); dstIterator != datastreamList->end(); dstIterator++)
        {
            std::cout << "5.1.9   Open first datastream " << std::endl;
            std::cout << "          DataStream ID:          " << dstIterator->first << std::endl << std::endl;
            dstIterator->second->Open();
            sDataStreamID = dstIterator->first;
            std::cout << "        Opened datastream - NodeList Information " << std::endl;
            std::cout << "          StreamAnnounceBufferMinimum:  " << dstIterator->second->GetNode("StreamAnnounceBufferMinimum")->GetValue() << std::endl;
            if( dstIterator->second->GetTLType() == "GEV" )
            {
                std::cout << "          StreamDriverModel:            " << dstIterator->second->GetNode("StreamDriverModel")->GetValue() << std::endl;
            }
            std::cout << "  " << std::endl;
            break;
        }
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    if (sDataStreamID == "")
    {
        std::cout << " No DataStream found " << sDataStreamID << std::endl;
        std::cout << std::endl << "End" << std::endl << "Input any number to close the program:";
        int endKey = 0;
        std::cin >> endKey;
        ReleaseAllResources(pSystem, pInterface, pDevice, pDataStream, pImageProcessor);
        return returncode;
    }
    else
    {
        pDataStream = (*datastreamList)[sDataStreamID];
    }


    std::cout << "BUFFER LIST" << std::endl;
    std::cout << "###########" << std::endl << std::endl;

    try
    {
        // get the BufferList
        bufferList = pDataStream->GetBufferList();

        // allocate 4 buffers using internal buffer mode
        for(int i = 0; i < 4; i++)
        {
            pBuffer = new BGAPI2::Buffer();
            bufferList->Add(pBuffer);
        }
        std::cout << "5.1.10   Announced buffers:       " << bufferList->GetAnnouncedCount() << " using " << pBuffer->GetMemSize() * bufferList->GetAnnouncedCount() << " [bytes]" << std::endl;
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    try
    {
        for (BufferList::iterator bufIterator = bufferList->begin(); bufIterator != bufferList->end(); bufIterator++)
        {
            bufIterator->second->QueueBuffer();
        }
        std::cout << "5.1.11   Queued buffers:          " << bufferList->GetQueuedCount() << std::endl;
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }
    std::cout << " " << std::endl;


    std::cout << "CAMERA START" << std::endl;
    std::cout << "############" << std::endl << std::endl;

    // Start DataStream acquisition
    try
    {
        pDataStream->StartAcquisitionContinuous();
        std::cout << "5.1.12   DataStream started " << std::endl;
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    // Start aquisition from camera device
    try
    {
        std::cout << "5.1.12   " << pDevice->GetModel() << " started " << std::endl;
        pDevice->GetRemoteNode("AcquisitionStart")->Execute();
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    // Capture 12 images
    std::cout << " " << std::endl;
    std::cout << "CAPTURE 12 IMAGES BY IMAGE POLLING" << std::endl;
    std::cout << "##################################" << std::endl << std::endl;

    // Create the image object to store the calculated polarisation data
    BGAPI2::Image* pImagePolarized = NULL;

    try
    {
        // Set to true to save result of the first captured image as a Baumer RAW image
        bool bSaveBrw = true;

        for (int i = 0; i < 12; i++)
        {
            BGAPI2::Buffer* pBufferFilled = pDataStream->GetFilledBuffer(1000); // timeout 1000 msec
            if (pBufferFilled == NULL)
            {
                std::cout << "Error: Buffer Timeout after 1000 msec" << std::endl;
            }
            else
            {
                try
                {
                    if (pBufferFilled->GetIsIncomplete() == true)
                    {
                        std::cout << "Error: Image is incomplete" << std::endl;
                    }
                    else if (pBufferFilled->GetImagePresent() != true)
                    {
                        std::cout << "Error: Image not present" << std::endl;
                    }
                    else
                    {
                        // get information about the image from the buffer object
                        bo_uint width = static_cast<bo_uint>(pBufferFilled->GetWidth());
                        bo_uint height = static_cast<bo_uint>(pBufferFilled->GetHeight());
                        void* pBufferData = pBufferFilled->GetMemPtr();
                        bo_uint64 bufferDataSize = pBufferFilled->GetMemSize();
                        bo_uint64 imageOffset = pBufferFilled->GetImageOffset();
                        bo_uint64 imageDataSize = (bufferDataSize > imageOffset) ? (bufferDataSize - imageOffset) : 0;
                        void* pImageData = reinterpret_cast<char*>(pBufferData) + imageOffset;

                        std::cout << " Image " << std::setw(5) << pBufferFilled->GetFrameID() << " received in memory address " << std::hex << pBufferData << std::dec << std::endl;

                        /* For the first image, a new image object is created, all further images reuse the object and
                           therefore just initialize it with new data */
                        if (pImagePolarized == NULL)
                        {
                            pImagePolarized = pImageProcessor->CreateImage(width, height, sPixelFormatRaw.c_str(), pImageData, imageDataSize);

                            // Enable the component to be calculated, disable all others
                            EnableSingleComponent(pImagePolarized, sComponent);
                        }
                        else
                        {
                            pImagePolarized->Init(width, height, sPixelFormatRaw.c_str(), pImageData, imageDataSize);
                            /* As the pixel format is the same for all images captured, the enabled components and the active component selector
                               are preserved, so you don't need to enable components on every image. */
                        }

                        // Calculate the required Polarisation format using a direct transformation from raw polarized image.
                        BGAPI2::Image* pComponent = pImageProcessor->CreateTransformedImage(pImagePolarized
                            , (sComponent != "ADOLP") ? "Mono8" : "RGB8");

                        std::cout << "  component image: " << pComponent->GetNode("ComponentSelector")->GetValue().get() << std::endl;
                        if (bSaveBrw) {
                            std::string sFilename = sComponent + ".brw";
                            pComponent->GetNode("SaveBrw")->SetValue(sFilename.c_str());
                        }

                        pComponent->Release();
                        bSaveBrw = false;
                    }
                }
                catch (BGAPI2::Exceptions::IException& ex)
                {
                    returncode = (returncode == 0) ? 1 : returncode;
                    std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
                    std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
                    std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
                }
            }

            if (pBufferFilled)
            {
                // Queue buffer again
                pBufferFilled->QueueBuffer();
            }
        }
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }
    std::cout << " " << std::endl;

    if (pImagePolarized)
    {
        try
        {
            pImagePolarized->Release();
        }
        catch (BGAPI2::Exceptions::IException& ex)
        {
            returncode = (returncode == 0) ? 1 : returncode;
            std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
            std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
            std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
        }
    }

    std::cout << "CAMERA STOP" << std::endl;
    std::cout << "###########" << std::endl << std::endl;

    // Stop the camera
    try
    {
        if (pDevice->GetRemoteNodeList()->GetNodePresent("AcquisitionAbort"))
        {
            pDevice->GetRemoteNode("AcquisitionAbort")->Execute();
            std::cout << "5.1.12   " << pDevice->GetModel() << " aborted " << std::endl;
        }

        pDevice->GetRemoteNode("AcquisitionStop")->Execute();
        std::cout << "5.1.12   " << pDevice->GetModel() << " stopped " << std::endl;
        std::cout << std::endl;

        BGAPI2::String sExposureNodeName = "";
        if (pDevice->GetRemoteNodeList()->GetNodePresent("ExposureTime"))
        {
            sExposureNodeName = "ExposureTime";
        }
        else if (pDevice->GetRemoteNodeList()->GetNodePresent("ExposureTimeAbs"))
        {
            sExposureNodeName = "ExposureTimeAbs";
        }
        std::cout << "         ExposureTime:                   " << std::fixed << std::setprecision(0) << pDevice->GetRemoteNode(sExposureNodeName)->GetDouble() << " [" << pDevice->GetRemoteNode(sExposureNodeName)->GetUnit() << "]" << std::endl;
        if (pDevice->GetTLType() == "GEV")
        {
            if(pDevice->GetRemoteNodeList()->GetNodePresent("DeviceStreamChannelPacketSize"))
                std::cout << "         DeviceStreamChannelPacketSize:  " << pDevice->GetRemoteNode("DeviceStreamChannelPacketSize")->GetInt() << " [bytes]" << std::endl;
            else
                std::cout << "         GevSCPSPacketSize:              " << pDevice->GetRemoteNode("GevSCPSPacketSize")->GetInt() << " [bytes]" << std::endl;
                std::cout << "         GevSCPD (PacketDelay):          " << pDevice->GetRemoteNode("GevSCPD")->GetInt() << " [tics]" << std::endl;
        }
        std::cout << std::endl;
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    // Stop DataStream acquisition
    try
    {
        if (pDataStream->GetTLType() == "GEV")
        {
            // DataStream Statistic
            std::cout << "         DataStream Statistics " << std::endl;
            std::cout << "           DataBlockComplete:              " << pDataStream->GetNodeList()->GetNode("DataBlockComplete")->GetInt() << std::endl;
            std::cout << "           DataBlockInComplete:            " << pDataStream->GetNodeList()->GetNode("DataBlockInComplete")->GetInt() << std::endl;
            std::cout << "           DataBlockMissing:               " << pDataStream->GetNodeList()->GetNode("DataBlockMissing")->GetInt() << std::endl;
            std::cout << "           PacketResendRequestSingle:      " << pDataStream->GetNodeList()->GetNode("PacketResendRequestSingle")->GetInt() << std::endl;
            std::cout << "           PacketResendRequestRange:       " << pDataStream->GetNodeList()->GetNode("PacketResendRequestRange")->GetInt() << std::endl;
            std::cout << "           PacketResendReceive:            " << pDataStream->GetNodeList()->GetNode("PacketResendReceive")->GetInt() << std::endl;
            std::cout << "           DataBlockDroppedBufferUnderrun: " << pDataStream->GetNodeList()->GetNode("DataBlockDroppedBufferUnderrun")->GetInt() << std::endl;
            std::cout << "           Bitrate:                        " << pDataStream->GetNodeList()->GetNode("Bitrate")->GetDouble() << std::endl;
            std::cout << "           Throughput:                     " << pDataStream->GetNodeList()->GetNode("Throughput")->GetDouble() << std::endl;
            std::cout << std::endl;
        }
        if (pDataStream->GetTLType() == "U3V")
        {
            // DataStream Statistic
            std::cout << "         DataStream Statistics " << std::endl;
            std::cout << "           GoodFrames:            " << pDataStream->GetNodeList()->GetNode("GoodFrames")->GetInt() << std::endl;
            std::cout << "           CorruptedFrames:       " << pDataStream->GetNodeList()->GetNode("CorruptedFrames")->GetInt() << std::endl;
            std::cout << "           LostFrames:            " << pDataStream->GetNodeList()->GetNode("LostFrames")->GetInt() << std::endl;
            std::cout << std::endl;
        }

        // BufferList Information
        std::cout << "         BufferList Information " << std::endl;
        std::cout << "           DeliveredCount:        " << bufferList->GetDeliveredCount() << std::endl;
        std::cout << "           UnderrunCount:         " << bufferList->GetUnderrunCount() << std::endl;
        std::cout << std::endl;

        pDataStream->StopAcquisition();
        std::cout << "5.1.12   DataStream stopped " << std::endl;
        bufferList->DiscardAllBuffers();
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }
    std::cout << std::endl;


    std::cout << "RELEASE" << std::endl;
    std::cout << "#######" << std::endl << std::endl;

    // Release buffers
    std::cout << "5.1.13   Releasing the resources " << std::endl;
    try
    {
        while (bufferList->size() > 0)
        {
            pBuffer = bufferList->begin()->second;
            bufferList->RevokeBuffer(pBuffer);
            delete pBuffer;
        }
        std::cout << "         buffers after revoke:    " << bufferList->size() << std::endl;

        ReleaseAllResources(pSystem, pInterface, pDevice, pDataStream, pImageProcessor);
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
    }

    std::cout << std::endl;
    std::cout << "End" << std::endl << std::endl;

    std::cout << "Input any number to close the program:";
    int endKey = 0;
    std::cin >> endKey;
    return returncode;
}

//------------------------------------------------------------------------------
/* Setup the Baumer GAPI to calculate the requested polarization component from the raw
   polarized image */
void EnableSingleComponent(BGAPI2::Image* const pImage, const std::string sComponent)
{
    BGAPI2::Node* pComponentSelector = pImage->GetNode("ComponentSelector");
    BGAPI2::Node* pComponentEnable = pImage->GetNode("ComponentEnable");
    BGAPI2::NodeMap*pComponents = pComponentSelector->GetEnumNodeList();
    const bo_uint64 componentsAvailable = pComponents->GetNodeCount();
    for (bo_uint64 i = 0; i < componentsAvailable; i++) {
        pComponentSelector->SetInt(i);
        pComponentEnable->SetBool(sComponent == pComponentSelector->GetValue().get());
    }
}

//------------------------------------------------------------------------------
/* Read the polarization calibration matrix and angle of polarization offset from the camera
   used to calculated the required polarisation data in the Baumer GAPI image processor */
void SetDeviceCalibrationToImageProcessor(BGAPI2::Device* const pDevice, BGAPI2::ImageProcessor* const pImageProcessor)
{
    struct CalibrationEntry {
        const char* pSelector;
        unsigned int row;
        unsigned int col;
    };

    static const CalibrationEntry calibrationEntry[] = {
        { "Gain00", 0, 0 },
        { "Gain01", 0, 1 },
        { "Gain02", 0, 2 },
        { "Gain03", 0, 3 },
        { "Gain10", 1, 0 },
        { "Gain11", 1, 1 },
        { "Gain12", 1, 2 },
        { "Gain13", 1, 3 },
        { "Gain20", 2, 0 },
        { "Gain21", 2, 1 },
        { "Gain22", 2, 2 },
        { "Gain23", 2, 3 },
    };

    BGAPI2::NodeMap* const pDeviceMap = pDevice->GetRemoteNodeList();

    BGAPI2::Node* pDeviceCalibrationMatrixValueSelector = pDeviceMap->GetNode("CalibrationMatrixValueSelector");
    BGAPI2::Node* pDeviceCalibrationMatrixValue = pDeviceMap->GetNode("CalibrationMatrixValue");

    BGAPI2::Node* pCalibrationMatrixRowSelector = pImageProcessor->GetNode("CalibrationMatrixRowSelector");
    BGAPI2::Node* pCalibrationMatrixColSelector = pImageProcessor->GetNode("CalibrationMatrixColumnSelector");
    BGAPI2::Node* pCalibrationMatrixValue = pImageProcessor->GetNode("CalibrationMatrixValue");

    const std::streamsize precision = std::cout.precision(5);
    const std::ios_base::fmtflags flags = std::cout.flags();
    std::cout.setf(std::ios_base::fixed | std::ios_base::right);

    // Set calibration matrix from device to image processor
    for (unsigned int i = 0; i < sizeof(calibrationEntry) / sizeof(calibrationEntry[0]); i++)
    {
        pDeviceCalibrationMatrixValueSelector->SetValue(calibrationEntry[i].pSelector);
        double value = pDeviceCalibrationMatrixValue->GetDouble();

        std::cout << "      CalibrationMatrix " << calibrationEntry[i].pSelector << ": "
            << std::setw(8) << value << std::endl;

        pCalibrationMatrixRowSelector->SetInt(calibrationEntry[i].row);
        pCalibrationMatrixColSelector->SetInt(calibrationEntry[i].col);
        pCalibrationMatrixValue->SetDouble(value);
    }

    std::cout.precision(2);

    // Set angle of polarisation offset from device to image processor
    const double aopOffset = pDeviceMap->GetNode("CalibrationAngleOfPolarizationOffset")->GetDouble();
    std::cout << "      CalibrationAngleOfPolarizationOffset: " << std::setw(6) << aopOffset << std::endl << std::endl;
    pImageProcessor->GetNode("CalibrationAngleOfPolarizationOffset")->SetDouble(aopOffset);

    std::cout.precision(precision);
    std::cout.flags(flags);
}


//------------------------------------------------------------------------------
/* Get the Angle Offset from the command line parameter (if provided) and use it for the calculation */
void argumentAopOffset(const Argument& argument, const ArgumentMode mode, const char* const pParam)
{
    if (mode == eArgumentInit)
    {
        g_aopOffset = 0.0;
        g_bAopOffset = false;
    }
    else
    {
        double value = 0.0;
#if _WIN32
        if ((pParam != NULL) && (sscanf_s(pParam, "%lf", &value) == 1))
#else
        if ((pParam != NULL) && (sscanf(pParam, "%lf", &value) == 1))
#endif
        {
            g_aopOffset = value;
            g_bAopOffset = true;
        }
    }
}

//------------------------------------------------------------------------------
/* Helper to filter found cameras devices and select only polarization camera for this example */
bool PolarizationDeviceFilter(BGAPI2::Device* const pDevice)
{
    if (pDevice->GetRemoteNodeList()->GetNodePresent("ComponentSelector"))
    {
        if (pDevice->GetRemoteNode("ComponentSelector")->GetValue() == "PolarizedRaw")
        {
            return true;
        }
    }
    return false;
}

//------------------------------------------------------------------------------
int GetFirstDevice(DeviceMatch* const pMatch
    , bool(*pSystemFilter)(BGAPI2::System* pSystem)
    , bool(*pInterfaceFilter)(BGAPI2::Interface* pInterface)
    , bool(*pDeviceFilter)(BGAPI2::Device* pDevice)
    , std::ostream& log)
{
    int returncode = 0;
    log << "SYSTEM LIST" << std::endl;
    log << "###########" << std::endl << std::endl;

    try {
        BGAPI2::SystemList* pSystemList = SystemList::GetInstance();

        // Counting available systems (TL producers)
        pSystemList->Refresh();
        log << "5.1.2   Detected systems:  " << pSystemList->size() << std::endl;

        // System device information
        for (SystemList::iterator sysIterator = pSystemList->begin(); sysIterator != pSystemList->end(); sysIterator++)
        {
            BGAPI2::System* const pSystem = sysIterator->second;
            log << "  5.2.1   System Name:     " << pSystem->GetFileName() << std::endl;
            log << "          System Type:     " << pSystem->GetTLType() << std::endl;
            log << "          System Version:  " << pSystem->GetVersion() << std::endl;
            log << "          System PathName: " << pSystem->GetPathName() << std::endl << std::endl;
        }

        for (SystemList::iterator sysIterator = pSystemList->begin(); sysIterator != pSystemList->end(); sysIterator++)
        {
            log << "SYSTEM" << std::endl;
            log << "######" << std::endl << std::endl;

            BGAPI2::System* const pSystem = sysIterator->second;
            pMatch->pSystem = pSystem;
            try
            {
                pSystem->Open();
                log << "5.1.3   Open next system " << std::endl;
                log << "  5.2.1   System Name:     " << pSystem->GetFileName() << std::endl;
                log << "          System Type:     " << pSystem->GetTLType() << std::endl;
                log << "          System Version:  " << pSystem->GetVersion() << std::endl;
                log << "          System PathName: " << pSystem->GetPathName() << std::endl << std::endl;

                log << "        Opened system - NodeList Information " << std::endl;
                log << "          GenTL Version:   " << pSystem->GetNode("GenTLVersionMajor")->GetValue() << "." << pSystem->GetNode("GenTLVersionMinor")->GetValue() << std::endl << std::endl;

                const char* pCloseSystemReason = "???";
                if ((pSystemFilter != NULL) && (pSystemFilter(pSystem) == false))
                {
                    pCloseSystemReason = "skipped";
                }
                else
                {
                    log << "INTERFACE LIST" << std::endl;
                    log << "##############" << std::endl << std::endl;

                    try
                    {
                        BGAPI2::InterfaceList* pInterfaceList = pSystem->GetInterfaces();
                        // Count available interfaces
                        pInterfaceList->Refresh(100);  // timeout of 100 msec
                        log << "5.1.4   Detected interfaces: " << pInterfaceList->size() << std::endl;

                        // Interface information
                        for (InterfaceList::iterator ifIterator = pInterfaceList->begin(); ifIterator != pInterfaceList->end(); ifIterator++)
                        {
                            BGAPI2::Interface* const pInterface = ifIterator->second;
                            log << "  5.2.2   Interface ID:      " << ifIterator->first << std::endl;
                            log << "          Interface Type:    " << pInterface->GetTLType() << std::endl;
                            log << "          Interface Name:    " << pInterface->GetDisplayName() << std::endl << std::endl;
                        }

                        log << "INTERFACE" << std::endl;
                        log << "#########" << std::endl << std::endl;

                        for (InterfaceList::iterator ifIterator = pInterfaceList->begin(); ifIterator != pInterfaceList->end(); ifIterator++)
                        {
                            try
                            {
                                // Open the next interface in the list
                                BGAPI2::Interface* const pInterface = ifIterator->second;
                                pMatch->pInterface = pInterface;
                                log << "5.1.5   Open interface " << std::endl;
                                log << "  5.2.2   Interface ID:      " << ifIterator->first << std::endl;
                                log << "          Interface Type:    " << pInterface->GetTLType() << std::endl;
                                log << "          Interface Name:    " << pInterface->GetDisplayName() << std::endl;

                                pInterface->Open();

                                const char* pReason = "???";
                                if ((pInterfaceFilter != NULL) && (pInterfaceFilter(pInterface) == false))
                                {
                                    pReason = "skipped";
                                }
                                else
                                {
                                    // Search for any camera is connected to this interface
                                    BGAPI2::DeviceList* const pDeviceList = pInterface->GetDevices();
                                    pDeviceList->Refresh(100);

                                    if (pDeviceList->size() == 0)
                                    {
                                        pReason = "no camera found";
                                    }
                                    else
                                    {
                                        log << "   " << std::endl;
                                        log << "        Opened interface - NodeList Information " << std::endl;
                                        if (pInterface->GetTLType() == "GEV")
                                        {
                                            log << "          GevInterfaceSubnetIPAddress: " << pInterface->GetNode("GevInterfaceSubnetIPAddress")->GetValue() << std::endl;
                                            log << "          GevInterfaceSubnetMask:      " << pInterface->GetNode("GevInterfaceSubnetMask")->GetValue() << std::endl;
                                        }
                                        if (pInterface->GetTLType() == "U3V")
                                        {
                                            // log << "          NodeListCount:     " << pInterface->GetNodeList()->GetNodeCount() << std::endl;
                                        }

                                        // Open the first matching camera in the list
                                        try
                                        {
                                            // Counting available cameras
                                            log << "5.1.6   Detected devices:         " << pDeviceList->size() << std::endl;

                                            // Device information before opening
                                            for (DeviceList::iterator devIterator = pDeviceList->begin(); devIterator != pDeviceList->end(); devIterator++)
                                            {
                                                BGAPI2::Device* const pDevice = devIterator->second;
                                                log << "  5.2.3   Device DeviceID:        " << pDevice->GetID() << std::endl;
                                                log << "          Device Model:           " << pDevice->GetModel() << std::endl;
                                                log << "          Device SerialNumber:    " << pDevice->GetSerialNumber() << std::endl;
                                                log << "          Device Vendor:          " << pDevice->GetVendor() << std::endl;
                                                log << "          Device TLType:          " << pDevice->GetTLType() << std::endl;
                                                log << "          Device AccessStatus:    " << pDevice->GetAccessStatus() << std::endl;
                                                log << "          Device UserID:          " << pDevice->GetDisplayName() << std::endl << std::endl;
                                            }

                                            for (DeviceList::iterator devIterator = pDeviceList->begin(); devIterator != pDeviceList->end(); devIterator++)
                                            {
                                                try
                                                {
                                                    BGAPI2::Device* const pDevice = devIterator->second;
                                                    pMatch->pDevice = pDevice;

                                                    GetDeviceInfo(log, pDevice, true);

                                                    if ((pDeviceFilter == NULL) || (pDeviceFilter(pDevice) == true))
                                                    {
                                                        return returncode;
                                                    }

                                                    log << "        Close device (skipped) " << std::endl << std::endl;
                                                    pDevice->Close();
                                                    pMatch->pDevice = NULL;
                                                }
                                                catch (BGAPI2::Exceptions::ResourceInUseException& ex)
                                                {
                                                    returncode = (returncode == 0) ? 1 : returncode;
                                                    log << " Device  " << devIterator->first << " already opened " << std::endl;
                                                    log << " ResourceInUseException: " << ex.GetErrorDescription() << std::endl;
                                                }
                                                catch (BGAPI2::Exceptions::AccessDeniedException& ex)
                                                {
                                                    returncode = (returncode == 0) ? 1 : returncode;
                                                    log << " Device  " << devIterator->first << " already opened " << std::endl;
                                                    log << " AccessDeniedException " << ex.GetErrorDescription() << std::endl;
                                                }
                                            }
                                        }
                                        catch (BGAPI2::Exceptions::IException& ex)
                                        {
                                            returncode = (returncode == 0) ? 1 : returncode;
                                            log << "ExceptionType:    " << ex.GetType() << std::endl;
                                            log << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
                                            log << "in function:      " << ex.GetFunctionName() << std::endl;
                                        }

                                        pReason = "no camera match";
                                    }
                                }

                                log << "5.1.13   Close interface (" << pReason << ") " << std::endl << std::endl;
                                pInterface->Close();
                                pMatch->pInterface = NULL;
                            }
                            catch (BGAPI2::Exceptions::ResourceInUseException& ex)
                            {
                                returncode = (returncode == 0) ? 1 : returncode;
                                log << " Interface " << ifIterator->first << " already opened " << std::endl;
                                log << " ResourceInUseException: " << ex.GetErrorDescription() << std::endl;
                            }
                        }
                    }
                    catch (BGAPI2::Exceptions::IException& ex)
                    {
                        returncode = (returncode == 0) ? 1 : returncode;
                        log << "ExceptionType:    " << ex.GetType() << std::endl;
                        log << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
                        log << "in function:      " << ex.GetFunctionName() << std::endl;
                    }
                    pCloseSystemReason = "no camera match";
                }

                log << "        Close system (" << pCloseSystemReason << ") " << std::endl << std::endl;
                pSystem->Close();
                pMatch->pSystem = NULL;
            }
            catch (BGAPI2::Exceptions::ResourceInUseException& ex)
            {
                returncode = (returncode == 0) ? 1 : returncode;
                log << " System " << sysIterator->first << " already opened " << std::endl;
                log << " ResourceInUseException: " << ex.GetErrorDescription() << std::endl;
            }
        }
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        returncode = (returncode == 0) ? 1 : returncode;
        log << "ExceptionType:    " << ex.GetType() << std::endl;
        log << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        log << "in function:      " << ex.GetFunctionName() << std::endl;
    }
    return returncode;
}

//------------------------------------------------------------------------------
/* Helper to Display various information of the camera */
void GetDeviceInfo(std::ostream& log, BGAPI2::Device* const pDevice, const bool bOpen)
{
    log << "5.1.7   Open device " << std::endl;
    log << "          Device DeviceID:        " << pDevice->GetID() << std::endl;
    log << "          Device Model:           " << pDevice->GetModel() << std::endl;
    log << "          Device SerialNumber:    " << pDevice->GetSerialNumber() << std::endl;
    log << "          Device Vendor:          " << pDevice->GetVendor() << std::endl;
    log << "          Device TLType:          " << pDevice->GetTLType() << std::endl;
    log << "          Device AccessStatus:    " << pDevice->GetAccessStatus() << std::endl;
    log << "          Device UserID:          " << pDevice->GetDisplayName() << std::endl << std::endl;

    if (bOpen)
        pDevice->Open();

    log << "        Opened device - RemoteNodeList Information " << std::endl;
    log << "          Device AccessStatus:    " << pDevice->GetAccessStatus() << std::endl;

    BGAPI2::NodeMap* const pRemoteNodeList = pDevice->GetRemoteNodeList();
    // Serial number
    if (pRemoteNodeList->GetNodePresent("DeviceSerialNumber"))
        log << "          DeviceSerialNumber:     " << pRemoteNodeList->GetNode("DeviceSerialNumber")->GetValue() << std::endl;
    else if (pRemoteNodeList->GetNodePresent("DeviceID"))
        log << "          DeviceID (SN):          " << pRemoteNodeList->GetNode("DeviceID")->GetValue() << std::endl;
    else
        log << "          SerialNumber:           Not Available " << std::endl;

    // Display DeviceManufacturerInfo
    if (pRemoteNodeList->GetNodePresent("DeviceManufacturerInfo"))
        log << "          DeviceManufacturerInfo: " << pRemoteNodeList->GetNode("DeviceManufacturerInfo")->GetValue() << std::endl;

    // Display DeviceFirmwareVersion or DeviceVersion
    if (pRemoteNodeList->GetNodePresent("DeviceFirmwareVersion"))
        log << "          DeviceFirmwareVersion:  " << pRemoteNodeList->GetNode("DeviceFirmwareVersion")->GetValue() << std::endl;
    else if (pRemoteNodeList->GetNodePresent("DeviceVersion"))
        log << "          DeviceVersion:          " << pRemoteNodeList->GetNode("DeviceVersion")->GetValue() << std::endl;
    else
        log << "          DeviceVersion:          Not Available " << std::endl;

    if (pDevice->GetTLType() == "GEV") {
        log << "          GevCCP:                 " << pRemoteNodeList->GetNode("GevCCP")->GetValue() << std::endl;
        log << "          GevCurrentIPAddress:    " << pRemoteNodeList->GetNode("GevCurrentIPAddress")->GetValue() << std::endl;
        log << "          GevCurrentSubnetMask:   " << pRemoteNodeList->GetNode("GevCurrentSubnetMask")->GetValue() << std::endl;
    }

    log << std::endl;
}

//------------------------------------------------------------------------------
/* Release all allocated resources */
int ReleaseAllResources(BGAPI2::System* pSystem, BGAPI2::Interface* pInterface, BGAPI2::Device* pDevice
    , BGAPI2::DataStream* pDataStream, BGAPI2::ImageProcessor* pImageProcessor)
{
    try
    {
        if (pDataStream)
            pDataStream->Close();
        if (pImageProcessor)
        {
            delete pImageProcessor;
        }
        if (pDevice)
        {
            pDevice->Close();
        }
        if (pInterface)
        {
            pInterface->Close();
        }
        if (pSystem)
        {
            pSystem->Close();
        }
        BGAPI2::SystemList::ReleaseInstance();
    }
    catch (BGAPI2::Exceptions::IException& ex)
    {
        std::cout << "ExceptionType:    " << ex.GetType() << std::endl;
        std::cout << "ErrorDescription: " << ex.GetErrorDescription() << std::endl;
        std::cout << "in function:      " << ex.GetFunctionName() << std::endl;
        return 1;
    }
    return 0;
}


Advantages of Polarization Function

1. Reduce glare and reflections on shiny or shiny surfaces, increase contrast for better detection of defects or surface features, and enhance color differentiation.

2. They can also help improve the accuracy and speed of automated inspection and quality control processes in industries such as automotive, electronics, and manufacturing.

3. Polarized cameras are useful in outdoor applications where there is a lot of sunlight or atmospheric haze that might otherwise interfere with image clarity.


Advantages of polarized industrial cameras over ordinary industrial cameras


Polarized industrial cameras have several advantages over ordinary industrial cameras.

1. They use polarizing filters to capture light waves that vibrate in a single direction, reducing glare and reflections from shiny surfaces. This results in a clearer and more precise image, making it easier to identify defects or anomalies in highly reflective surfaces.

2. Polarized cameras also provide better contrast and color accuracy, allowing precise color measurement and analysis.

3. Polarizing cameras can be used in harsh environmental conditions and can capture images of objects that are difficult to see with ordinary cameras.


Industrial Applications of Baumer Polarization Cameras

Polarized industrial cameras are commonly used in various industrial applications such as quality control, defect inspection, material analysis, and surface inspection.

They help eliminate glare and reflections, and improve image contrast and accuracy on a variety of materials, including glass, plastic, and metal.

Polarized industrial cameras are also useful in detecting hidden defects or contaminants, identifying stress points in materials, and inspecting hidden structures. They are commonly used in industries such as automotive, aerospace, electronics and manufacturing.

The following is a brief introduction to several industry applications that can reflect polarization characteristics :

  

  

  


Guess you like

Origin blog.csdn.net/xianzuzhicai/article/details/130436899