红外夜视
红外夜视让同一路相机在白天输出彩色,在光照不足时移开红外线截止滤光片、打开红外补光灯,并输出黑白。esp_ipa 的红外算法根据环境亮度决定何时切换。启用 ISP 流水线后,滤光片、补光灯、饱和度和夜间色彩参数由流水线自动下发,应用不必每帧下发命令。
目标与适用场景
红外夜视用于夜间或光照不足时成像:可移动的红外线截止滤光片在可见光与近红外之间切换,同一路相机兼顾白天彩色和夜间黑白。适用于以下场景:
安防监控
家庭、商铺、仓库的夜间监控,要求看清人物轮廓和行为。
小区周界、停车场等室外区域,避免可见光补光造成光污染或暴露摄像头位置。
监狱、军事基地等高安全等级场所的 24 小时隐蔽监控。
车载辅助驾驶
探测前方行人、动物或障碍物,在仪表上显示黑白图像。
无路灯时的倒车影像。
野外监测与生态研究
夜间观察蝙蝠、夜行哺乳动物等,不惊扰动物。
防盗猎、森林防火监控。
工业与管道检测
地下管道、矿井、隧道等黑暗环境的巡检机器人。
变压器、开关柜等设备内部的巡检。
适用前提:传感器输出 RAW,并由片上 ISP 统计亮度与白平衡,例如 ESP32-P4。已在传感器内部完成彩色处理的 YUV/RGB 传感器不使用 esp_ipa 中的红外算法。
解决的问题
白天必须挡住近红外,否则彩色偏色。夜间移开红外线截止滤光片,近红外才能到达传感器。只按画面亮暗切换会振荡:补光灯点亮后画面变亮,算法会立刻切回白天。近红外下继续做彩色插值只会得到假色。
本方案处理这三件事:
白天只比较环境亮度。夜视先把亮度乘
night_ir_factor,再要求本帧白平衡统计里红、绿通道之和都不为 0。补光把画面照亮,但没有有效白平衡样本时,仍留在夜视。开始进入夜视时把饱和度设为 0,并写入夜间的白平衡统计窗、色彩校正矩阵和红蓝增益。回到白天的过渡结束后,饱和度、白平衡、色温和色彩校正按各自的调参重新输出。
条件要连续成立一段保持时间才开始切换。切换之后有一段过渡时间,这段时间不再判断,等滤光片到位、曝光重新收敛。
方案原理
硬件上,红外线截止滤光片可移入或移出光路。白天滤光片留在光路中,挡住近红外。夜间滤光片移出,近红外到达传感器;此时打开红外补光灯,即可在没有可见光的环境下成像。
算法有四个状态:白天、切到夜视、夜视、切回白天。上电进入白天。ir_enable 为真表示夜视,流水线据此把滤光片切到夜间,并把补光灯开到最大亮度;为假则把滤光片切回白天,并把灯关到最小亮度。滤光片是机械装置,行程时间不由软件控制,因此灯与滤光片在同一帧下发。未走这路控制的灯仍须与滤光片保持同一日夜状态,否则亮度判断会被灯的开关带偏。
环境亮度来自 luma_env 指定的变量。省略该键时使用 env.luma.avg。写成 JSON null 或字符串 "NULL" 时,这一帧没有亮度:白天保持白天,夜视保持夜视,保持计时重新开始。算法不读取 ir_led_on,也不比较 G/R。
白天。亮度高于
day_luma_threshold为亮,保持计时清零。不高于该门限,并连续保持day_keep_time_us,才开始切到夜视。这里不乘night_ir_factor,也不看白平衡。夜视。比较前先把亮度乘
night_ir_factor。乘完后不高于night_luma_threshold为暗。高于该门限时,还要本帧带有白平衡统计,且红、绿通道之和都不为 0,才算亮。没有亮度、亮度偏暗、没有白平衡统计,或红、绿通道之和有一个为 0,都当作暗,保持计时清零。
两套亮度门限形成滞回。night_ir_factor 用来抵消补光灯点亮后的亮度跳变。
一次切换的顺序如下。过渡时间内不再判断。过渡时间走完的那一帧只完成状态切换,这一帧不做亮度判断。
开始切到夜视:
ir_enable置真,饱和度设为 0,并停止饱和度、白平衡、色温和色彩校正。同时写入night_awb、night_ccm、night_red_gain和night_blue_gain。随后等待day_switch_night_time_us,再进入夜视状态。开始切回白天:
ir_enable置假。饱和度和色彩模块仍停止,画面保持黑白和夜间色彩参数。随后等待night_switch_day_time_us。过渡结束后重新打开饱和度、白平衡、色温和色彩校正。这些模块在下一次处理时按自己的调参表重发:饱和度、色彩校正和色温的表索引置为-1,白平衡清掉已应用的统计窗。
日夜若要使用两份 IPA JSON,由应用调用 esp_video_isp_pipeline_set_ipa_config() 更换。红外算法不会自行更换配置。
白天 ——持续偏暗——> 切到夜视(过渡)——过渡结束——> 夜视
^ │
│ │ 持续偏亮,且 AWB 的 R、G 非 0
└——过渡结束—— 切回白天(过渡) <———————————————+
硬件需求
软件门限只能在硬件已经确定之后做补偿。传感器近红外响应、镜头透过率、滤光片方案和补光灯没就绪时,先不要调 IPA 参数,也不要把虚焦、看不清、来回切换都当成算法问题。
相机传感器选型要点
标准 CMOS / CCD 对近红外有响应,硅在 350–1050 nm 都能感光,但近红外量子效率(QE)差异很大:
普通消费级 CMOS:850 nm 处 QE 大约只有 20%~30%,940 nm 处更低。
近红外增强型 CMOS:加厚硅外延层、采用背照式结构或像素内光陷阱后,850 nm 处 QE 可以大于 35%。
备注
波长越长,硅的吸收系数越低,需要的吸收深度越大。在有限的感光层厚度下,940 nm 的 QE 通常低于 850 nm。
选型时查阅传感器数据手册中的 QE 曲线,确认目标波长下的量子效率。
下图是 SC2336 的相对量子效率曲线。可见光段 R / G / B 差异明显;进入近红外后各通道逐渐重合并下降。850 nm 附近仍有可用响应,接近 940 nm 后继续走低。换传感器时按该传感器手册中的曲线核对,不要套用这张图上的数值。
SC2336 相对量子效率曲线
光学设计
镜头:镜片镀膜和粘合胶必须透过近红外。普通可见光镜头在 850 nm 以后透过率会下降。对夜视画质要求高时,使用红外校正镜头(IR-corrected)。
焦点偏移:移开红外线截止滤光片后,红外光与可见光不在同一焦平面,夜视画面会虚焦。对夜视画质要求高时,用红外校正镜头补偿,或在切到夜间时触发一次自动对焦。软件无法消除这种光学虚焦。
滤光片:常见有三种配置。
固定红外线截止滤光片:始终阻挡红外,白天色彩准确,没有夜视。
双滤光片切换(ICR):白天红外线截止滤光片到位,夜间移出并换上全透片。安防监控通常用这种,本方案驱动的也是这种。
去掉截止滤光片并加装 850 nm 带通滤镜:只让目标波段通过,用于专用红外系统。
补光系统
完全黑暗时,传感器本身没有可用信号,必须主动红外补光。流水线在 ir_enable 变化的那一帧同时设置滤光片和补光灯。未接入这路控制的灯仍须与滤光片保持同一日夜状态。
850 nm 红外 LED:感光效率高,灯面能看到红点,适合一般监控。
940 nm 红外 LED:肉眼看不见,传感器 QE 更低,同等功率下照射距离更短。
功率与距离:标称 30 m 的红外相机,实际有效距离通常只有 15–20 m。草丛和树叶会散射、吸收红外光,看清细节需要更近的距离或更高的功率。波长选定后,用
night_ir_factor补偿由此带来的亮度差。
ISP 与图像处理
夜间 ISP 保持原输出格式,去马赛克等模块仍按原流水线处理。黑白画面来自饱和度被写成 0。夜间的白平衡统计窗、色彩校正矩阵和红蓝增益来自 night_awb、night_ccm、night_red_gain 和 night_blue_gain。回到白天的过渡结束后,对应模块按自己的调参重新下发。
滤光片由 V4L2_CID_IRCUT_MODE 切换,补光灯由 V4L2_CID_IR_LED_BRIGHTNESS 设为最大或最小亮度。这两项与输出格式无关,并在 ir_enable 变化的同一帧下发。
近红外图像还需要镜头阴影校正、降噪、增益控制和曝光自适应,否则噪点会很重。夜视期间白平衡和色温已经停止,这段时间主要让亮度收敛。
如何使用
先按上一节装好传感器、镜头、滤光片和补光灯,再按下面的顺序接入软件。ISP 流水线控制器会在算法给出结果后设置滤光片、补光灯、饱和度和夜间色彩参数。
1. 使能驱动与算法
打开红外线截止滤光片驱动、补光灯驱动、视频设备上的滤光片与补光灯控制、ISP 流水线和红外算法。滤光片和补光灯目前由 MIPI-CSI 视频设备提供,补光灯选项依赖滤光片。
Component config --->
Espressif Camera Sensors Configurations --->
Camera IRCUT Control Configuration --->
[*] AP1511B --->
Camera LED Control Configuration --->
[*] IR2835
Espressif Video Configuration --->
[*] Enable MIPI-CSI based Video Device --->
[*] Enable MIPI-CSI IR-Cut Support
[*] Enable MIPI-CSI LED Support
[*] Enable ISP based Video Device --->
[*] Enable ISP Pipeline Controller
Espressif Image Process Algorithm Configuration --->
[*] IR Algorithm
AP1511B 的切换稳定时间默认 1000 ms,与芯片 CE 引脚上的电容有关。滤光片动作慢或切换后偶发卡滞时,加大该时间。算法里的过渡时间应不短于滤光片实际到位时间。
2. 填写初始化引脚
在 esp_video_init() 使用的 MIPI-CSI 配置里挂上滤光片和补光灯。ircut_chip_id 填 0 表示启用。不接滤光片时不要填写 ircut_config,或把 ircut_chip_id 设为 255。不接补光灯时不要填写 led_config,或把 gpio_ctrl 设为 -1。未使用的引脚填 -1。
static esp_video_init_ircut_config_t s_ircut_config = {
.ircut_chip_id = 0,
.fbc_pin = GPIO_NUM_10, /* FBC,未连接则填 -1 */
.en_pin = GPIO_NUM_11, /* EN,未连接则填 -1 */
};
static esp_video_init_led_config_t s_led_config = {
.gpio_ctrl = GPIO_NUM_12, /* 控制脚,未连接则填 -1 */
.gpio_en = GPIO_NUM_13, /* 使能脚。IR2835 不驱动该脚,未连接则填 -1 */
};
static const esp_video_init_csi_config_t s_csi_config = {
.ircut_config = &s_ircut_config,
.led_config = &s_led_config,
/* SCCB、reset、pwdn 等按传感器要求填写 */
};
示例工程可在 Example Video Initialization Configuration 中打开 Enable IR-Cut Control 与 Enable LED Control,并填写滤光片 FBC、EN 以及灯的控制脚、使能脚。
3. 在 IPA JSON 末尾加入红外参数
把 ir 写入该传感器的 IPA JSON(esp_cam_sensor/sensors/<sensor>/cfg/ 中对应文件),并放在发布 luma_env 的模块之后,通常作为该传感器对象的最后一项。写在前面会读到尚未更新的亮度。
下面的数值只说明相对关系,不能直接当作产品门限。先在基准光源下测出环境亮度,再拉开两套门限。白天、黄昏和开灯夜间各采一段核对。
day_luma_threshold控制进入夜视,要远小于基准光源下的环境亮度。亮度不高于它才算暗,门限越低越不容易进入夜视。night_luma_threshold控制回到白天,要远大于开灯夜间测到的环境亮度。亮度乘night_ir_factor后高于它,才有机会离开夜视。门限越高越不容易回到白天。night_awb、night_ccm和红蓝增益在开始切到夜视时写入。night_awb是夜间白平衡统计窗,不参与日夜判断。
"ir": {
"model": 0,
"model0_param": {
"luma_env": "env.luma.avg",
"day_luma_threshold": 5.0,
"day_switch_night_time_us": 1500000,
"day_keep_time_us": 2000000,
"night_ir_factor": 10.0,
"night_luma_threshold": 50.0,
"night_switch_day_time_us": 3500000,
"night_keep_time_us": 3000000,
"night_awb": {
"green": { "max": 255, "min": 0 },
"rg": { "max": 1.5, "min": 0.5 },
"bg": { "max": 1.5, "min": 0.5 }
},
"night_ccm": {
"matrix": [
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0
]
},
"night_red_gain": 1.0,
"night_blue_gain": 1.0
}
}
参数 |
作用 |
|---|---|
|
算法模型。当前只有 |
|
环境亮度变量名。省略时为 |
|
白天亮度门限,必填。亮度高于它为亮。 |
|
白天偏暗的连续保持时间,单位微秒,必填。保持满才开始切到夜视。 |
|
切到夜视后的过渡时间,单位微秒。省略为 |
|
夜视下比较前乘到环境亮度上。省略为 |
|
夜视亮度门限,必填。乘过 |
|
夜视偏亮且白平衡红、绿通道之和都非 0 的连续保持时间,单位微秒,必填。保持满才开始切回白天。 |
|
切回白天后的过渡时间,单位微秒。省略为 |
|
切到夜视时写入的白平衡统计窗,必填。 |
|
切到夜视时写入的色彩校正矩阵,必填。 |
|
切到夜视时写入的红增益和蓝增益,必填。 |
|
为真时打印每帧亮度和是否跳过。省略为假。发布版本关掉。 |
4. 启动后无需逐帧控制
esp_video_init() 会探测滤光片和补光灯并挂到 MIPI-CSI 视频设备。ISP 流水线运行后,算法决定切换时会自动完成滤光片、补光灯、饱和度和夜间色彩设置。应用按原有流程采集图像即可。
流水线每轮都要发布 luma_env。该变量缺失时,这一帧不开始切换,并清零保持计时。变量停在旧值上时,保持时间按旧亮度继续累计。
只有在不启用红外算法、由应用自己决定日夜时,才对相机设备(MIPI-CSI,不是 ISP 设备)设置 V4L2_CID_IRCUT_MODE:ESP_CAM_IRCUT_MODE_DAY 为白天,ESP_CAM_IRCUT_MODE_NIGHT 为夜视。这条命令只移动滤光片。补光灯亮度用 V4L2_CID_IR_LED_BRIGHTNESS 单独设置,范围来自灯的驱动。红外算法启用后,下一次自动判定会覆盖手动设置的滤光片和灯。
调参注意
硬件未按上一节就绪时,先回到传感器量子效率、镜头和灯。虚焦、看不清、补光不够,都不是门限能补上的。
先固定补光灯是否随夜视开关,再测环境亮度。门限是在灯的开关策略已经确定之后标定的。
白天进夜视偏早:降低
day_luma_threshold,或加长day_keep_time_us。进入夜视要求亮度不高于该门限,门限越高越容易判成暗。夜间不回白天:提高
night_ir_factor,或降低night_luma_threshold。亮度已经高于门限时,再确认白平衡红、绿通道之和是否为 0。没有白点样本会一直留在夜视。在两套门限附近来回切换:拉大两套门限的差距,并加长保持时间和过渡时间。
打开
enable_log后对照实景亮度调整门限。发布版本再关掉。