图像信号处理器(ISP)基础算法及处理流程

在这里插入图片描述

💪 专业从事且热爱图像处理,图像处理专栏更新如下👇:
📝《图像去噪》
📝《超分辨率重建》
📝《语义分割》
📝《风格迁移》
📝《目标检测》
📝《暗光增强》
📝《模型优化》
📝《模型实战部署》


在这里插入图片描述

传统的ISP(Image Signal Processing)图像处理算法涵盖了从图像传感器(通常是CMOS或CCD传感器)获取原始图像数据到生成最终显示图像的全过程。以下是一些常见的传统ISP图像处理算法处理步骤。

目录

  • 一、黑电平校正(Black Level Correction)
    • 1.1 代码
  • 二、去噪(Denoising)
    • 2.1 固定模式噪声校正
    • 2.2 随机噪声去除
    • 2.3 代码
  • 三、白平衡(White Balance)
    • 3.1 灰世界算法(Gray World Algorithm)
    • 3.2 完美反射算法(Perfect Reflector Algorithm)
    • 3.3 代码
  • 四、去马赛克(Demosaicing)
    • 4.1 代码
  • 五、伽玛校正(Gamma Correction)
    • 5.1 代码
  • 六、色彩校正(Color Correction)
    • 6.1 色彩空间转换
    • 6.2 色彩矩阵处理
    • 6.3 代码
  • 七、锐化(Sharpening)
    • 7.1 拉普拉斯锐化
    • 7.2 非线性锐化
    • 7.3 代码
  • 八、色彩空间转换(Color Space Conversion)
    • 8.1 代码
  • 九、色调映射(Tone Mapping)
    • 9.1 局部色调映射
    • 9.2 全局色调映射
    • 9.3 代码
  • 十、变换(Transformations)
    • 10.1 代码
  • 十一、校准和矫正(Calibration and Correction)
    • 11.1 镜头畸变校正
    • 11.2 色差校正
    • 11.3 遮光校正
    • 11.4 代码
  • 十二、自动对焦(Autofocus)
    • 12.1 对比度检测
    • 12.2 相位检测
    • 12.3 代码
  • 十三、曝光控制(Exposure Control)
    • 13.1 代码
  • 十四、自动增益控制(Auto Gain Control, AGC)
    • 14.1 代码
  • 十五、动态范围压缩(Dynamic Range Compression, DRC)
    • 15.1 局部动态范围压缩
    • 15.2 全局动态范围压缩
    • 15.3 代码
  • 十六、总结

一、黑电平校正(Black Level Correction)

目的:在图像传感器捕获的原始图像中,可能存在黑电平偏移。这一步校正这些偏移,使得黑电平值归零,从而提高图像的动态范围。

步骤:

传感器捕获的原始图像可能包含偏移的黑电平值。
计算或查找黑电平值。
从每个像素值中减去黑电平值,使得图像黑电平归零。

1.1 代码

def black_level_correction(image, black_level=16):
    return np.clip(image - black_level, 0, 255).astype(np.uint8)

black_level_corrected_image = black_level_correction(image)
cv2.imwrite('black_level_corrected_image.jpg', black_level_corrected_image)

二、去噪(Denoising)

抑制图像中的各种噪声,如固定模式噪声(FPN)和随机噪声。

步骤:

2.1 固定模式噪声校正

固定模式噪声是由传感器中各像素的响应不均匀引起的。
使用暗帧(captured when no light is entering the sensor)来校正固定模式噪声。

2.2 随机噪声去除

随机噪声通常包括热噪声和读出噪声。
使用滤波技术(如中值滤波、均值滤波或高斯滤波)来抑制随机噪声。

2.3 代码

下面给出通过高斯模糊去噪的例子:

import cv2
import numpy as np

def denoise_image(image):
    return cv2.GaussianBlur(image, (5, 5), 0)

image = cv2.imread('input_image.jpg')
denoised_image = denoise_image(image)
cv2.imwrite('denoised_image.jpg', denoised_image)

