Baumer工业相机堡盟相机如何使用PixelTransformation像素转换功能(像素转换功能的使用和优点以及行业应用)(C++)

简介: Baumer工业相机堡盟相机如何使用PixelTransformation像素转换功能(像素转换功能的使用和优点以及行业应用)(C++)

项目场景

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


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


Baumer工业相机堡盟相机中PixelTransformation功能由BGAPI SDK提供的ImageProcesser函数进行转换的,以方便各种场合所需要的不同格式图像。


技术背景

工业相机SDK开发工具包中的像素转换功能通常用于将来自相机传感器的数据转换成可由计算机处理的格式。该功能将原始像素数据(通常表示为一系列数字)转换为可在计算机屏幕上显示或用于进一步分析和处理的图像。


这个功能的具体细节取决于具体的SDK和正在使用的相机,可能有所不同。不过,一般来说,像素转换功能会考虑到相机传感器的颜色深度、用于传输数据的任何压缩或编码,以及可能影响原始像素数据表示方式的任何其他因素。


总的来说,像素转换功能是任何工业相机SDK开发工具包的一个重要组成部分,因为它允许用户以对广泛的应用有用和实用的方式处理相机产生的数据。


工业相机从环境中捕捉图像并将其转换为数字数据。像素转换功能是在模拟信号转换为数字信号的过程中发生的,其中每个像素的特征被修改,以优化所产生的图像的质量。


在mono8和mono12像素格式的情况下,该数字表示每个像素的比特深度。单8相机捕获的灰度图像有256级亮度,而单12相机捕获的灰度图像有4096级亮度。


在转换过程中,像素值根据各种算法进行转换,包括伽玛校正、色彩校正和数字增益,以确保图像准确地表现所拍摄的场景。例如,伽马校正,调整每个像素的亮度值,以补偿相机响应的非线性。


CameraExplorer使用像素转换功能

22.png


Baumer BGAPI SDK使用像素转换功能

Baumer工业相机堡盟相机SDK示例中005_PixelTransformation.cpp详细介绍了如何配置像素转换功能。


软件SDK示例地址如下所示:Baumer_GAPI_SDK_2.12.0_win_x86_64_cpp\examples\src\0_Common\005_PixelTransformation\005_PixelTransformation.cpp


11.png


下面代码Demo演示如何通过相机SDK中的Buffer转换Mono8和彩色像素转换为BGR8。


如下所示为C++的部分核心代码:

