RK 平台 MIPI 摄像头画面发绿排查与修复:从零到可用(IMX415 + /dev/video22)

1. 背景现象

在 Rockchip 平台(例如 RK3588 系列)接入 MIPI 摄像头后,常见问题之一是:

  • 画面整体偏绿(非常绿),颜色严重不正常。
    在这里插入图片描述

很多新手会怀疑是摄像头坏了、排线接触不良、或者需要换 MIPI 口。但实际更常见的原因是:

  • ISP 的 3A(AE/AWB/AF)没有正常运行,尤其是 AWB(自动白平衡)未生效,会导致明显偏色(偏绿最常见)。

本文将自己经历的问题按一个可复现的排查路径,从“确认链路”到“修复 3A”再到“固化脚本”,帮助你把颜色恢复正常。


2. 基础概念:为什么一个摄像头会出现很多 /dev/videoX?

RK 平台的摄像头数据通路通常包括:

  • CIF(采集):从 MIPI CSI2 接入,输出 RAW/Bayer
  • ISP(图像处理):去噪、白平衡、曝光、色彩校正等
  • 多个输出节点:main_path、self_path、统计节点、参数节点等

因此系统里会出现很多 /dev/videoXX
其中只有部分节点是“可直接用于预览/推理的 YUV 输出”,其它节点可能是 RAW 或统计/参数通道。


3. 第一步:确认 ISP 输出节点(以 /dev/video22 为例)

3.1 查看系统识别到的设备

v4l2-ctl --list-devices

3.2 确认 ISP 输出节点支持 NV12(常用)

v4l2-ctl -d /dev/video22 --list-formats-ext

如果能看到 NV12/NV21 等,通常说明 /dev/video22 是 ISP 的某个 YUV 输出(main_path 在很多 BSP 上是常用选择)。


4. 第二步:用“抓一帧 + 手动转色”做真相验证

排查偏色时,最可靠的方式是:绕开应用框架(OpenCV/GStreamer),直接从 V4L2 抓一帧 NV12 文件,再用 Python 明确做 NV12→BGR 转换保存 PNG。这样可以快速判断“问题在 ISP/3A 还是在上层应用”。

4.1 抓一帧 NV12

v4l2-ctl -d /dev/video22 \
  --set-fmt-video=width=640,height=480,pixelformat=NV12 \
  --stream-mmap --stream-count=1 --stream-to=/tmp/isp.nv12

4.2 NV12 转 BGR 并保存图片