三、白平衡(White Balance)

白平衡算法调整图像的色温,以确保图像在各种照明条件下颜色的准确性。常见的白平衡方法包括灰世界算法(Gray World Algorithm)和完美反射算法(Perfect Reflector Algorithm)。

步骤:

3.1 灰世界算法(Gray World Algorithm)

假设图像中所有颜色的平均值应该是中性的灰色。
计算图像中红、绿、蓝三通道的平均值。
根据平均值的偏差,调整各通道的增益使其均衡。

3.2 完美反射算法(Perfect Reflector Algorithm)

假设图像中存在一个完美反射的白色物体。
使用该物体的颜色作为白平衡参考点,调整其他颜色的增益。

3.3 代码

def white_balance(image):
    result = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    avg_a = np.average(result[:, :, 1])
    avg_b = np.average(result[:, :, 2])
    result[:, :, 1] = result[:, :, 1] - ((avg_a - 128) * (result[:, :, 0] / 255.0) * 1.1)
    result[:, :, 2] = result[:, :, 2] - ((avg_b - 128) * (result[:, :, 0] / 255.0) * 1.1)
    return cv2.cvtColor(result, cv2.COLOR_LAB2BGR)

white_balanced_image = white_balance(denoised_image)
cv2.imwrite('white_balanced_image.jpg', white_balanced_image)

四、去马赛克(Demosaicing)

大多数图像传感器使用拜耳(Bayer)滤色器阵列,因此捕获的图像是单色图像(每个像素只记录一种颜色)。去马赛克算法将这些单色图像转换为全彩色图像。

步骤:

传感器使用拜耳滤色器阵列捕获图像,每个像素只记录一种颜色(红、绿或蓝)。

插值算法(Interpolation Algorithms):
最简单的方法是线性插值。
更复杂的方法包括双向插值、边缘方向插值和加权方向插值。

4.1 代码

去马赛克将拜耳阵列转换为RGB图像。

def demosaic(image):
    return cv2.cvtColor(image, cv2.COLOR_BAYER_BG2BGR)

demosaiced_image = demosaic(black_level_corrected_image)
cv2.imwrite('demosaiced_image.jpg', demosaiced_image)

五、伽玛校正(Gamma Correction)

伽玛校正用于调整图像的亮度,以匹配显示设备的特性。它将线性传感器数据转换为非线性,以更好地反映人眼对亮度的感知。

步骤:

原始图像数据通常是线性响应的。
应用非线性伽玛曲线将线性数据转换为伽玛校正后的数据。
常见的伽玛值为2.2(对于sRGB显示设备)。

5.1 代码

加粗样式

def gamma_correction(image, gamma=1.0):
    invGamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
    return cv2.LUT(image, table)

gamma_corrected_image = gamma_correction(color_corrected_image, gamma=2.2)
cv2.imwrite('gamma_corrected_image.jpg', gamma_corrected_image)

六、色彩校正(Color Correction)

色彩校正包括色彩空间转换和色彩矩阵处理,以确保图像的颜色准确性。

步骤:

6.1 色彩空间转换

将原始RGB数据转换为目标色彩空间(如sRGB)。

6.2 色彩矩阵处理

应用色彩校正矩阵,调整图像的颜色分布。
该矩阵通常根据摄像头和显示设备的色彩特性预先计算。

6.3 代码

def color_correction(image, red_gain=1.0, green_gain=1.0, blue_gain=1.0):
    b, g, r = cv2.split(image)
    b = cv2.multiply(b, blue_gain)
    g = cv2.multiply(g, green_gain)
    r = cv2.multiply(r, red_gain)
    return cv2.merge([b, g, r])

color_corrected_image = color_correction(white_balanced_image, red_gain=1.1, green_gain=1.0, blue_gain=1.2)
cv2.imwrite('color_corrected_image.jpg', color_corrected_image)