SystemList 
Open a System 
Get the InterfaceList and fill it Open an Interface 
Get the DeviceList and fill it 
Open a Device 
// CAPTURE 8 IMAGES
std::cout << " " << std::endl;
std::cout << "CAPTURE & TRANSFORM 4 IMAGES" << std::endl;
std::cout << "############################" << std::endl << std::endl;
BGAPI2::Buffer * pBufferFilled = NULL;
try {
    BGAPI2::Image* pImage = imgProcessor->CreateImage();
    BGAPI2::Node* pPixelFormatInfoSelector = imgProcessor->GetNode("PixelFormatInfoSelector");
    BGAPI2::Node* pBytesPerPixel = imgProcessor->GetNode("BytesPerPixel");
    for (int i = 0; i < 4; i++) {
        pBufferFilled = pDataStream->GetFilledBuffer(1000);  // timeout 1000 msec
        if (pBufferFilled == NULL) {
            std::cout << "Error: Buffer Timeout after 1000 msec" << std::endl << std::endl;
        } else if (pBufferFilled->GetIsIncomplete() == true) {
            std::cout << "Error: Image is incomplete" << std::endl << std::endl;
            // queue buffer again
            pBufferFilled->QueueBuffer();
        } else {
            std::cout << " Image " << std::setw(5) << pBufferFilled->GetFrameID()
                << " received in memory address " << std::hex << pBufferFilled->GetMemPtr()
                << std::dec << std::endl;
            // create an image object from the filled buffer and convert it
            BGAPI2::Image * pTransformImage = NULL;
            pImage->Init(pBufferFilled);
            BGAPI2::String sPixelFormat = pImage->GetPixelformat();
            std::cout << "  pImage.Pixelformat:             "
                << pImage->GetPixelformat() << std::endl;
            std::cout << "  pImage.Width:                   "
                << pImage->GetWidth() << std::endl;
            std::cout << "  pImage.Height:                  "
                << pImage->GetHeight() << std::endl;
            std::cout << "  pImage.Buffer:                  "
                << std::hex << pImage->GetBuffer() << std::dec << std::endl;
            pPixelFormatInfoSelector->SetValue(sPixelFormat);
            double fBytesPerPixel = pBytesPerPixel->GetAvailable() ? pBytesPerPixel->GetDouble() : 0.0;
            std::cout << "  Bytes per image:                "
                << static_cast<unsigned int>((pImage->GetWidth())*(pImage->GetHeight())*fBytesPerPixel)
                << std::endl;
            std::cout << "  Bytes per pixel:                "
                << fBytesPerPixel << std::endl;
            // display first 6 pixel values of first 6 lines of the image
            // ========================================================================
            unsigned char* imageBuffer = (unsigned char *)pImage->GetBuffer();
            std::cout << "  Address" << std::endl;
            // set display for uppercase hex numbers filled with '0'
            std::cout << std::uppercase << std::setfill('0') << std::hex;
            for (int j = 0; j < 6; j++) {  // first 6 lines
                void* imageBufferAddress = &imageBuffer[static_cast<int>(pImage->GetWidth()*j*fBytesPerPixel)];
                std::cout << "  " << std::setw(8) << imageBufferAddress << " ";
                for (int k = 0; k < static_cast<int>(6 * fBytesPerPixel); k++) {  // bytes of first 6 pixels
                    std::cout << " " << std::setw(2)
                        << static_cast<int>(imageBuffer[static_cast<int>(pImage->GetWidth()*j*fBytesPerPixel)+k]);
                }
                std::cout << "  ..." << std::endl;
            }
            // set display for lowercase dec numbers filled with ' '
            std::cout << std::nouppercase << std::setfill(' ') << std::dec;
            // if pixel format starts with "Mono"
            if (std::string(pImage->GetPixelformat()).substr(0, 4) == "Mono") {
                // transform to Mono8
                pTransformImage = imgProcessor->CreateTransformedImage(pImage, "Mono8");
                std::cout << " Image "
                    << std::setw(5) << pBufferFilled->GetFrameID() << " transformed to Mono8" << std::endl;
                std::cout << "  pTransformImage.Pixelformat:    "
                    << pTransformImage->GetPixelformat() << std::endl;
                std::cout << "  pTransformImage.Width:          "
                    << pTransformImage->GetWidth() << std::endl;
                std::cout << "  pTransformImage.Height:         "
                    << pTransformImage->GetHeight() << std::endl;
                std::cout << "  pTransformImage.Buffer:         "
                    << std::hex << pTransformImage->GetBuffer() << std::dec << std::endl;
                std::cout << "  Bytes per image:                "
                    << pTransformImage->GetWidth() * pTransformImage->GetHeight() * 1 << std::endl;
                std::cout << "  Bytes per pixel:                "
                    << 1.0 << std::endl;
                unsigned char* transformBuffer = (unsigned char *)pTransformImage->GetBuffer();
                // display first 6 pixel values of first 6 lines of the transformed image
                // ========================================================================
                std::cout << "  Address    Y  Y  Y  Y  Y  Y " << std::endl;
                // set display for uppercase hex numbers filled with '0'
                std::cout << std::uppercase << std::setfill('0') << std::hex;
                for (int j = 0; j < 6; j++) {  // first 6 lines
                    void* transformBufferAddress = &transformBuffer[pTransformImage->GetWidth() * 1 * j];
                    std::cout << "  " << std::setw(8) << std::setfill('0')
                        << std::hex << transformBufferAddress << " ";
                    for (int k = 0; k < 6; k++) {  // first 6 Pixel with Mono8 (1 Byte per Pixel)
                        // value of pixel
                        std::cout << " " << std::setw(2)
                            << static_cast<int>(transformBuffer[pTransformImage->GetWidth()*j + k]);
                    }
                    std::cout << " ..." << std::endl;
                }
                // set display for lowercase dec numbers filled with ' '
                std::cout << std::nouppercase << std::setfill(' ') << std::dec;
                std::cout << " " << std::endl;
            } else {  // if color format
                // transform to BGR8
                pTransformImage = imgProcessor->CreateTransformedImage(pImage, "BGR8");
                std::cout << " Image "
                    << std::setw(5) << pBufferFilled->GetFrameID() << " transformed to BGR8" << std::endl;
                std::cout << "  pTransformImage.Pixelformat:    "
                    << pTransformImage->GetPixelformat() << std::endl;
                std::cout << "  pTransformImage.Width:          "
                    << pTransformImage->GetWidth() << std::endl;
                std::cout << "  pTransformImage.Height:         "
                    << pTransformImage->GetHeight() << std::endl;
                std::cout << "  pTransformImage.Buffer:         "
                    << std::hex << pTransformImage->GetBuffer() << std::dec << std::endl;
                std::cout << "  Bytes per image:                "
                    << pTransformImage->GetWidth() * pTransformImage->GetHeight() * 3 << std::endl;
                std::cout << "  Bytes per pixel:                "
                    << 3.0 << std::endl;
                unsigned char* transformBuffer = (unsigned char *)pTransformImage->GetBuffer();
                // display first 6 pixel values of first 6 lines of the transformed image
                // ========================================================================
                std::cout << "  Address    B  G  R  B  G  R  B  G  R  B  G  R  B  G  R  B  G  R" << std::endl;
                // set display for uppercase hex numbers filled with '0'
                std::cout << std::uppercase << std::setfill('0') << std::hex;
                for (int j = 0; j < 6; j++) {  // 6 lines
                    void* transformBufferAddress = &transformBuffer[pTransformImage->GetWidth() * 3 * j];
                    std::cout << "  " << std::setw(8) << std::setfill('0')
                        << std::hex << transformBufferAddress << " ";
                    for (int k = 0; k < 6; k++) {  // first 6 Pixel with BGR8 (3 Bytes per Pixel)
                        // Value of Blue pixel
                        std::cout << " " << std::setw(2)
                            << static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 0]);
                        // Value of Green pixel
                        std::cout << " " << std::setw(2)
                            << static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 1]);
                        // Value of Red pixel
                        std::cout << " " << std::setw(2)
                            << static_cast<int>(transformBuffer[pTransformImage->GetWidth() * 3 * j + k * 3 + 2]);
                    }
                    std::cout << " ..." << std::endl;
                }
                // set display for lowercase dec numbers filled with ' '
                std::cout << std::nouppercase << std::setfill(' ') << std::dec;
                std::cout << " " << std::endl;
            }
            pTransformImage->Release();
            // delete [] transformBuffer;
            // QUEUE BUFFER AFTER USE
            pBufferFilled->QueueBuffer();
        }
    }
    if (pImage != NULL) {
        pImage->Release();
        pImage = NULL;
    }
}
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 STOP" << std::endl;
std::cout << "###########" << std::endl << std::endl;