python3 - << 'PY'
import cv2, numpy as np
w,h=640,480
data=np.fromfile("/tmp/isp.nv12", dtype=np.uint8)
yuv=data.reshape((h*3//2, w))
bgr=cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV12)
cv2.imwrite("/tmp/isp_frame.png", bgr)
print("wrote /tmp/isp_frame.png")
PY

4.3 如何解读结果?

  • 如果 /tmp/isp_frame.png 偏绿:基本可以确认是 3A(特别是 AWB)没生效,需要启动 AIQ/3A。
  • 如果颜色正常:说明 ISP 输出正常;偏色可能来自你自己的应用链路(此处不展开)。

5. 第三步:为什么会偏绿?——因为 3A(AIQ)没有正常运行

在 Rockchip ISP 架构中,自动曝光/自动白平衡等通常由 **rkaiq(AIQ/3A 引擎)**负责。
rkaiq_3A_server 没运行或崩溃时,ISP 可能以“默认/未校准”状态输出,画面出现明显偏色(偏绿)。

检查 3A 是否存在:

ps -ef | grep -E 'rkaiq_3A_server' | grep -v grep

6. 关键修复:让 rkaiq_3A_server 稳定运行并接管 ISP

6.1 现象与根因(本案例)

本案例系统中存在多套 ISP(例如 rkisp0/rkisp1)。
rkaiq_3A_server 在“枚举/初始化多 ISP”路径下会触发崩溃(Segmentation fault)。为了让 AIQ 稳定启动,我们采用一个可落地的规避策略:

  1. 临时让 AIQ “打不开”第二套 ISP 对应的设备节点
  2. 启动时去掉 root 的越权能力,让权限限制真正生效
  3. AIQ 只初始化目标 ISP(对应 /dev/video22),从而稳定运行

6.2 修复命令(按顺序执行)

(1) 临时屏蔽第二套 ISP 节点
chmod 000 /dev/media3 /dev/v4l-subdev8 /dev/video31 /dev/video38 /dev/video39 2>/dev/null || true
(2) 用 setpriv 启动 3A(关键)
setpriv \
  --bounding-set=-dac_override,-dac_read_search \
  --inh-caps=-dac_override,-dac_read_search \
  --ambient-caps=-dac_override,-dac_read_search \
  /usr/bin/rkaiq_3A_server --silent

启动成功时常见输出包括:

  • rk_aiq_uapi_sysctl_init success
  • rk_aiq_uapi_sysctl_start success
  • wait stream start event...(等待你开始取流)
(3) 触发取流(让 3A 真正开始工作)

只要你启动任何方式的取流(例如运行预览程序或再次 v4l2-ctl 抓帧),AIQ 就会接管并开始实时调整 AE/AWB。


7. 修复后验证:颜色是否恢复正常?

重复第 4 节的“抓一帧 + 转 PNG”验证流程:

v4l2-ctl -d /dev/video22 \
  --set-fmt-video=width=640,height=480,pixelformat=NV12 \
  --stream-mmap --stream-count=1 --stream-to=/tmp/isp_after.nv12

python3 - << 'PY'
import cv2, numpy as np
w,h=640,480
data=np.fromfile("/tmp/isp_after.nv12", dtype=np.uint8)
yuv=data.reshape((h*3//2, w))
bgr=cv2.cvtColor(yuv, cv2.COLOR_YUV2BGR_NV12)
cv2.imwrite("/tmp/isp_after.png", bgr)
print("wrote /tmp/isp_after.png")
PY

/tmp/isp_after.png 颜色正常,则修复完成。


8. 用完之后恢复权限(建议)

屏蔽 ISP1 是一种 workaround。使用完成或不再需要时,建议恢复权限:

chmod 644 /dev/media3 /dev/v4l-subdev8 /dev/video31 /dev/video38 /dev/video39 2>/dev/null || true

停止 3A(如果需要):

pkill -f rkaiq_3A_server

9. 最佳实践:做成一键脚本,避免每次手敲

9.1 启动脚本 /usr/local/bin/start_aiq.sh

#!/bin/bash
set -e

# 屏蔽第二套 ISP 节点,避免 rkaiq 走多 ISP 初始化路径崩溃
chmod 000 /dev/media3 /dev/v4l-subdev8 /dev/video31 /dev/video38 /dev/video39 2>/dev/null || true

# 启动 3A(前台运行,Ctrl+C 停止)
exec setpriv \
  --bounding-set=-dac_override,-dac_read_search \
  --inh-caps=-dac_override,-dac_read_search \
  --ambient-caps=-dac_override,-dac_read_search \
  /usr/bin/rkaiq_3A_server --silent

授权:

chmod +x /usr/local/bin/start_aiq.sh

启动:

/usr/local/bin/start_aiq.sh

9.2 停止并恢复脚本 /usr/local/bin/stop_aiq.sh

#!/bin/bash
pkill -f rkaiq_3A_server 2>/dev/null || true
chmod 644 /dev/media3 /dev/v4l-subdev8 /dev/video31 /dev/video38 /dev/video39 2>/dev/null || true

授权:

chmod +x /usr/local/bin/stop_aiq.sh

10. 结论

当 RK 平台 MIPI 摄像头画面明显偏绿时,优先按以下 checklist 排查:

  1. 找到正确的 ISP YUV 输出节点(本文示例 /dev/video22
  2. v4l2-ctl 抓帧 + Python 明确 NV12→BGR 验证是否偏绿
  3. 若偏绿,优先怀疑 3A(AWB)未生效
  4. 使用本文给出的“屏蔽 ISP1 + setpriv 启动 rkaiq_3A_server”方式让 3A 稳定运行
  5. 再次抓帧验证颜色恢复
Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