七、锐化(Sharpening)

锐化算法用于增强图像的细节和边缘,使图像看起来更加清晰。常用的方法包括拉普拉斯锐化和非线性锐化。

步骤:

7.1 拉普拉斯锐化

使用拉普拉斯算子计算图像的二阶导数,增强边缘。

7.2 非线性锐化

使用非线性滤波器,如高斯拉普拉斯(LoG)滤波器,增强细节。

7.3 代码

图像锐化可以通过卷积操作来实现。

def sharpen_image(image):
    kernel = np.array([[0, -1, 0],
                       [-1, 5, -1],
                       [0, -1, 0]])
    return cv2.filter2D(image, -1, kernel)

sharpened_image = sharpen_image(gamma_corrected_image)
cv2.imwrite('sharpened_image.jpg', sharpened_image)

八、色彩空间转换(Color Space Conversion)

将图像从一种色彩空间转换到另一种色彩空间,例如从RGB到YCbCr,以便于压缩和显示。

步骤:

常见的色彩空间转换包括RGB到YCbCr。
这种转换有助于压缩和显示。
使用线性变换矩阵进行转换。

8.1 代码

色彩空间转换将图像从一种色彩空间转换到另一种。

def convert_color_space(image, conversion_code=cv2.COLOR_BGR2YCrCb):
    return cv2.cvtColor(image, conversion_code)

color_converted_image = convert_color_space(demosaiced_image, cv2.COLOR_BGR2YCrCb)
cv2.imwrite('color_converted_image.jpg', color_converted_image)

九、色调映射(Tone Mapping)

色调映射用于处理高动态范围(HDR)图像,将其映射到低动态范围显示设备上,同时保留细节和对比度。

步骤:

9.1 局部色调映射

根据局部亮度调整色调,保留细节。

9.2 全局色调映射

根据整体亮度调整色调,压缩动态范围。

9.3 代码

def tone_mapping(image, gamma=2.2):
    invGamma = 1.0 / gamma
    table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8")
    return cv2.LUT(image, table)

tone_mapped_image = tone_mapping(color_converted_image)
cv2.imwrite('tone_mapped_image.jpg', tone_mapped_image)

十、变换(Transformations)

图像几何变换包括旋转、缩放、平移和镜像等,用于图像的对齐和校正。

步骤:

使用变换矩阵对图像进行几何变换。
常用的变换包括仿射变换、透视变换和投影变换。

10.1 代码

def transform_image(image, angle=0, scale=1.0):
    h, w = image.shape[:2]
    M = cv2.getRotationMatrix2D((w/2, h/2), angle, scale)
    return cv2.warpAffine(image, M, (w, h))

transformed_image = transform_image(tone_mapped_image, angle=15, scale=1.1)
cv2.imwrite('transformed_image.jpg', transformed_image)

十一、校准和矫正(Calibration and Correction)

包括镜头畸变校正、色差校正、遮光校正等,以补偿镜头和传感器引入的各种失真和缺陷。

步骤:

11.1 镜头畸变校正

计算镜头畸变参数(如径向和切向畸变)。
应用畸变校正模型(如鱼眼校正)校正图像。

11.2 色差校正

校正由于不同波长的光在镜头中折射率不同引起的色差。

11.3 遮光校正

补偿由于镜头遮光引起的图像边缘变暗现象(渐晕)。

11.4 代码

def calibrate_and_correct(image, camera_matrix, dist_coeffs):
    h, w = image.shape[:2]
    new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(camera_matrix, dist_coeffs, (w, h), 1, (w, h))
    corrected_image = cv2.undistort(image, camera_matrix, dist_coeffs, None, new_camera_matrix)
    x, y, w, h = roi
    return corrected_image[y:y+h, x:x+w]

# 示例相机矩阵和畸变系数
camera_matrix = np.array([[800, 0, 320], [0, 800, 240], [0, 0, 1]], dtype=np.float32)
dist_coeffs = np.array([-0.2, 0.1, 0, 0], dtype=np.float32)

