Nicla Vision中RGB565转RGB888出错,输出图像色彩失真
RGB565转RGB888色彩异常问题排查与修复
你的问题核心是G通道提取逻辑错误,同时可能存在Nicla帧缓冲区RGB565字节序与代码假设不符的情况,以下是具体修复步骤:
1. 修正G通道转换逻辑
标准RGB565的16位结构为 RRRRRGGGGGGBBBBB(Bit15-11为R,Bit10-5为G,Bit4-0为B),但你的代码在提取G通道时错误多取了一位:
- 原代码用
VH & 0xF0取高4位、VL & 0x0F取低4位,导致G通道被错误扩展,直接引发色彩混乱。
正确的G通道提取逻辑是:从对应字节中分别取G的高3位和低3位,组合成完整的6位G值后再扩展到8位。
2. 适配Nicla帧缓冲区的字节序
Nicla帧缓冲区通常采用小端存储,即16位RGB565值的低8位先存入内存,高8位后存,对应内存结构:
- 第1个字节(
rgbData[bytePosition]):GGGBBBBB(G的低3位 + B的5位) - 第2个字节(
rgbData[bytePosition+1]):RRRRRGGG(R的5位 + G的高3位)
修正后的完整代码
void convertRGB565To888(const uint8_t* rgbData, File outFile) { // 写入BMP头 for(int i = 0; i < 54; i++) { char ch = pgm_read_byte(&bmp_header[i]); outFile.write((uint8_t*)&ch, 1); } for(int i = 0; i < 240; i++) { for(int j = 0; j < 320; j++) { int bytePosition = (i * 320 + j) * 2; // 每个RGB565像素占2字节 uint8_t lowByte = rgbData[bytePosition]; // 小端存储的低字节:GGGBBBBB uint8_t highByte = rgbData[bytePosition + 1]; // 小端存储的高字节:RRRRRGGG // RGB565转RGB888正确逻辑 uint8_t b = ((lowByte & 0x1F) * 527 + 23) >> 6; // 提取B5并扩展到8位 uint8_t r = (((highByte >> 3) & 0x1F) * 527 + 23) >> 6; // 提取R5并扩展到8位 // 提取G的高3位(highByte低3位)和低3位(lowByte高3位),组合成G6后扩展到8位 uint8_t g6 = ((highByte & 0x07) << 3) | ((lowByte >> 5) & 0x07); uint8_t g = (g6 * 259 + 33) >> 6; // BMP格式要求像素按BGR顺序写入,此处顺序正确 outFile.write(b); outFile.write(g); outFile.write(r); } outFile.flush(); }
额外排查步骤
若修复后仍有问题,说明字节序假设错误,尝试交换lowByte和highByte的赋值:
uint8_t lowByte = rgbData[bytePosition + 1]; uint8_t highByte = rgbData[bytePosition];
为什么其他转换正常?
你提到预生成的RGB565转换正常,是因为预生成数据的字节序与原代码假设一致,且原代码的G通道错误在特定数据下表现不明显;而Nicla帧缓冲区的字节序或数据结构与预生成数据不同,导致错误被放大,出现迷幻色彩。
内容的提问来源于stack exchange,提问作者Jan van der Kuyl
相关产品推荐
相关产品推荐

