Baumer工业相机堡盟相机如何使用JPEG图像压缩功能(LXT.JP系列相机图像压缩功能的使用和优点以及行业应用)(C++)

简介: Baumer工业相机堡盟相机如何使用JPEG图像压缩功能(LXT.JP系列相机图像压缩功能的使用和优点以及行业应用)(C++)

项目场景

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


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


Baumer万兆网相机中LXT.JP图像压缩系列相机是一种预处理相机,在相机内部对图像进行JPEG算法压缩然后再传输到处理器中。


技术背景

工业相机的JPEG图像压缩功能有助于减少图像文件的大小,同时保持图像质量。这种压缩功能是基于JPEG(联合摄影专家组)压缩标准,该标准被广泛用于数字摄影和图像编辑。


具有JPEG压缩功能的工业相机可以捕捉高分辨率的图像,并将其压缩成较小的文件,从而使图像的存储、传输和处理更加容易。压缩水平和质量可以根据用户的具体需求进行调整。


在工业相机中使用JPEG压缩的一个优点是,它可以帮助减少数据传输时间,这在需要高速图像处理的机器视觉应用中特别重要。此外,较小的文件大小允许更有效地存储和检索图像,这在工业环境中可以节省时间和金钱。


总的来说,JPEG图像压缩功能是工业相机的一个重要功能,有助于提高高分辨率图像的效率、存储和处理。

4.png

3.png

代码分析

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


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


2.png


本例描述了对堡盟JPEG相机的处理。给出的源代码适用于处理一个系统、一台相机和十幅图像。


代码整体结构相对简单,在相机初始化后进行工业相机的JPEG图像压缩功能使用,部分核心代码如下:

