在 H.264 视频编码中,SEI(Supplemental Enhancement Information)消息用于传输额外的、非编码的数据,例如目标检测的信息。SEI 数据可以嵌入到 H.264 流中,以在解码过程中传递这些附加信息。
一、步骤
-
确定 SEI 类型:定义用于传递目标检测信息的 SEI 类型。H.264 标准允许用户定义自定义 SEI 消息类型。你可以选择一个未被标准使用的 SEI 类型(例如,
0x1F
是一个预留的 SEI 类型)或自定义类型。 -
创建 SEI 消息:
- 帧级 SEI:SEI 消息可以附加到视频帧中。需要在编码过程中生成 SEI 消息,并将其插入到 NAL 单元中。
- SEI 结构:SEI 消息通常包含一个类型字段和一个负载字段。你可以在负载字段中存储目标检测信息。
-
SEI 负载格式:目标检测信息可能包括目标的位置、类型等。可以使用以下格式之一(或设计自己的格式)来表示这些信息:
- 位置:可以使用目标的边界框(bounding box)来表示,如
(x, y, width, height)
。 - 类型:用整数或字符串表示目标类型。
- 位置:可以使用目标的边界框(bounding box)来表示,如
-
插入 SEI 消息:将创建的 SEI 消息插入到 H.264 流中,通常是在 IDR 帧之前。SEI 消息是通过特定的 NAL 单元类型插入的,如
NAL_UNIT_SEI
。
二、SEI 消息格式
假设 SEI 类型为 0x1F
,并且负载格式为:
0x1F
(SEI 类型)目标数量
(1 字节)目标数据
:目标类型
(1 字节)位置
(4 字节:x
、y
、width
、height
)
三、代码
#include <vector>
// 定义 SEI 消息类型
const uint8_t SEI_TYPE_OBJECT_DETECTION = 0x1F;
// 创建 SEI 消息
std::vector<uint8_t> create_object_detection_sei(const std::vector<std::tuple<int, int, int, int, uint8_t>>& detections) {
std::vector<uint8_t> sei_message;
sei_message.push_back(SEI_TYPE_OBJECT_DETECTION); // SEI 类型
// 目标数量
sei_message.push_back(static_cast<uint8_t>(detections.size()));
// 目标数据
for (const auto& detection : detections) {
auto [x, y, width, height, type] = detection;
sei_message.push_back(type); // 目标类型
sei_message.push_back(static_cast<uint8_t>(x)); // x
sei_message.push_back(static_cast<uint8_t>(y)); // y
sei_message.push_back(static_cast<uint8_t>(width)); // width
sei_message.push_back(static_cast<uint8_t>(height)); // height
}
return sei_message;
}