YU12转YUYV转换后图像出现噪点问题求助
问题排查与修复方案
核心原因:填充数据导致色彩平面偏移
640×480分辨率的YU12格式,理论总字节数为:
- Y平面:
640*480 = 307200字节 - U/V平面各为:
(640/2)*(480/2) = 76800字节 - 总计:
307200 + 76800*2 = 460800字节,与v4l2-ctl查询结果一致。
你拿到的输入数据多了2048字节,这是V4L2设备为内存对齐自动添加的帧填充数据,通常附加在每帧末尾。你的原转换函数直接按理论长度截取Y/U/V平面,相当于把部分填充数据误纳入U/V平面,导致色彩采样错位,最终产生噪点。
修复方案
先截断多余的填充数据,只保留有效图像部分再进行转换,修改后的函数如下:
pub fn yu12_to_yuyv(resolution: Resolution, data: &[u8]) -> Vec<u8> { let width = resolution.width_x as usize; let height = resolution.height_y as usize; let y_size = width * height; let uv_plane_size = (width / 2) * (height / 2); let expected_total_size = y_size + uv_plane_size * 2; // 截断填充数据,仅保留有效图像字节 let valid_data = if data.len() > expected_total_size { &data[0..expected_total_size] } else { data }; // 提取正确的Y/U/V平面 let y_plane = &valid_data[0..y_size]; let u_plane = &valid_data[y_size..(y_size + uv_plane_size)]; let v_plane = &valid_data[(y_size + uv_plane_size)..]; let mut yuyv = Vec::with_capacity(y_size * 2); for y in 0..height { for x in (0..width).step_by(2) { let y_index1 = y * width + x; let y_index2 = y * width + x + 1; let uv_index = (y / 2) * (width / 2) + (x / 2); let y1 = y_plane[y_index1]; let y2 = y_plane[y_index2]; let u = u_plane[uv_index]; let v = v_plane[uv_index]; yuyv.extend_from_slice(&[y1, u, y2, v]); } } yuyv }
额外验证建议
- 确认转换后YUYV数据长度为
640*480*2 = 614400字节,确保有效数据未丢失。 - 若仍有问题,可在Droidcam设置中尝试强制输出无填充的YU12格式,减少裁剪操作的开销。
内容的提问来源于stack exchange,提问作者Ajay Pillay
相关产品推荐
相关产品推荐

