一、ISP整体流程概述
相机成像的完整链路中,首先,通过设备的光学镜片将光聚焦到传感器上,将光信号转为电信号,然后,通过核心的ISP模块对接收的电信号处理输出可视图像信号,再对图像进行存储和显示。其中,ISP主要功能有噪声去除、坏点去除、去马赛克、白平衡、自动曝光控制等,依赖于ISP模块处理后才能在不同的光学条件下都能较好的还原现场细节,可以说ISP技术在很大程度上决定了摄像机的成像质量。

一般而言,ISP包含以下子模块:从 sensor 端过来的图像是拜尔图像,经过坏点矫正(dead pixel, DPC),黑电平补偿(black level compensation, BLC),去噪(denoise),镜头矫正(lens shading correction,LSC),白平衡(auto white balance, awb),去马赛克(demosaic),色彩校正(color correction matrix,CCM),HDR/Tone Mapping,gamma矫正,边缘增强(edge enhance,EE)色彩空间变化(color space manipulation, CSM)等输出 YUV( 或者 RGB) 格式的数据, 再通过 I/O 接口传输到 CPU 中处理。

当然对于一个优秀的ISP处理器,肯定不仅仅局限与上述模块,还会包含其他功能,例如HDR/Tone Mapping等,但本博客聚焦于这些主要模块,其他模块读者可以自行查阅资料进行了解。
二、分模块介绍及对应算法(含代码)
1. 坏点矫正
从传感器制造的角度来看,由于制造过程的不确定性,如粉尘、制造故障、曝光不完全等,一个图像传感器可能会有一定数量的缺陷像素。
一般来讲,坏点分为三类:第一类是死点,即一直表现为最暗值的点;第二类是亮点,即一直表现为最亮值的点:第三类是漂移点,就是变化规律与周围像素明显不同的像素点。由于图像传感器中CFA的应用,每个像素只能得到一种颜色信息,缺失的两种颜色信息需要从周围像素中得到。如果图像中存在坏点的话,那么坏点会随着颜色插补的过程往外扩散,直到影响整幅图像。因此必须在颜色插补之前进行坏点的消除。
坏点校正功能分为两个步骤:首先检测有缺陷的像素,然后是用插值值替换缺陷。

检测是否存在换点通常是通过判断中心点P0和周围像素点之间的插值是否超大于某个预定义好的阈值thres来确定。若为坏点,有两种方式:
一种是计算领域像素均值作为坏点P0的值,即P0 = (P2 + P4 + P5 + P7) / 4

另一种是基于梯度的滤波,首先计算相邻像素在不同方向上的梯度:
dh = |2P0 - P4 - P5|, dv = |2P0 - P2 - P7|
ddr = |2P0 - P3 - P6|, ddl = |2P0 - P1 - P8|
计算得到不同方向梯度后,选择最小梯度方向的邻域像素求均值进行插值:

两种方法实现代码如下:
import numpy as np
import cv2
def dpc_mean(img, thres=30):
img_pad = np.pad(img, (2, 2), 'reflect')
raw_h, raw_w = img.shape
dpc_img = np.empty((raw_h, raw_w), np.uint16)
# change uint16 to int_, still exists overflow warning in the following abs calculation
for x in range(img_pad.shape[0] - 4):
for y in range(img_pad.shape[1] - 4):
p0 = img_pad[x + 2, y + 2].astype(int)
p1 = img_pad[x, y].astype(int)
p2 = img_pad[x, y + 2].astype(int)
p3 = img_pad[x, y + 4].astype(int)
p4 = img_pad[x + 2, y].astype(int)
p5 = img_pad[x + 2, y + 4].astype(int)
p6 = img_pad[x + 4, y].astype(int)
p7 = img_pad[x + 4, y + 2].astype(int)
p8 = img_pad[x + 4, y + 4].astype(int)
if (abs(p1 - p0) > thres) and (abs(p2 - p0) > thres) and (abs(p3 - p0) > thres) \
and (abs(p4 - p0) > thres) and (abs(p5 - p0) > thres) and (abs(p6 - p0) > thres) \
and (abs(p7 - p0) > thres) and (abs(p8 - p0) > thres):
p0 = (p2 + p4 + p5 + p7) / 4
dpc_img[x, y] = p0.astype('uint16')
img = dpc_img
img = np.clip(img, 0, 1024).astype(np.float32)
re

本文介绍了ISP整体流程,其在相机成像中起关键作用,决定成像质量。还分模块介绍了坏点矫正、黑电平补偿、去噪等功能及对应算法,如均值滤波、灰度世界白平衡算法等,并给出部分算法的Python实现代码,为ISP图像处理提供了全面的技术参考。
&spm=1001.2101.3001.5002&articleId=132831818&d=1&t=3&u=e96e31aa964b42f2988e5d8c0403c8f4)
1万+

被折叠的 条评论
为什么被折叠?