图像转换的优势

工业相机的像素变换功能有几个优点,例如。


1. 提高图像质量。像素变换有助于纠正图像的失真和非线性,从而使图像更清晰、明确。


2. 提高准确性和精确性。通过纠正图像的失真和非线性,像素变换有助于提高测量和分析的准确性和精确度。


3. 不同相机之间的一致性。像素变换可用于校准不同的相机,以产生一致和准确的结果。


4.  提高效率。通过校正失真和非线性,像素转换消除了对额外的后处理步骤的需要,节省了时间和精力。


5. 更大的灵活性。像素转换可以定制,以适应特定的应用,使图像采集和分析更加灵活。


图像转换的行业应用

工业相机的像素转换功能可用于各种场景,如。


1. 图像校正。像素变换功能可用于纠正图像失真和其他由相机镜头引起的缺陷,如色差、晕影和透视变形。


2. 色彩校正。该功能可用于调整图像的色彩平衡、饱和度和其他与色彩有关的参数。


3. 图像增强。该功能可用于增强图像的对比度、锐度和其他视觉特征,以提高图像的质量。


4. 图像处理。该功能可用于转换图像格式或数据类型,调整图像大小,裁剪图像,或应用其他图像处理技术。


5. 机器视觉。该函数可用于预处理图像数据,然后再将其输入计算机视觉算法,用于物体检测、识别、跟踪或其他机器视觉任务。


总的来说,像素变换函数在图像处理和分析中起着至关重要的作用,它在制造业、机器人、汽车、医疗和其他行业的应用非常广泛。

目录
相关文章
|
9天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
38 12
|
1月前
|
编译器 数据安全/隐私保护 C++
【C++面向对象——继承与派生】派生类的应用(头歌实践教学平台习题)【合集】
本实验旨在学习类的继承关系、不同继承方式下的访问控制及利用虚基类解决二义性问题。主要内容包括: 1. **类的继承关系基础概念**:介绍继承的定义及声明派生类的语法。 2. **不同继承方式下对基类成员的访问控制**:详细说明`public`、`private`和`protected`继承方式对基类成员的访问权限影响。 3. **利用虚基类解决二义性问题**:解释多继承中可能出现的二义性及其解决方案——虚基类。 实验任务要求从`people`类派生出`student`、`teacher`、`graduate`和`TA`类,添加特定属性并测试这些类的功能。最终通过创建教师和助教实例,验证代码
57 5
|
4月前
|
存储 并行计算 安全
C++多线程应用
【10月更文挑战第29天】C++ 中的多线程应用广泛,常见场景包括并行计算、网络编程中的并发服务器和图形用户界面(GUI)应用。通过多线程可以显著提升计算速度和响应能力。示例代码展示了如何使用 `pthread` 库创建和管理线程。注意事项包括数据同步与互斥、线程间通信和线程安全的类设计,以确保程序的正确性和稳定性。
|
4月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
109 2
|
5月前
|
编译器 C++
【C++核心】函数的应用和提高详解
这篇文章详细讲解了C++函数的定义、调用、值传递、常见样式、声明、分文件编写以及函数提高的内容,包括函数默认参数、占位参数、重载等高级用法。
47 3
|
9天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
11天前
|
编译器 C语言 C++
类和对象的简述(c++篇)
类和对象的简述(c++篇)
|
9天前
|
安全 编译器 C语言
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
|
9天前
|
存储 程序员 C语言
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
|
1月前
|
C++ 芯片
【C++面向对象——类与对象】Computer类(头歌实践教学平台习题)【合集】
声明一个简单的Computer类,含有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等等,以及两个公有成员函数run、stop。只能在类的内部访问。这是一种数据隐藏的机制,用于保护类的数据不被外部随意修改。根据提示,在右侧编辑器补充代码,平台会对你编写的代码进行测试。成员可以在派生类(继承该类的子类)中访问。成员,在类的外部不能直接访问。可以在类的外部直接访问。为了完成本关任务,你需要掌握。
71 19