跳转到内容

iolibrt#

librt 库提供了用于加载和存储常用图像格式的功能。在 Windows 上,该库还允许从视频文件中加载图像序列,或将图像序列保存到 .avi 视频文件中。

要使用该库,应将包含文件 sisoIo.h 添加到源代码中。

#include <sisoIo.h>

此外, iolibrt.lib 应添加到您的 Microsoft Visual Studio 项目中,或者 libiolibrt.so 到您的 Linux 项目中。如果您使用 CMake,包名称为 SisoIoLib,库存储在变量 ${SISOIOLIB_LIBRARIES} 中,包含目录存储在变量 ${SISOIOLIB_INCLUDE_DIR}。请参见 前提条件 了解有关项目以及如何使用 CMake 的更多详细信息。

iolibrt 中的错误处理#

API 的大多数函数都会返回一个 int 结果代码。如果函数调用执行成功,返回值为 0,或者对于某些函数,返回值大于或等于零。在大多数情况下,负值表示出现错误条件。错误代码定义在头文件中 sisoIoFileErrorCodes.h 用于与读取和写入文件相关的通用错误,以及 sisoIoBmpErrorCodes.h, sisoIoRawErrorCodes.h 和 sisoIoTiffErrorCodes.h 用于与特定文件格式相关的错误。

本文档其余部分的代码示例将不包含错误处理,因为这取决于应用程序的具体要求。不过,在可行的情况下,仍会检查返回码以确保函数成功执行。

处理图像文件#

图像输入/输出库支持两种标准图像文件格式: Windows 位图 ( .bmp ) 和标记图像文件格式 ( .tif或.tiff )。此外,还支持一种带有最小文件头的原始数据文件格式( .raw ),用于存储无法用标准文件格式表示的数据。.raw 文件的文件头按以下顺序包含以下信息:

  1. 4 个字节,描述图像宽度
  2. 4 个字节,描述图像高度
  3. 4 个字节,用于描述每个 Pixel Format 的位数。例如:8 位灰度 = 8;14 位灰度 = 14;10 位 rgb = 30
  4. 4 个字节,用于描述每个 Pixel Format 的字节数;每个 Pixel Format 的字节数向上取整,例如 10 位 = 2 个字节
  5. 原始数据

本章中的函数将根据文件名中的文件扩展名来确定文件格式。

打开图像文件#

int IoImageOpen(
    const char * file,
    SisoIoImageEngine ** handle);

int IoImageOpenEx(
    const char * file,
    SisoIoImageEngine ** handle,
    int rgbSequence);

int IoFreeImage(
    SisoIoImageEngine * handle);
int IoGetWidth(
    const SisoIoImageEngine * handle);

int IoGetHeight(
    const SisoIoImageEngine * handle);

int IoGetBitsPerPixel(
    const SisoIoImageEngine * handle);

int IoGetBitsPerComponent(
    const SisoIoImageEngine * handle) ;

int IoGetNrOfComponents(
    const SisoIoImageEngine * handle);

const void * IoImageGetData(
    const SisoIoImageEngine * handle);
size_t IoCalculateBufferSize(
    int width,
    int height,
    int bitsPerPixel);

要打开图像文件,可以调用 IoImageOpen() 或 IoImageOpenEx() 函数。这两个函数都期望在第一个参数中传入文件名,并在第二个参数中传入一个指向 SisoIoImageEngine * 类型变量的指针,该变量将在后续函数中用于访问图像数据。函数 IoImageOpenEx() 可用于处理红色、绿色和蓝色数据顺序颠倒的图像,只需将参数 rgbSequence 设为 1。

当不再需要某幅图像后,应调用函数 IoFreeImage() 来释放该图像数据的 Memory。

要获取图像数据的尺寸和数据格式,可以调用函数 IoGetWidth(), IoGetHeight(), IoGetBitsPerPixel(), IoGetBitsPerComponent() 和 IoGetNrOfComponents() 函数可以被调用。

可以通过调用函数来访问图像数据 IoImageGetData() 该函数将返回一个指向包含图像数据的缓冲区的指针。要获取缓冲区的大小,可以调用函数 IoCalculateBufferSize() 。