calibrated_image = calibrate_and_correct(transformed_image, camera_matrix, dist_coeffs)
cv2.imwrite('calibrated_image.jpg', calibrated_image)

十二、自动对焦(Autofocus)

自动对焦算法根据图像内容调整镜头位置,以确保图像的清晰度。

步骤:

12.1 对比度检测

通过检测图像的对比度最大化来实现自动对焦。

12.2 相位检测

使用相位检测传感器快速确定对焦位置。

12.3 代码

def auto_focus(image):
    # 示例:评估图像的拉普拉斯变换的方差,作为对焦度的度量
    focus_measure = cv2.Laplacian(image, cv2.CV_64F).var()
    return focus_measure

focus_value = auto_focus(calibrated_image)
print(f"Focus measure: {focus_value}")

十三、曝光控制(Exposure Control)

根据场景亮度调整曝光时间和增益,以获得最佳亮度的图像。

步骤:

自动曝光(Auto Exposure, AE):
测量场景的整体亮度。
根据预设的曝光策略调整曝光参数(快门速度、光圈和ISO感光度)。

13.1 代码

def adjust_exposure(image, target_brightness=128):
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    current_brightness = np.mean(gray)
    correction_factor = target_brightness / current_brightness
    return np.clip(image * correction_factor, 0, 255).astype(np.uint8)

exposure_adjusted_image = adjust_exposure(calibrated_image)
cv2.imwrite('exposure_adjusted_image.jpg', exposure_adjusted_image)

十四、自动增益控制(Auto Gain Control, AGC)

调整图像传感器的增益,以确保在不同光照条件下图像的亮度。

步骤:

增益调整:
根据测量到的图像亮度,动态调整传感器的增益。

14.1 代码

自动增益控制用于调整图像的对比度。

def auto_gain_control(image, clip_limit=2.0, tile_grid_size=(8, 8)):
    lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    lab_planes = cv2.split(lab)
    clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=tile_grid_size)
    lab_planes[0] = clahe.apply(lab_planes[0])
    lab = cv2.merge(lab_planes)
    return cv2.cvtColor(lab, cv2.COLOR_LAB2BGR)

gain_adjusted_image = auto_gain_control(exposure_adjusted_image)
cv2.imwrite('gain_adjusted_image.jpg', gain_adjusted_image)

十五、动态范围压缩(Dynamic Range Compression, DRC)

压缩图像的动态范围,以适应显示设备的能力。

步骤:

15.1 局部动态范围压缩

在保留细节的情况下压缩亮度范围。

15.2 全局动态范围压缩

调整图像的整体对比度,压缩高光和阴影部分的亮度。

15.3 代码

直方图均衡化对图像的亮度通道(L通道)进行处理,从而实现动态范围压缩。以下是代码的实现步骤:

将图像转换为LAB色彩空间:LAB色彩空间将亮度和色彩分离,便于单独处理亮度。

对L通道进行直方图均衡化:直方图均衡化是一种常见的动态范围压缩技术,通过调整图像亮度分布来增强图像的对比度和细节。

合并通道并转换回BGR色彩空间:处理完L通道后,重新合并LAB通道并转换回BGR色彩空间,以便显示和保存图像。

显示和保存结果图像:使用matplotlib库显示原始图像和处理后的图像,并将结果保存为JPEG文件。

import cv2
import numpy as np
from matplotlib import pyplot as plt

def dynamic_range_compression(image):
    # 将图像转换为LAB色彩空间
    lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
    l, a, b = cv2.split(lab)
    
    # 对L通道进行直方图均衡化
    l_eq = cv2.equalizeHist(l)
    
    # 合并通道并转换回BGR色彩空间
    lab_eq = cv2.merge((l_eq, a, b))
    compressed_image = cv2.cvtColor(lab_eq, cv2.COLOR_LAB2BGR)
    
    return compressed_image

