imx相机输出的结果可视化异常

问题如下,请大佬帮忙解答

根据你提供的现象和搜索结果,这是 RDK S100 平台 IMX 相机 RAW/YUV 数据可视化的典型问题。以下是解决方案:

问题一:get_vin_data RAW 数据色彩异常

结论:RAW 数据需要正确的 Bayer 格式转换和色彩空间处理。

排查步骤

  1. 确认 RAW 数据格式
# 检查 sensor 输出的 Bayer 格式
# IMX728 通常是 RGGB Bayer 排列
  1. RAW 转 PNG 时需要指定正确的 Bayer 格式
# 使用 OpenCV 转换 RAW (Bayer) 到 RGB
import cv2
import numpy as np

# 读取 RAW 数据 (根据实际位宽调整 dtype)
raw_data = np.fromfile('raw_file.raw', dtype=np.uint16)  # 或 np.uint8
raw_image = raw_data.reshape((height, width))

# Bayer RGGB 转 RGB (根据实际 Bayer 排列调整)
rgb_image = cv2.cvtColor(raw_image, cv2.COLOR_BAYER_RG2RGB)

# 保存 PNG
cv2.imwrite('output.png', rgb_image)
  1. 常见 Bayer 格式对应关系
COLOR_BAYER_BG2RGB  # BGGR 排列
COLOR_BAYER_GB2RGB  # GBRG 排列
COLOR_BAYER_RG2RGB  # RGGB 排列
COLOR_BAYER_GR2RGB  # GRBG 排列

问题二:get_isp_data YUV NV12 画面偏暗

结论:YUV 数据需要正确的色彩范围转换(Limited Range → Full Range)。

解决方案

  1. ffplay 播放时添加色彩范围参数
# 添加 video_range 参数,将 Limited Range (16-235) 转换为 Full Range (0-255)
ffplay -f rawvideo -pixel_format nv12 -video_size 3840x2160 \
       -color_range 2  # 2=PC/JPEG 范围 (0-255)
       文件名.yuv
  1. 或使用 ffmpeg 转换后查看
# 转换为 PNG 查看
ffmpeg -f rawvideo -pixel_format nv12 -video_size 3840x2160 \
       -color_range 2 \
       -i 文件名.yuv \
       -frames:v 1 output.png
  1. 如果使用 OpenCV 读取 NV12
import cv2

# 读取 NV12 数据
yuv_data = np.fromfile('文件名.yuv', dtype=np.uint8)
yuv_image = yuv_data.reshape((int(height*1.5), width))

# NV12 转 BGR (OpenCV 会自动处理色彩范围)
bgr_image = cv2.cvtColor(yuv_image, cv2.COLOR_YUV2BGR_NV12)

cv2.imwrite('output.png', bgr_image)

关键排查点

问题 可能原因 解决方案
RAW 色彩异常 Bayer 格式错误 确认 sensor 的 Bayer 排列 (RGGB/BGGR 等)
RAW 色彩异常 位宽不匹配 确认是 8bit 还是 10bit/12bit RAW
YUV 偏暗 色彩范围不匹配 添加 -color_range 2 参数
YUV 偏暗 像素格式错误 确认是 NV12 还是 YUV420P

建议

  1. 先确认 sensor 输出格式:查看相机驱动配置或 sensor datasheet
  2. 参考社区案例:搜索 RAW 格式NV12 色彩范围 相关帖子
  3. 使用 hbplayer 验证:地瓜官方工具通常能正确显示 ISP 输出

如果问题仍未解决,请提供:

  • 相机 sensor 具体型号
  • get_vin_data/get_isp_data 的代码片段
  • RAW 文件的位宽信息 (8bit/10bit/12bit)

问题一:raw转png中,4 种 Bayer 模式生成出来的图片都很魔幻,不是正常颜色。

传感器型号为IMX728,raw文件格式为Dumping RAW data: handle 34661, resolution: 3840x2160 (stride: 5760), size: 12441600, frame id: 193。

