最近需要在边缘端进行模型部署,模型推理需要使用RGBA图像,而接收到的图像为NV12格式,由于板子资源有限,无法使用opencv完成转换,因此需要手动实现NV12转RGBA,目前网上的代码几乎都无法使用,通义灵码等大模型虽然可以生成代码,但转出的图像不正确,因此,在这里分享我最终使用的代码,有需要的同行可以参考,麻烦点点关注
typedef unsigned char __uint8_t;
typedef __uint8_t uint8_t;
T clamp(T value, T min, T max) {
if (value < min) return min;
if (value > max) return max;
return value;
}
//将输入的nv12图像转为rgba图像进行图里
void nv12_to_rgba(uint8_t* src_nv12, uint8_t* dst_rgba, int width, int height) {
if (width < 1 || height < 1 || src_nv12 == nullptr || dst_rgba == nullptr) {
return;
}
int frame_size = width * height;
uint8_t* y_plane = src_nv12;
uint8_t* uv_plane = src_nv12 + frame_size;
for (int j = 0; j < height; ++j) {
for (int i = 0; i < width; ++i) {
int y_index = j * width + i;
int uv_index = (j / 2) * width + (i & ~1);
uint8_t y = y_plane[y_index];
uint8_t u = uv_plane[uv_index];
uint8_t v = uv_plane[uv_index + 1];
int c = y - 16;
int d = u - 128;
int e = v - 128;
int r = (298 * c + 409 * e + 128) >> 8;
int g = (298 * c - 100 * d - 208 * e + 128) >> 8;
int b = (298 * c + 516 * d + 128) >> 8;
r = clamp(r, 0, 255);
g = clamp(g, 0, 255);
b = clamp(b, 0, 255);
int rgba_index = y_index * 4;
dst_rgba[rgba_index] = static_cast<uint8_t>(r);
dst_rgba[rgba_index + 1] = static_cast<uint8_t>(g);
dst_rgba[rgba_index + 2] = static_cast<uint8_t>(b);
dst_rgba[rgba_index + 3] = 255; // Alpha channel
}
}
}