图像数据通常分为多行。图像的高度即为构成图像数据的行数。每行由多个像素组成,图像的宽度即为一行中的像素数。每个像素由一个或多个颜色分量表示。灰度图像通常每个像素只有一个分量,即灰度值。彩色图像通常包含三个分量,分别对应红色、绿色和蓝色值。附加分量可能是透明度值,或者是红外或 X 射线分量。这些分量通常使用相同数量的位数进行编码。分量数量和每个 Pixel Format 的位数统称为 Pixel Format。(有时,会使用每个分量的位数来代替每个 Pixel Format 的位数。)

根据 Pixel Format 的不同,每行末尾可能包含一些填充字节,以确保每行的第一个像素从定义的对齐方式开始。函数 IoCalculateBufferSize() 假定行总是从字节边界开始,因此对于每个 Pixel Format 不使用 8 的倍位数的图像格式,行尾可能会包含填充位,而下一行则从缓冲区中的下一个字节开始。

保存图像文件#

int IoSaveImageExt(
    const char * file,
    void * data,
    int width,
    int height,
    int bitsPerPixel);

要将图像数据保存到文件,可以调用函数 IoSaveImageExt() 。该函数要求在第一个参数中传入文件名,在第二个参数中传入包含图像数据的缓冲区指针。其余三个参数用于向函数传递图像尺寸和每个 Pixel Format 的位数。

您可以保存以下文件格式: .tif,.tiff, .bmp, 。生的文件格式会自动检测。 const char * file.

处理图像序列文件#

图像 I/O 库支持简单的图像序列文件格式。图像序列文件包含多幅具有相同尺寸和 Pixel Format 的图像。每幅图像都被分配了一个序列索引和一个帧号。序列索引对应图像在文件中的位置,序列索引 0 是序列文件中的第一幅图像,1 是第二幅,依此类推。帧号在采集期间获取,通常从 1 开始,如果并非所有连续图像都写入了序列中,则序列的帧号可能会出现间断。

未为图像序列文件定义标准文件扩展名,推荐的选择是 .isq 或 .imageseq.

打开图像序列文件#

int IoOpenSeq(
    void ** handle,
    const char * file,
    int * width,
    int * height,
    int * bitsPerPixel,
    int flags);

int IoCloseSeq(
    void * handle);
int IoGetSeqInfo(
    void * handle,
    int * nrOfFrames,
    int * nrOfLostFrames);

int IoReadNextSeqPicture(
    void * handle,
    int * frame,
    void * buffer);

要打开现有的图像序列文件以读取其中的图像,可以调用函数 IoOpenSeq() 。该函数要求传入一个指向 void * 中传递 handle 类型变量的指针(该变量将在后续函数中用于访问图像序列文件中的数据),并在参数中传入文件名 file 以及参数中指向图像尺寸变量的三个指针 width 和 height 以及参数中的每像素位数 bitsPerPixel来同步等待一组事件源中的事件。参数 flags 保留用于将来扩展,且应始终设置为 0。

当应用程序完成访问图像序列文件中的数据时,该函数 IoCloseSeq() 应该被调用。

要从图像序列文件中读取下一幅图像,该函数 IoReadNextSeqPicture() 可以被调用。该函数需要来自先前调用的句柄 IoOpenSeq() 中传递 handle,同时在参数 int 以便将图像的帧编号存储在参数中 frame 以及指向缓冲区以在参数中存储图像数据的指针 buffer。缓冲区的大小必须足以根据图像尺寸和 Pixel Format 存储图像数据,例如可以通过调用以下内容进行计算 IoCalculateBufferSize().

函数 IoGetSeqInfo() 可以调用以请求有关图像序列文件中存储的图像数量以及序列中帧编号之间间隙总和的信息。

写入图像序列文件#

int IoCreateSeq(
    void ** handle,
    const char * file,
    int width,
    int height,
    int bitsPerPixel,
    int flags);

int IoCloseSeq(
    void * handle);

int IoWriteNextSeqPicture(
    void * handle,
    int frame,
    const void * buffer);

要创建用于写入图像的新图像序列文件,该函数 IoCreateSeq() 。该函数要求传入一个指向 void * 中传递 handle 类型变量的指针(该变量将在后续函数中用于访问图像序列文件中的数据),并在参数中传入文件名 file,参数中的图像尺寸 width 和 height 以及参数中的每像素位数 bitsPerPixel来同步等待一组事件源中的事件。参数 flags 保留用于将来扩展,且应始终设置为 0。

当应用程序完成访问图像序列文件中的数据时,该函数 IoCloseSeq() 应该被调用。