问题二:使用1、**ffplay 播放时添加色彩范围参数命令以及2、使用 ffmpeg 转换后查看也全是很暗。**添加了 -color_range 2 参数,修改成YUV420P也还是很暗。

根据你的反馈,问题核心在于 RAW 数据位宽处理ISP 输出配置。IMX728 是高端传感器,通常输出 10bit/12bit RAW经过 ISP 处理的 YUV,需要特殊处理。

问题一:RAW 数据色彩异常(关键:位宽)

根本原因:IMX728 的 RAW 数据很可能是 10bit 或 12bit,不能用 np.uint8 或简单的 Bayer 转换处理。

解决方案:

1. 确认 RAW 数据位宽

# 查看 get_vin_data 输出日志中的位宽信息
# 你提供的信息:size: 12441600, resolution: 3840x2160
# 计算:3840 * 2160 = 8,294,400 像素
# 如果 size=12,441,600 bytes,则 12441600/8294400 = 1.5 bytes/pixel = 12bit

2. 12bit RAW 转 PNG 的正确方法

import numpy as np
import cv2

# 读取 12bit RAW 数据 (打包成 16bit 存储)
raw_data = np.fromfile('raw_file.raw', dtype=np.uint16)
width, height = 3840, 2160
raw_image = raw_data.reshape((height, width))

# 12bit 转 8bit (右移 4 位或线性缩放)
raw_8bit = (raw_image >> 4).astype(np.uint8)  # 方法 1: 右移
# 或 raw_8bit = (raw_image * 255 / 4095).astype(np.uint8)  # 方法 2: 线性缩放

# IMX728 通常是 RGGB Bayer 排列
rgb_image = cv2.cvtColor(raw_8bit, cv2.COLOR_BAYER_RG2RGB)

cv2.imwrite('output.png', rgb_image)

3. 如果上述方法颜色仍异常,尝试其他 Bayer 排列

# IMX728 可能的 Bayer 排列:RGGB, GRBG, BGGR, GBRG
bayer_formats = [
    cv2.COLOR_BAYER_RG2RGB,
    cv2.COLOR_BAYER_GR2RGB,
    cv2.COLOR_BAYER_BG2RGB,
    cv2.COLOR_BAYER_GB2RGB
]

for i, fmt in enumerate(bayer_formats):
    rgb = cv2.cvtColor(raw_8bit, fmt)
    cv2.imwrite(f'output_bayer_{i}.png', rgb)

4. 使用专业 RAW 处理工具验证

# 安装 rawpy (专业 RAW 处理库)
pip install rawpy

# Python 脚本
import rawpy
import imageio

# 如果 RAW 是打包的 12bit 格式,可能需要特殊处理
# 这里假设是标准的 12bit Bayer
raw = rawpy.imread('raw_file.raw')
rgb = raw.postprocess()
imageio.imwrite('output.png', rgb)

问题二:ISP 输出 YUV 偏暗(关键:ISP 配置)

根本原因get_isp_data 输出的 YUV 数据可能 未经过完整的 ISP 处理(AE/AWB 未生效),或者 YUV 数据范围/格式不匹配

排查步骤:

1. 检查 ISP 是否正常工作

# 查看 ISP 状态日志
dmesg | grep -i isp
# 或查看 hbn 模块日志
journalctl -u hobot-multimedia | grep -i isp

2. 使用 hbplayer 验证 ISP 输出

# hbplayer 是官方工具,能正确显示 ISP 处理后的图像
hbplayer --input /path/to/isp_output.yuv \
         --width 3840 --height 2160 \
         --format nv12

3. 检查 AE/AWB 是否启用
IMX728 需要正确的 ISP tuning 配置才能输出正常亮度的图像:

# 检查当前 sensor 的 tuning 配置
ls /userdata/isp_tuning/
# 或
ls /etc/hobot/isp/