# 读取图像
image = cv2.imread('input_image.jpg')

# 进行动态范围压缩
compressed_image = dynamic_range_compression(image)

# 保存结果图像
cv2.imwrite('compressed_image.jpg', compressed_image)

# 显示原图和处理后的图像
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.title('Original Image')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.subplot(1, 2, 2)
plt.title('Compressed Image')
plt.imshow(cv2.cvtColor(compressed_image, cv2.COLOR_BGR2RGB))
plt.show()

十六、总结

通过以上步骤,ISP图像处理系统能够将传感器捕获的原始图像数据转换为高质量的可视图像,适用于各种应用和显示设备。以上算法只是基础算法,各个板块都可以衍生出独立领域研究,现在更多的研究引入深度学习(AI ISP),与传统方法相比,深度学习方法可以提供更高质量的图像处理效果,并且能够适应复杂多变的图像内容和拍摄环境。

感谢您阅读到最后!😊总结不易,多多支持呀🌹 点赞👍收藏⭐评论✍️,您的三连是我持续更新的动力💖

关注公众号「视觉研坊」,获取干货教程、实战案例、技术解答、行业资讯!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/772163.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FreeRTOS之队列上锁和解锁(详解)

这篇文章将记录我学习实时操作系统FreeRTOS的队列上锁和解锁的知识,在此分享给大家,希望我的分享能给你带来不一样的收获! 目录 一、简介 二、队列上锁函数prvLockQueue() 1、函数初探 2、应用示例 三、队列解锁函…

转让北京文化传媒公司带营业性演出经纪许可证

影视文化传播倡导将健康的影视文化有效传播给观众,从而构建观众与电影制作者的良 性沟通与互动,是沟通电影制作者与电影受众的重要桥梁。影视文化泛指以电影,电视方式所进行的全部文化创造,即体现为电影,电视全部的存在…

找不到msvcp120.dll无法继续执行的原因分析及解决方法

在计算机使用中,经常会遇到msvcp120.dll文件丢失的情况,很多人对这个文件不是很熟悉,今天就来给大家讲解一下msvcp120.dll文件的丢失以及这个文件的重要性,让大家更好地了解计算机,同时也可以帮助我们更好地掌握这个文…

航模插头篇