要将下一幅图像追加到图像序列文件,该函数 IoWriteNextSeqPicture() 可以被调用。该函数需要来自先前调用的句柄 IoCreateSeq() 中传递 handle,参数中的图像帧编号 frame 以及指向包含图像数据的缓冲区的指针(在参数中) buffer。缓冲区的大小必须足以根据图像尺寸和 Pixel Format 提供图像数据,例如可以通过调用以下内容进行计算 IoCalculateBufferSize().

处理视频文件( Windows 仅有的)#

当在 Microsoft Windows 操作系统上使用 Framegrabber API 时,图像输入/输出库对 Audio Video Interleave (.avi) 文件格式提供有限的支持。

打开视频文件#

int IoOpenAVI(
    void ** handle,
    const char * file,
    int * width,
    int * height,
    int * bitDepth);

int IoCloseAVI(
    void * handle);

int IoReadAVIPicture(
    void * handle,
    int index,
    void * buffer);

要打开现有的视频文件以从中读取图像,该函数 IoOpenAVI() 。该函数要求传入一个指向 void * 中传递 handle 将在用于访问视频文件中数据的函数中使用的文件名(位于参数中) file 以及参数中指向图像尺寸变量的三个指针 width 和 height 以及参数中的每像素位数 bitsPerPixel.

当应用程序完成访问视频文件中的数据时,该函数 IoCloseAVI() 应该被调用。

要从视频文件中读取图像,该函数 IoReadAVIPicture() 可以被调用。该函数需要来自先前调用的句柄 IoOpenSeq() 中传递 handle,要读取的图像索引以及指向在参数中存储图像数据的缓冲区的指针 buffer。缓冲区的大小必须足以根据图像尺寸和 Pixel Format 存储图像数据,例如可以通过调用以下内容进行计算 IoCalculateBufferSize().

写入视频文件#

int IoCreateAVIGray(
    void ** handle,
    const char * file,
    int width,
    int height,
    double fps);

int IoCreateAVIGrayW(
    void ** handle,
    const LPCWSTR file,
    int width,
    int height,
    double fps);

int IoCreateAVIColor(
    void ** handle,
    const char * file,
    int width,
    int height,
    double fps);

int IoCreateAVIColorW(
    void ** handle,
    const LPCWSTR file,
    int width,
    int height,
    double fps);

int IoCloseAVI(
    void * handle);

int IoWriteAVIPicture(
    void * handle,
    int index,
    const void * buffer);

要创建用于写入图像的新视频文件,可以调用以下函数之一 IoCreateAVIGray(), IoCreateAVIGrayW(), IoCreateAVIColor() 或 IoCreateAVIColorW() 可以调用。这些函数需要一个指向某种类型变量的指针 void * 中传递 handle 将在用于访问视频文件中数据的函数中使用的文件名(位于参数中) file,参数中的图像尺寸 width 和 height 以及参数中的每秒帧数 fps像素格式由函数的变体决定: IoCreateAVIGray() 和 IoCreateAVIGrayW() 为 8 位灰度图像数据创建一个视频文件,并 IoCreateAVIColor() 和 IoCreateAVIColorW() 为 24 位 RGB 图像数据创建一个文件。以 W 结尾的变体允许使用宽字符字符串的文件名。

当应用程序完成访问视频文件中的数据时,该函数 IoCloseAVI() 应该被调用。

要将图像写入视频文件,可以调用 IoWriteAVIPicture() 函数。该函数在参数 handle中期望获取先前调用某个创建视频文件的函数时返回的句柄,在参数 index 以及指向包含图像数据的缓冲区的指针(在参数中) buffer。缓冲区的大小必须足以根据图像尺寸和 Pixel Format 提供图像数据,例如可以通过调用以下内容进行计算 IoCalculateBufferSize().

从图像序列文件创建视频文件#

int IoSeqCreateAvi(
    void * handle,
    const char * file,
    int fromSeqIndex,
    int toSeqIndex);

函数 IoSeqCreateAvi() 中期望获取视频序列中图像的索引。可以调用该函数从现有的图像序列文件中创建视频文件。该函数期望获取先前调用的句柄作为参数 IoOpenSeq() 中传递 handle,在参数 file 中获取要创建的视频文件的文件名,并在参数 fromSeqIndex 和 toSeqIndex中获取要包含在视频文件中的图像序列文件的第一个和最后一个序列索引。 toSeqIndex如果将值 -1 传递给参数 fromSeqIndex ,则图像序列文件中自