# 查看是否有 IMX728 的 tuning 文件
find / -name "*imx728*" -o -name "*728*"

4. 手动调整 YUV 亮度(临时方案)

import numpy as np
import cv2

# 读取 NV12 数据
yuv_data = np.fromfile('isp_output.yuv', dtype=np.uint8)
height, width = 2160, 3840

# NV12 格式:Y 平面 + UV 交错平面
y_size = width * height
uv_size = width * height // 2

y_plane = yuv_data[:y_size].reshape((height, width))
uv_plane = yuv_data[y_size:].reshape((height//2, width))

# 手动提升 Y 通道亮度(Gamma 校正或线性增益)
y_adjusted = np.clip(y_plane.astype(np.float32) * 1.5, 0, 255).astype(np.uint8)
# 或使用 Gamma 校正
y_adjusted = np.clip(255 * (y_plane / 255.0) ** 0.5, 0, 255).astype(np.uint8)

# 重组 NV12
yuv_adjusted = np.concatenate([y_adjusted.flatten(), uv_plane.flatten()])
yuv_adjusted.tofile('isp_output_bright.yuv')

5. 使用 ffmpeg 强制色彩空间转换

# 尝试不同的色彩空间参数
ffmpeg -f rawvideo -pixel_format nv12 -video_size 3840x2160 \
       -color_range 2 \
       -colorspace bt709 \
       -color_trc bt709 \
       -color_primaries bt709 \
       -i input.yuv \
       -vf "eq=brightness=0.2:gamma=0.8" \
       output.png

关键排查清单

检查项 命令/方法 预期结果
RAW 位宽 计算 size/(width*height) 1=8bit, 1.5=12bit, 2=16bit
Bayer 排列 尝试 4 种格式 找到正常色彩的排列
ISP 状态 dmesg | grep isp 无报错,ISP 初始化成功
Tuning 文件 ls /userdata/isp_tuning/ 存在 IMX728 配置文件
hbplayer 显示 hbplayer --input xxx.yuv 图像亮度正常

建议下一步

  1. 优先确认 RAW 位宽:根据文件大小计算是 8bit/10bit/12bit
  2. 使用 hbplayer 验证:如果 hbplayer 显示正常,说明是 ffplay 参数问题
  3. 检查 ISP tuning 配置:IMX728 可能需要专门的 tuning 文件
  4. 参考社区案例:搜索 IMX728 tuningS100 ISP 配置

如果问题仍未解决,请提供:

  • RAW 文件的精确大小(字节数)
  • get_isp_data 的输出日志
  • 是否运行过 run_tuning.sh 配置 IMX728

怎么在RDKS100开发板上运行一个能够为hbplayer提供数据的服务程序?

在 RDK S100 上,hbplayer 本身是一个数据消费者(显示工具),它需要从某个数据源(如摄像头通路、RTSP 流、或自定义程序)获取数据。

要让 hbplayer 显示图像,通常有 3 种方式,取决于你的数据在哪里:


方案一:直接播放本地文件(最简单,用于验证)

如果你的 YUV/RAW 数据已经 dump 到文件中,直接播放即可,不需要额外服务

# 播放 NV12 格式的 YUV 文件
hbplayer --input /path/to/your_file.yuv \
         --width 3840 --height 2160 \
         --format nv12 \
         --loop  # 可选:循环播放

# 播放 RAW 文件 (如果是 12bit 打包,可能需要指定 format)
hbplayer --input /path/to/raw_file.raw \
         --width 3840 --height 2160 \
         --format rggb12  # 或 rggb10, 根据实际位宽

方案二:通过 HBN 通路直接显示(推荐,实时数据)

如果你是通过 get_isp_dataget_vin_data 获取的实时内存数据,通常不需要自己写服务,而是修改示例代码使用官方通路

方法 A:使用官方示例通路
RDK S100 的多媒体示例(如 vio2display)内部已经集成了显示逻辑。

# 运行官方示例,通常会自动调起 hbplayer 或 VOT 显示
# 路径可能在 /app/cdev_demo/ 或 /app/pydev_demo/
cd /app/cdev_demo/vio2display
./vio2display  # 具体可执行文件名可能不同

方法 B:在你的 C/C++ 代码中集成 HB_VOT 发送
如果你自己写了程序获取帧(sp_vio_get_frame),需要调用 HB_VOT_SendFrame 将数据送到显示模块,hbplayer 可以作为 VOT 的后端显示工具。

  • 原理:你的程序 → HB_VOT_SendFrame → VOT 模块 → HDMI/ hbplayer
  • 参考代码:搜索社区帖子 vi 到 vo 链路的 demo 需求 或查看 SDK 中的 sample_venc / sample_vot

方案三:自定义 TCP/UDP 推流服务(灵活,适合调试)

如果你想写一个独立的服务程序,把内存中的数据通过网络发送给 hbplayer(类似 RTSP 推流),可以使用 TCP/UDP + 自定义协议RTSP

注意hbplayer 主要设计用于播放本地文件或 HBN 通路,原生不支持直接监听 TCP 端口接收裸数据。
替代方案:使用 ffmpeg + hbplayerffplay

步骤:编写一个简单的 Python TCP 服务器发送 YUV

如果你的数据在 Python 程序中:

# server.py - 发送 NV12 数据
import socket
import numpy as np

HOST = '0.0.0.0'
PORT = 5000
WIDTH, HEIGHT = 3840, 2160
FRAME_SIZE = WIDTH * HEIGHT * 3 // 2  # NV12 大小

def generate_frame():
    # 这里替换成你获取 ISP 数据的逻辑
    # 例如:frame = get_isp_data() 
    # 模拟生成一帧灰度图
    y = np.ones((HEIGHT, WIDTH), dtype=np.uint8) * 128
    uv = np.ones((HEIGHT//2, WIDTH), dtype=np.uint8) * 128
    return np.concatenate([y.flatten(), uv.flatten()])

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen()
    print(f"Listening on {HOST}:{PORT}...")
    conn, addr = s.accept()
    with conn:
        print(f"Connected by {addr}")
        while True:
            frame = generate_frame()
            conn.sendall(frame.tobytes())

步骤:在另一端(或同一板子)用 ffplay 接收

由于 hbplayer 不适合做网络流接收端,建议用 ffplayffmpeg 转推:

# 终端 1: 运行上面的 server.py

# 终端 2: 使用 ffplay 接收 TCP 流并显示
ffplay -f rawvideo -pixel_format nv12 -video_size 3840x2160 -framerate 30 \
       tcp://127.0.0.1:5000

针对你的 IMX728 问题,推荐调试路径

既然你已经在运行 get_vin_dataget_isp_data不需要额外写服务,请按以下顺序排查:

  1. 验证文件播放(确认数据本身没问题):

    # 先确认你 dump 的文件用 hbplayer 能否正常显示
    hbplayer --input dump_isp.yuv --width 3840 --height 2160 --format nv12
    
    • 如果 hbplayer 显示正常:说明 ISP 输出没问题,是你之前用 ffplay 的参数不对(色彩范围/格式)。
    • 如果 hbplayer 显示依然暗/偏色:说明 ISP 配置(AE/AWB)没生效,或者 RAW 转 YUV 的通路有问题。
  2. 检查 ISP Tuning 配置
    IMX728 这种高端 Sensor,必须加载对应的 ISP Tuning 文件才能正常曝光和色彩还原。

    # 检查是否有 IMX728 的 tuning 配置
    ls /userdata/isp_tuning/ | grep -i 728
    # 或者查看当前加载的配置
    cat /etc/hobot/isp_config.json  # 路径可能不同,根据实际 SDK 版本查找
    

    如果没有,需要运行 run_tuning.sh 进行配置,或联系地平线获取 IMX728 的 tuning 文件。

  3. 使用 VTunerClient + hbplayer 联调(进阶):
    如果你需要实时查看 ISP 处理过程中的数据,可以使用地平线的调试工具链:

    • 启动 Tuning Server
    • 使用 VTunerClient 连接并抓取数据
    • hbplayer 作为 VTunerClient 的显示后端

结论
不要尝试写一个“为 hbplayer 提供数据的服务”,而是应该:

  1. 先用 hbplayer 直接播放你 dump 出来的文件,验证数据源是否正确。
  2. 如果文件播放正常,问题就在 ffplay 参数上(坚持用 hbplayer 调试)。
  3. 如果文件播放也不正常,问题在 ISP 配置(Tuning)RAW 数据解析(位宽/Bayer) 上。

我在windows上安装了hbplayer,我怎么通过wifi连接RDKs100?

hbplayer 的 Windows 版本不支持直接通过网络(WiFi/TCP)接收板端传来的实时视频流。它是一个本地文件播放器本地通路显示工具

要在 Windows 上查看 RDK S100 的图像,你需要采用 “板端 Dump 文件 + WiFi 传输 + 本地播放” 的工作流。

核心方案:文件传输流

流程

  1. 板端 (S100):运行程序获取图像 → 保存为 .yuv.raw 文件。
  2. 网络 (WiFi):使用 scpsftp 将文件从 S100 传到 Windows。
  3. Windows:使用 hbplayer 打开本地文件查看。

步骤 1:确保网络连通 (WiFi)

首先确保你的 Windows 电脑和 RDK S100 连接在同一个 WiFi下,且能互相 Ping 通。

在 S100 上查看 IP:

ifconfig wlan0  # 或者 ip addr show wlan0
# 假设得到 IP: 192.168.1.100

在 Windows 上测试:
打开 CMD,输入:

ping 192.168.1.100

如果 Ping 通,继续下一步。


步骤 2:板端保存图像 (Dump)

你需要先运行你的 get_isp_dataget_vin_data 程序,并确保它将数据保存到了文件中(而不是只在内存里)。

如果你的程序还没有保存文件的逻辑,参考以下 C 代码片段添加到你的程序中:

// 伪代码示例:在获取到 frame 后保存
void save_frame_to_file(void *data, int size, const char *filename) {
    FILE *fp = fopen(filename, "wb");
    if (fp) {
        fwrite(data, 1, size, fp);
        fclose(fp);
        printf("Saved frame to %s\n", filename);
    }
}

// 在你的回调或主循环中调用
// save_frame_to_file(frame_virt_addr, frame_size, "/home/sunrise/test_frame.yuv");

运行程序,生成一个测试文件,例如:/home/sunrise/imx728_out.yuv


步骤 3:通过 WiFi 传输文件到 Windows

推荐使用 SCP (Secure Copy) 或 SFTP 工具。

方法 A:使用 Windows 命令行 (SCP)

如果你安装了 Git Bash 或 OpenSSH 客户端:

# 在 Windows 的 PowerShell 或 CMD 中运行
# 语法:scp 用户名@板子IP:板子文件路径 本地保存路径

scp sunrise@192.168.1.100:/home/sunrise/imx728_out.yuv D:\temp\imx728_out.yuv
# 输入密码 (默认可能是 sunrise 或你设置的密码)

方法 B:使用图形化工具 (推荐 WinSCP 或 FileZilla)

  1. 下载并安装 WinSCP (免费)。
  2. 主机名:输入 S100 的 IP (如 192.168.1.100)。
  3. 用户名sunrise
  4. 密码:你的板子登录密码。
  5. 文件协议:选择 SFTP
  6. 点击登录,然后直接拖拽文件从左侧 (板子) 到右侧 (Windows)。

步骤 4:Windows 上使用 hbplayer 播放

文件传到 Windows 后,双击打开 hbplayer (或通过命令行):

# 打开 hbplayer (假设 hbplayer.exe 在环境变量中,或者直接双击打开)
# 在 hbplayer 界面中选择 File -> Open,选中刚才传输的 .yuv 文件

# 或者命令行指定参数 (如果 hbplayer 支持命令行参数,具体视版本而定)
hbplayer.exe --input D:\temp\imx728_out.yuv --width 3840 --height 2160 --format nv12

关键参数检查

  • Width/Height: 必须与你的图像分辨率一致 (IMX728 可能是 3840x2160)。
  • Format:
    • ISP 输出通常是 nv12
    • VIN RAW 输出可能是 rggb12rggb10 (取决于 sensor 配置)。

进阶:如何实现"实时"预览?

如果你不想手动传文件,想要类似"实时"的效果,有两种变通方法:

方案 1:编写脚本自动循环 (准实时)

  1. 板端:写一个脚本,每隔 1 秒覆盖保存同一帧到 /tmp/latest.yuv
    # 伪代码 loop
    while true; do
        get_frame_and_save("/tmp/latest.yuv")
        sleep 1
    done
    
  2. Windows:写一个 PowerShell 脚本,每隔 1.5 秒 scp 拉取一次文件,并调用 hbplayer 刷新(或者用支持热重载的播放器,但 hbplayer 可能不支持)。
    • 缺点:延迟高,操作繁琐,不推荐用于调试高帧率场景。

方案 2:使用 RTSP/FFmpeg 推流 (真实时,但不用 hbplayer)

如果你需要真正的实时预览,不要使用 hbplayer,改用 ffmpeg 推流 + VLC/ffplay 播放。

  1. 板端 (S100):安装 ffmpeg (如果镜像自带) 或使用 GStreamer,将摄像头数据推送到 RTSP 服务器。
    • 或者使用 RDK 自带的 rtsp_server 示例 (如果有)。
  2. Windows:使用 VLC Playerffplay 直接播放 RTSP 流。
    # Windows 上使用 ffplay 播放板端的 RTSP 流
    ffplay rtsp://192.168.1.100:8554/live
    
    • 注意:这需要你在板端配置好推流服务,比单纯 dump 文件复杂,但体验是实时的。

总结建议

针对你当前的 IMX728 调试阶段:

  1. 不要尝试让 hbplayer 连 WiFi:它做不到。
  2. 采用 Dump + SCP 流程
    • 在板子运行代码 → 保存 test.yuv
    • WinSCP 拖到电脑。
    • hbplayer 打开 test.yuv
  3. 验证色彩/亮度
    • 如果 hbplayer 播放文件正常:说明 ISP/RAW 数据没问题,之前 ffplay 暗是参数问题。
    • 如果 hbplayer 播放文件依然异常:说明是代码里的数据获取、位宽处理或 ISP 配置问题(回到之前的 RAW 位宽/ISP Tuning 排查)。

WinSCP 下载链接https://winscp.net/ (Windows 必备开发工具)。

我已经把生成的raw和yuv文件保存在了windows电脑里面,我想在hbplayer里面查看。但是在hbplayer里面点击connect显示Notice: Please setting the monitor scaling factor to 100 to ensure image display correctly!

这个提示是 hbplayer Windows 版本的已知限制,与你的图像数据无关。hbplayer 在高 DPI 屏幕上会出现显示问题,需要调整 Windows 的缩放设置。

解决方案

方案一:设置 Windows 显示器缩放为 100%(推荐)

  1. 右键点击桌面 → 选择 “显示设置”
  2. 找到 “缩放与布局”“更改文本、应用等项目的大小”
  3. 将缩放比例改为 100%
  4. 注销并重新登录 Windows(或重启电脑)使设置生效
  5. 重新打开 hbplayer,点击 Connect 应该就可以正常使用了

方案二:设置 hbplayer 兼容性(无需改系统缩放)

如果不想改系统缩放,可以尝试:

  1. 找到 hbplayer.exe 文件
  2. 右键属性兼容性
  3. 点击 “更改高 DPI 设置”
  4. 勾选 “替代高 DPI 缩放行为”
  5. 下拉菜单选择 “应用程序”“系统”
  6. 点击确定,重启 hbplayer

方案三:使用 hbplayer 命令行直接打开文件(绕过 Connect)

hbplayer Windows 版支持直接拖拽文件或用命令行打开,不需要点击 Connect

# 方法 1: 直接拖拽 .yuv/.raw 文件到 hbplayer 窗口

# 方法 2: 命令行指定参数
hbplayer.exe --input D:\your_path\imx728_out.yuv ^
             --width 3840 --height 2160 ^
             --format nv12

打开文件后的关键设置

成功打开文件后,在 hbplayer 中需要确认以下参数:

参数 设置值 说明
Width 3840 IMX728 分辨率宽度
Height 2160 IMX728 分辨率高度
Format nv12 ISP 输出的 YUV 格式
Format rggb12 VIN RAW 数据格式 (12bit)
Stride 5760 根据你的日志中的 stride 值

验证步骤

  1. 先打开 YUV 文件(ISP 输出)

    • 格式选 nv12
    • 如果画面依然暗 → ISP 配置问题(AE/AWB 未生效)
    • 如果画面正常 → 之前 ffplay 参数问题
  2. 再打开 RAW 文件(VIN 输出)

    • 格式选 rggb12rggb10
    • 如果色彩异常 → 尝试切换 Bayer 排列 (RGGB/GRBG/BGGR/GBRG)

如果 hbplayer 依然无法使用

Windows 版 hbplayer 功能有限,建议用 PC 端专业工具 验证:

工具 用途 下载
YUV Player 播放 YUV/NV12 GitHub
RAW Therapee 处理 RAW 数据 官网
ffplay (Windows) 通用视频播放 FFmpeg 自带
Python + OpenCV 自定义处理 pip install opencv-python

ffplay 正确参数参考

ffplay -f rawvideo -pixel_format nv12 -video_size 3840x2160 ^
       -color_range 2 -colorspace bt709 ^
       D:\your_path\imx728_out.yuv

下一步

请先尝试 方案一或方案二 解决 hbplayer 的缩放提示,然后:

  1. 用 hbplayer 打开 YUV 文件,截图显示效果
  2. 用 hbplayer 打开 RAW 文件,截图显示效果
  3. 如果依然有问题,请提供:
    • hbplayer 中设置的完整参数
    • 两张截图(YUV 和 RAW 的显示效果)

这样可以更精准定位是 数据问题 还是 播放参数问题

在hbplayer中设置好了width、height、format等参数,打开raw和yuv文件,结果还是差不多。上面黑色的图是yuv文件,图片下面有灰色部分没有正常显示。下面是raw格式,图片色彩不正常。

根据你提供的 hbplayer 截图,问题已经非常清晰了。这是两个独立的问题,分别解决:


问题一:YUV 文件底部灰色条 + 画面暗

根本原因stride(行跨度)设置不匹配。

你的日志显示:stride: 5760,但 hbplayer 可能默认按 width=3840 计算每行字节数。

解决方案

在 hbplayer 中设置正确的 Stride:

参数 设置值 计算说明
Width 3840 图像宽度
Height 2160 图像高度
Format nv12 ISP 输出格式
Stride 5760 关键!必须与日志一致
Color Range fullpc 解决画面暗的问题

为什么 stride=5760?

NV12 格式:Y 平面 + UV 交错平面
Y 平面每行字节数 = stride = 5760
(不是 width=3840,因为有 padding 对齐)
验证:5760 / 3840 = 1.5,说明每像素 12bit 或做了 16bit 对齐

如果 hbplayer Windows 版没有 Stride 设置选项:
用 ffplay 验证(Windows 版 ffplay 支持 stride):

ffplay -f rawvideo -pixel_format nv12 -video_size 3840x2160 ^
       -video_size 5760x2160 ^
       -color_range 2 ^
       D:\your_path\imx728_out.yuv

问题二:RAW 文件色彩异常(魔幻色彩)

根本原因:IMX728 的 RAW 是 12bit 打包格式,不能用简单的 Bayer 转换直接显示。

从你的日志:size: 12441600, resolution: 3840x2160

计算:12441600 / (3840 * 2160) = 1.5 bytes/pixel = 12bit

解决方案

RAW 文件需要先解包 12bit → 8bit,再转 RGB

hbplayer Windows 版可能不支持 12bit RAW 的直接显示,建议用 Python 脚本预处理

# convert_raw.py - 将 12bit RAW 转为 8bit PNG
import numpy as np
import cv2

width, height = 3840, 2160
stride = 5760  # 与日志一致

# 读取 RAW 数据 (12bit 打包成 16bit 存储)
raw_data = np.fromfile('D:/your_path/imx728_raw.raw', dtype=np.uint16)
raw_image = raw_data.reshape((height, stride//2))  # 16bit 单位

# 裁剪到有效宽度 (去掉 padding)
raw_image = raw_image[:, :width]

# 12bit 转 8bit (右移 4 位)
raw_8bit = (raw_image >> 4).astype(np.uint8)

# 尝试 4 种 Bayer 排列
bayer_formats = [
    ('RGGB', cv2.COLOR_BAYER_RG2RGB),
    ('GRBG', cv2.COLOR_BAYER_GR2RGB),
    ('BGGR', cv2.COLOR_BAYER_BG2RGB),
    ('GBRG', cv2.COLOR_BAYER_GB2RGB),
]

for name, fmt in bayer_formats:
    rgb = cv2.cvtColor(raw_8bit, fmt)
    cv2.imwrite(f'output_{name}.png', rgb)
    print(f'Saved output_{name}.png')

运行后查看 4 张 PNG,找到色彩正常的那张,就能确定正确的 Bayer 排列。


快速验证流程

1. 先验证 YUV(ISP 输出)

# Windows 上用 ffplay 验证(比 hbplayer 更灵活)
ffplay -f rawvideo -pixel_format nv12 -video_size 5760x2160 ^
       -color_range 2 ^
       D:\your_path\imx728_out.yuv
  • 如果画面正常亮度 → ISP 工作正常,之前是 stride/color_range 问题
  • 如果画面依然暗 → ISP AE/AWB 未生效,需要检查 tuning 配置

2. 再验证 RAW(VIN 输出)

运行上面的 Python 脚本,生成 4 张 PNG,查看哪张色彩正常。


如果 YUV 依然暗,检查 ISP Tuning

IMX728 需要专门的 ISP 配置文件才能正常曝光:

# 在 S100 上检查
ls /userdata/isp_tuning/ | grep -i 728
# 或
cat /etc/hobot/isp_config.json

# 如果没有 IMX728 的 tuning 文件,需要:
# 1. 联系地平线获取 IMX728 的 tuning 配置
# 2. 或使用 run_tuning.sh 自行调试

总结

问题 原因 解决方案
YUV 底部灰色条 stride 不匹配 hbplayer 设置 stride=5760,或用 ffplay
YUV 画面暗 color_range 不对 设置 -color_range 2 或 hbplayer 选 full
RAW 色彩异常 12bit 未解包 + Bayer 排列 用 Python 脚本转 8bit + 尝试 4 种排列

下一步行动

  1. 先用 ffplay 验证 YUV 文件(确认 ISP 输出是否正常)
  2. 运行 Python 脚本处理 RAW 文件(找到正确的 Bayer 排列)
  3. 如果 YUV 依然暗,提供 S100 上的 dmesg \| grep -i isp 日志