当前位置: 首页 > article >正文

Baumer工业相机堡盟相机如何使用偏振功能(偏振相机优点和行业应用)(C#)

 项目场景:

Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。  

Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易于集成以及高度可扩展性等特点。  

Baumer相机系列中偏振相机的特殊功能有助于在一些特殊应用场合使用。


技术背景

偏光工业相机相机旨在捕捉偏光,以提高图像质量,减少各种工业应用中的眩光。

这些相机的镜头中集成了偏振滤光片,可以帮助改善图像对比度,提高色彩饱和度,并减少闪亮表面的反射。

偏光工业相机的一些关键特征可能包括高分辨率、快速帧率、适用于工业环境的坚固设计,以及与不同照明条件的兼容性。

此外,它们可能具有触发、曝光控制和图像处理能力等功能,有助于为检查和分析目的捕获清晰和详细的图像。

  

  


代码分析

Baumer工业相机堡盟相机SDK示例中020_Polarized.cpp详细介绍了如何配置相机偏振功能。

软件SDK示例地址如下所示:Baumer_GAPI_SDK_2.9.2_win_x86_64_cpp\examples\src\0_Common\020_Polarized_SinglePart\020_Polarized_SinglePart.cpp

Baumer工业相机系列中VCXU-50MP和VCXG-50MP为偏振工业相机。 

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

该示例描述了如何使用所提供的堡盟GAPI API功能来配置相机并计算所需的偏振数据(AOL、DOP、ADOLP、Intensity)

下面的例子描述了如何从VCXU-50MP 和 VCXG-50MP 获得偏振数据。

描述了所有如何使用提供的 Baumer GAPI API 功能来配置相机和计算所需的偏振数据(AOL,DOP,ADOLP,亮度)如果需要多于一种可用的偏振数据格式,使用多部分图像进行计算会更有效。

这在示例021 _ Polalization _ MultiPart 中进行了描述

代码整体结构相对简单,在相机初始化后进行相机的偏振功能使用,下面主要描述部分核心代码如下: 

/*
    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;
}


偏振功能的优点

1、减少闪亮或光亮表面的眩光和反射,提高对比度以更好地检测缺陷或表面特征,并加强颜色区分。

2、它们还可以帮助提高汽车、电子和制造业等行业的自动检测和质量控制过程的准确性和速度。

3、偏振照相机在户外应用中很有用,因为那里有大量的阳光或大气雾霾,否则可能会干扰图像的清晰度。


偏振工业相机相对于普通工业相机的优势


偏光工业相机与普通工业相机相比有几个优点。

1、它们使用偏振滤光片来捕捉在单一方向上振动的光波,减少眩光和闪亮表面的反射。这导致了更清晰和更精确的图像,使其更容易识别高反射表面的缺陷或异常情况。

2、偏光相机还提供更好的对比度和颜色精度,允许精确的颜色测量和分析。

3、偏光相机可以在恶劣的环境条件下使用,并能捕捉到普通相机难以看到的物体的图像。


Baumer偏振相机的行业应用

偏光工业相机通常用于各种工业应用,如质量控制、缺陷检查、材料分析和表面检查。

它们有助于消除眩光和反射,提高玻璃、塑料、金属等各种材料的图像对比度和准确性。

偏光工业相机在检测隐藏的缺陷或污染物、识别材料中的应力点和检查隐藏结构方面也很有用。它们通常用于汽车、航空航天、电子和制造业等行业。

下面简单介绍几个能体现出偏振特性的行业应用:

  

  

  



http://www.kler.cn/a/16720.html

相关文章:

  • 飞牛云fnOS本地部署WordPress个人网站并一键发布公网远程访问
  • Redo与Undo的区别:数据库事务的恢复与撤销机制
  • 【数学二】线性代数-线性方程组-齐次线性方程组、非齐次线性方程组
  • 如何在python中模拟重载初始化函数?
  • SQL面试题——奔驰SQL面试题 车辆在不同驾驶模式下的时间
  • 学习记录:js算法(九十二):克隆图
  • MySQL数据库中,在读已提交和可重复读这两个不同事务隔离级别下幻读的区别
  • 来CSDN两年了,一些小感想
  • 第十八章 协程
  • Vue父组件生命周期和子组件生命周期触发顺序
  • Reactive响应式编程系列:解密reactor-netty如何实现响应式
  • Java 基础入门篇(一)—— Java 概述
  • CF1060E Sergey and Subway
  • 并发编程之Atomic原子操作类
  • 【华为OD机试真题】计算网络信号 (javaC++python)100%通过率 超详细代码注释
  • 【计算机视觉】ViT:代码逐行解读
  • linux入门---软硬链接
  • 支持轴体热插拔的平价机械键盘,全尺寸带灯效,雷柏V700DIY上手
  • linux 设置开机启动不同方式
  • Linux系统中查看日志的命令
  • CentOS软件那么老为什么大家还要用它?
  • 为什么在马云成功前就有那么多影像留下来?
  • SpringBoot调取OpenAi接口实现ChatGpt功能
  • rac部署前配置互信
  • CUDA编程(六):代码分析与调试
  • 死信队列