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

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

项目场景:

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


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


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


技术背景

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


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


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


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

33.png

22.png

11.png

代码分析

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为偏振工业相机。

1691646837090.png

该示例描述了如何使用所提供的堡盟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偏振相机的行业应用

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


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


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


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

7.png

6.png

5.png

目录
相关文章
|
1月前
|
存储 安全 物联网
C# 在物联网 (IoT) 应用中的应用
本文介绍了C#在物联网(IoT)应用中的应用,涵盖基础概念、优势、常见问题及其解决方法。重点讨论了网络通信、数据处理和安全问题,并提供了相应的代码示例,旨在帮助开发者更好地利用C#进行IoT开发。
58 3
|
1月前
|
开发框架 C# iOS开发
基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform
基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform
|
1月前
|
传感器 IDE 测试技术
C#一分钟浅谈:Visual Studio IDE 高级功能
【10月更文挑战第24天】本文从初学者角度介绍了 Visual Studio 的高级功能,包括安装与配置、创建项目、运行与调试、常见问题及解决方案(如代码格式化、重构、导航、单元测试、代码分析),以及智能感知、Live Unit Testing、代码生成和代码片段等高级功能,帮助开发者提高效率和代码质量。
48 1
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
38 3
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
63 1
|
1月前
|
网络协议 Unix Linux
精选2款C#/.NET开源且功能强大的网络通信框架
精选2款C#/.NET开源且功能强大的网络通信框架
|
2月前
|
开发框架 Cloud Native .NET
10 个 C# 关键字和功能
10 个 C# 关键字和功能
63 8
|
1月前
|
编译器 C#
c# - 运算符<<不能应用于long和long类型的操作数
在C#中,左移运算符的第二个操作数必须是 `int`类型,因此需要将 `long`类型的位移计数显式转换为 `int`类型。这种转换需要注意数据丢失和负值处理的问题。通过本文的详细说明和示例代码,相信可以帮助你在实际开发中正确使用左移运算符。
18 0
|
2月前
|
消息中间件 网络协议 安全
C# 一分钟浅谈:WebSocket 协议应用
【10月更文挑战第6天】在过去的一年中,我参与了一个基于 WebSocket 的实时通信系统项目,该项目不仅提升了工作效率,还改善了用户体验。本文将分享在 C# 中应用 WebSocket 协议的经验和心得,包括基础概念、C# 实现示例、常见问题及解决方案等内容,希望能为广大开发者提供参考。
165 0
|
2月前
|
物联网 C#
【C#】简单的蓝牙通讯功能实现
【C#】简单的蓝牙通讯功能实现
61 0