std::cout << "DEVICE PARAMETER SETUP" << std::endl;
std::cout << "######################" << std::endl << std::endl;
try {
    // SET TRIGGER MODE OFF (FreeRun)
    pDevice->GetRemoteNode("TriggerMode")->SetString("Off");
    std::cout << "         TriggerMode:             "
        << pDevice->GetRemoteNode("TriggerMode")->GetValue() << std::endl;
    // JPEGTAG01 (see description on top)
    // check for JPEG capable camera
    if (pDevice->GetRemoteNodeList()->GetNodePresent(kImageCompressionMode.c_str())) {
        BGAPI2::NodeMap* image_compression_map =
            pDevice->GetRemoteNode(kImageCompressionMode.c_str())->GetEnumNodeList();
        if (image_compression_map->GetNodePresent(kImageCompressionModeJPEG.c_str())) {
            jpeg_streaming_capable = true;
            std::cout << "         JPEG Supported:          Yes" << std::endl;
        } else {
            std::cout << "         JPEG Supported:          No, Feature '" <<
                kImageCompressionMode << "' has no element " <<
                kImageCompressionModeJPEG <<
                std::endl;
        }
    } else {
        std::cout << "         JPEG Supported:          No Feature '" <<
            kImageCompressionMode << "' not found." <<
            std::endl;
    }
    if (jpeg_streaming_capable) {
        // JPEGTAG02 (see description on top)
        // AND SET PIXELFORMAT (Mono8, YCbCr) IF AVAILABLE
        BGAPI2::NodeMap * pixel_format_enum_map = pDevice->GetRemoteNode("PixelFormat")->GetEnumNodeList();
        std::string pixel_format = "YCbCr422_8";
        if (!pixel_format_enum_map->GetNodePresent(pixel_format.c_str()) || 
            (pixel_format_enum_map->GetNodePresent(pixel_format.c_str()) && !pixel_format_enum_map->GetNode(pixel_format.c_str())->IsReadable())) {
            pixel_format = "Mono8";
            if (!pixel_format_enum_map->GetNodePresent(pixel_format.c_str()) ||
                (pixel_format_enum_map->GetNodePresent(pixel_format.c_str()) && !pixel_format_enum_map->GetNode(pixel_format.c_str())->IsReadable())) {
                pixel_format = "";
            }
        }
        if(!pixel_format.empty() && pDevice->GetRemoteNode("PixelFormat")->IsWriteable()) {
            pDevice->GetRemoteNode("PixelFormat")->SetString(pixel_format.c_str());
            std::cout << "         PixelFormat:             "
                << pDevice->GetRemoteNode("PixelFormat")->GetValue() << std::endl;
            // JPEGTAG03 (see description on top)
            // set the compression mode to JPEG
            pDevice->GetRemoteNode(kImageCompressionMode.c_str())->SetValue("JPEG");
        } else {
            std::cout << "         PixelFormat:             "
                << pDevice->GetRemoteNode("PixelFormat")->GetValue() << " (set to Mono8/YCbCr failed, not supported or no write accees)" << 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;
}

下面功能为开启了JPEG图像压缩功能后,如何进行图像保存的功能方法,核心代码如下:

// CAPTURE 12 IMAGES
std::cout << " " << std::endl;
std::cout << "CAPTURE " << num_to_capture << " IMAGES BY IMAGE POLLING" << std::endl;
std::cout << "##################################" << std::endl << std::endl;
BGAPI2::Buffer * pBufferFilled = NULL;
try {
    // capture num_to_capture images
    for (unsigned int i = 0; i < num_to_capture; i++) {
        pBufferFilled = pDataStream->GetFilledBuffer(1000);  // timeout 1000 msec
        if (pBufferFilled == NULL) {
            std::cout << "Error: Buffer Timeout after 1000 msec" << std::endl;
        } else if (pBufferFilled->GetIsIncomplete() == true) {
            std::cout << "Error: Image is incomplete" << std::endl;
            pBufferFilled->QueueBuffer();
        } else {
            std::cout << " Image " << std::setw(5) << pBufferFilled->GetFrameID()
                << " received in memory address "
                << std::hex << pBufferFilled->GetMemPtr() << std::dec << std::endl;
            // JPEGTAG05 (see description on top)
            // save the compressed images to disk if supported
            if (jpeg_streaming_capable) {
                std::string jpeg_file = "022_JPEGCapture_";
                std::stringstream jpeg_filename;
                size_t jpeg_start_offset = pBufferFilled->GetImageOffset();
                size_t jpeg_end_offset = jpeg_start_offset + pBufferFilled->GetImageLength();
                if (jpeg_end_offset != 0) {
                    jpeg_filename.str("");
                    jpeg_filename << jpeg_file << std::setw(6) << std::setfill('0')
                        << pBufferFilled->GetFrameID() << ".jpg";
                    std::ofstream outfile;
                    outfile.open(jpeg_filename.str().c_str(), std::ios_base::binary);
                    outfile.write(
                        reinterpret_cast<const char*>(pBufferFilled->GetMemPtr()) + jpeg_start_offset,
                        jpeg_end_offset - jpeg_start_offset);
                    std::cout << "JPEG Data found. Image saved as JPEG file." << std::endl;
                } else {
                    std::cout << "JPEG Data not found in image buffer. No JPEG Saved." << std::endl;
                }
            }
            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;
std::cout << "CAMERA STOP" << std::endl;
std::cout << "###########" << std::endl << std::endl;

JPEG图像压缩功能的优势

1.JPEG

在好的压缩比下能够得到高质量的图片(例如 1:10)

被广泛接受的标准格式,通过MJPEG压缩得到AVI 视频成为可能

2.使处理过程变的简单

不PC软件压缩相比,降低了CPU的负载

在一台PC上可使用多台JPEG相机,有效降低成本

3.传输需要更低的带宽

在更低带宽接口上确保高分辨率和高速的数据传输

通过使用交换机支持远距离传输,有效降低成本

4.存档所需的存储空间更小

更长的存储时间,更低的存储介质成本

5.自由度更高,灵活性得以发挥

对应不同应用的需求更具有灵活性和自由度


JPEG图像压缩功能的行业应用


工业相机的JPEG图像压缩功能可广泛用于许多行业应用,如。


1. 监视。JPEG压缩功能可以为视频监控系统有效地存储和传输高质量的图像。


2. 医学成像。医疗成像系统经常使用 JPEG 压缩来存储和传输医疗图像。


3. 工业检查。工业检查系统可以使用 JPEG 压缩来存储生产过程中的缺陷或异常的图像。


4. 农业。在农业应用中,JPEG压缩可以被用来捕获和存储农作物和牲畜的图像。


5. 运输。在运输系统中,JPEG压缩可以用来存储和传输由放置在车辆上的摄像机所拍摄的图像,以保证安全和安保。


总的来说,JPEG图像压缩功能在许多工业应用中是一个必不可少的功能,因为它可以有效地存储和传输高质量的图像,提高生产力和减少运营成本。

目录
打赏
0
0
0
0
9
分享
相关文章
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Force IP强制修改网口IP功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK使用Force IP强制修改网口IP功能(C++)
88 0
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
根据相机旋转矩阵求解三个轴的旋转角/欧拉角/姿态角 或 旋转矩阵与欧拉角(Euler Angles)之间的相互转换,以及python和C++代码实现
640 0
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C++)
117 0
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
48 16
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。
类和对象(上)(C++)
本篇内容主要讲解了C++中类的相关知识,包括类的定义、实例化及this指针的作用。详细说明了类的定义格式、成员函数默认为inline、访问限定符(public、protected、private)的使用规则,以及class与struct的区别。同时分析了类实例化的概念,对象大小的计算规则和内存对齐原则。最后介绍了this指针的工作机制,解释了成员函数如何通过隐含的this指针区分不同对象的数据。这些知识点帮助我们更好地理解C++中类的封装性和对象的实现原理。
|
1月前
|
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
105 6
类和对象(下)C++
本内容主要讲解C++中的初始化列表、类型转换、静态成员、友元、内部类、匿名对象及对象拷贝时的编译器优化。初始化列表用于成员变量定义初始化,尤其对引用、const及无默认构造函数的类类型变量至关重要。类型转换中,`explicit`可禁用隐式转换。静态成员属类而非对象,受访问限定符约束。内部类是独立类,可增强封装性。匿名对象生命周期短,常用于临时场景。编译器会优化对象拷贝以提高效率。最后,鼓励大家通过重复练习提升技能!
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等