一、常见的电池插头(电调端 是公头 电池端 是母头) 电池总是被插的 1.XT60头 过流大 安全系数高 难插拔 2.T插 插拔轻松 过流比较小 容易发烫 电调端 是公头 电池端 是母头 3.香蕉头插孔 过流够 插拔轻松 但 容易插反 爆炸 4.TX90(和XT60差…

2024 年 亚太赛 APMCM (A题)中文赛道国际大学生数学建模挑战赛 | 飞行器外形的优化 | 数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时,你是否曾经感到茫然无措?作为2022年美国大学生数学建模比赛的O奖得主,我为大家提供了一套优秀的解题思路,让你轻松应对各种难题! 完整内容可以在文章末尾领取! 第一个问…

C++内存管理(候捷)第一讲 笔记

内存分配的每一层面 applications可以调用STL,里面会有allocator进行内存分配;也可以使用C 基本工具primitives,比如new, new[], new(), ::operator new();还可以使用更底层的malloc和free分配和释放内存。最底层的是系统调用&…

明星代言6个提升企业形象的杀手锏-华媒舍

在当今竞争激烈的商业世界中,企业形象的塑造对于品牌的发展至关重要。而明星代言作为一种常见的营销手段,被广泛使用来提升企业形象和产品销售。本文将介绍明星代言的六个杀手锏,帮助您了解如何通过明星代言来提升企业形象。 1. 拥有广泛的影…

十二、【源码】Spring整合AOP

源码地址:https://github.com/spring-projects/spring-framework 仓库地址:https://gitcode.net/qq_42665745/spring/-/tree/12-spring-aop Spring整合AOP 核心类: DefaultAdvisorAutoProxyCreator:用于在Spring框架中自动为符…

若依多数据源原理分析

首先,想明白不同的接口想要使用不同的数据源。 那么自然想到了AOP,自定义注解。 通过自定义注解标注当前方法到底使用的是哪个数据源。 上面是前置条件。 看下若依是怎么处理的: 1.定义自定义注解,以及对应的多数据源的枚举类…

天润融通分析AI技术助力客户服务,实现满意度三倍增长

如今,客户体验越来越成为影响客户决策的核心要素。 对于企业来讲,客户在不同触点的每一次互动体验,都成为塑造品牌声誉的“Aha时刻”。但同时,随着社会的发展的加速,客户的需求也在日新月异,给企业带来挑战…

Codeforces Round 955 (Div. 2, with prizes from NEAR!)(A~C题解)

这场比赛怎么说呢,一开始打的还算好,能进前1000,但是后面就被卡住了,这个确实没办法水平还是不够,学过的还是没想起来,后面继续练 A. Soccer 题解:水题一个,想要在过程中出现平局的…

web零碎知识

&nbsp 在html文件中 连续的空格会被认为是一个空格 所以我们需要使用&nbsp来代表空格 &#x3000 把这个当成tab键来使用 我们可以引入js文件,就可以减少html文件的长度。 首先创建一个js文件夹,然后在js文件夹中创建一个,后缀…

【第17章】MyBatis-Plus自动维护DDL

文章目录 前言一、功能概述二、注意事项三、代码示例四、实战1. 准备2. ddl配置类3. 程序启动4. 效果(数据库) 总结 前言 在MyBatis-Plus的3.5.3版本中,引入了一项强大的功能:数据库DDL(数据定义语言)表结构的自动维护。这一功能…

【电路笔记】-B类放大器

B类放大器 文章目录 B类放大器1、概述2、B类放大器介绍3、推挽式配置4、限制交叉失真5、B类放大器效率6、总结1、概述 我们在之前的文章中已经知道,A 类放大器的特点是导通角为 360,理论最大效率为 50%。 在本文中,我们将详细介绍另一类放大器,称为B类放大器,它是为解决A…

康姿百德磁性床垫好不好,效果怎么样靠谱吗

康姿百德典雅款床垫,打造舒适睡眠新体验 康姿百德床垫是打造舒适睡眠新体验的首选,其设计能够保护脊椎健康,舒展脊椎,让您享受一夜好眠。康姿百德床垫的面料选择也非常重要,其细腻亲肤的针织面料给您带来柔软舒适的触…

A*——AcWing 179. 八数码

A* 定义 A* 算法是一种在图形或地图中寻找最短路径的启发式搜索算法。它通过综合考虑起始节点到当前节点的实际代价和当前节点到目标节点的预估代价,来决定下一步的搜索方向。 运用情况 路径规划:如在地图导航中为车辆、行人规划最优路线。游戏开发&…

旅游系统(附管理端+前台)PHP源码

一. 前言 今天小编给大家带来了一款可学习,可商用的,旅游系统 源码,支持二开,无加密。支持景点管理,登录,景点预定,意见反馈,统计等功能。详细界面和功能见下面视频演示。 二. 视频…

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势 在数字化时代,广告投放已成为各行各业不可或缺的一部分,特别是在游戏行业,如何有效地推广游戏产品,吸引玩家的眼球,成为了每一个游戏开发商和广告主所关注的焦…

DllImport进阶:参数配置与高级主题探究

深入讨论DllImport属性的作用和配置方法 在基础篇中,我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…

TreeSize Free - 硬盘空间管理工具

TreeSize FreeTreeSize Free 是一款免费的强大灵活的硬盘空间管理工具。可以帮你找出硬盘上最大的目录以及它占用的空间。支持空间大小显示、分配空间和占用空间、文件数、3D工具条和分配图、最近使用数据、文件作者、NTFS压缩率等信息,并支持搜索文件。该软件类似浏…