ISP之DPC(坏点校正)模块

2023-10-27

DPC - Defective Photosites Correction即坏点校正

一、DPC的意义

图像传感器上由于自身工艺技术造成的瑕疵,如光线采集的点存在缺陷,导致在光电转换过程中某些像素值不准确,我们称之为坏点(Defect Pixel)。尤其是对于低成本的sensor来说,坏点数为100 或者1000ppm(parts per million,百万分之一)是正常的。若sensor中存在坏点,经过图像的插值(如demosaic)和滤波等非线性过程,坏点的尺寸会变大(坏点扩散),而且由于色彩校正和串扰补偿,坏点处颜色的强度和饱和度也会明显提高,因此需要在其他模块执行之前对坏点进行校正,坏点一般分为静态坏点和动态坏点。

  • 静态坏点:
    • 亮点:亮点的亮度值明显大于入射光乘以相应比例,随着曝光时间的增加,该点的亮度会显著增加;
    • 暗点:接近于0。
  • 动态坏点:在一定像素范围内,该点表现正常,而超过这一范围,该点表现的比周围像素要亮。动态坏点与sensor 温度、gain值有关,sensor 温度升高或者gain 值增大时,动态坏点会变的更加明显。

坏点的存在一方面会影响图像的画质,另一方面,在某些应用场景下可能会影响CV的识别准确率,因此一般需要对DPC进行矫正。但是DPC的矫正也会带来相应的副作用,例如锐度下降,图像细节损失等,所以进行合适的DPC矫正是必要的。

二、DPC一般怎么实现

  • 依赖标定的方法 - 主要校正静态坏点

静态坏点的校正是基于已有的静态坏点表(静态坏点表一般由sensor厂商提供),比较当前点的坐标是否与静态坏点表中的某个坐标一致,若一致则判定为坏点,然后再采用中值滤波的方法对其进行校正。一般来说,每颗sensor的静态坏点都可以百分百矫正,但这样做对sensor厂商会增加成本,所以对于低成本的sensor来说,由于成本和时间的限制,sensor制造商没有检测sensor的坏点信息,因此需要用户自行对静态坏点进行标定,得到静态坏点表。

  • 不依赖标定的方法 - 主要校正动态坏点

由于存储坏点信息的内存有限,静态坏点校正有可能无法完全校正sensor中的坏点,因此静态坏点校正应当校正对图像质量影响较大的坏点,而动态坏点校正方法则校正其余的坏点。动态坏点的校正可以实时的检测和校正sensor 的亮点与暗点,并且校正的坏点个数不受限制。动态坏点校正相对静态坏点校正具有更大的不确定性。动态坏点校正可以分为两个步骤:坏点检测和坏点校正。

三、代码实现

1、读取RAW图像文件

由于我自己采集到的RAW文件是.dng格式而不是.raw格式,在读取的时候也遇到来一些问题,所以先跟大家分享一下raw图的基本知识。

RAW文件是一个数据包文件,而非图像文件。我们的电脑并不知道应该如何解读这种数据包,和JPEG等标准格式不同的是,RAW文件并不包含供电脑解码所需的信息。

和JPEG格式不同的是,RAW格式并没有一个统一的标准。各大厂各行其是,使用的RAW文件格式各不相同,甚至同一厂商不同型号相机之间使用的标准也不一样。

DNG格式是这种混乱局面中的唯一例外,这是一种由Adobe开发的公开文件格式,可供任意数码相机制造商选用。

每一幅DNG图像是以8字节的IFH( Image File Header)开始的,所以说文件中不仅仅包含各像素点的值,还包含一些头文件等信息,我们在去读的时候需要剪掉头文件,仅取出来像素点的值。

由于博主自己采集到的图像坏点较少,为了让大家更清楚的看到坏点校正效果所以又手动添加了一些坏点。

用代码实现:

 
img = np.fromfile(r'/Users/Desktop/IMG_20230719_111556.dng',dtype = 'uint16')
a = len(img)
#原图大小为6016*4512
b = 6016 * 4512
#dng与raw的差别是,dng有头部信息,需要剪掉头部信息才是真实像素值,原图为10bit图像
img1 = img[a-b:a].reshape(4512,6016)
# 转化为8bit图像
img2 = img1/4

#添加坏点
img3 = img2.copy()

for i in range(img3.shape[0]):
   for j in range(img3.shape[1]):
       if random.random() < prob:
          img3[i][j] = 0 if random.random() < 0.0001 else 255
       else:
          img3[i][j] = img3[i][j]

img3.astype(int)

2、校正坏点

2.1 中值滤波

坏点的分布符合我们图像中椒盐噪声的表现(噪声点的灰度值 与邻域像素点具有明显不同,因此在图像中造成过亮或 过暗的像素点, 严重影响图像的视觉质量),所以用中值滤波可以很有效的校正坏点。

用代码直接调用opencv也非常简单,下面是用一个5*5的滤波器进行中值滤波。

中值滤波的基本原来是:用一个X*X(X为奇数)的滤波器在画面中进行滤波,用滤波器中X*X点的中值代替(i,j)的值,实现坏点校正。

img4 = cv2.medianBlur(np.uint8(img3),5)

2.2识别坏点并校正坏点

中值滤波去除坏点简单有效,但是会存在一个问题,如果图像中并没有坏点,但是经过中值滤波后反而会损失细节。

如何避免细节的损失呢,我们可以用先识别坏点,然后再去除坏点的方法,尽可能的保留纹理。

  • 坏点识别
    • 图像中某像素坐标为(i, j)
    • 用(i,j)和它周围的8个像素比较
    • 若(i,j)与周围8个像素点的差异均大于1,那么判定该点为坏点
  • 考虑梯度的坏点校正
    • 计算2*(i,j)与水平、垂直及两条对角线的差值(dv,dh,ddl,ddr)
    • 判断边缘,比较(dv,dh,ddl,ddr)中最小的值
    • 为(i,j)赋值
    #考虑边缘:识别坏点并校正坏点
    thred = 1
    t = 0
    img4 = img3.copy()

    #坏点识别

       for i in range(1, img4.shape[0] - 1):
        for j in range(1, img4.shape[1] -1):
            P = img4[i-1:i+2,j-1:j+2].copy()


            different_value = np.abs(P - P[1,1])          
            compare = (different_value / P2) > thred
            number = np.count_nonzero(compare)

            if number == 8:
                dv = abs(2 * P[1,1] - P[0,1] - P[2,1])
                dh = abs(2 * P[1,1] - P[1,0] - P[1,2])
                ddl = abs(2 * P[0,0] - P[0,0] - P[2,2])
                ddr = abs(2 * P[1,1] - P[2,0] - P[0,2])
                t = t + 1
                if (min(dv, dh, ddl, ddr) == dv):
                    img4[i, j] = (P[0,1] + P[2,1]) / 2
                elif (min(dv, dh, ddl, ddr) == dh):
                    img4[i, j] = (P[1,0] + P[1,2]) / 2
                elif (min(dv, dh, ddl, ddr) == ddl):
                    img4[i, j] = (P[0,0] + P[2,2]) / 2
                else:
                    img4[i, j] = (P[0,2] + P[2,0]) / 2

四、结果

坏点图片

DPC后图片 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ISP之DPC(坏点校正)模块 的相关文章

随机推荐

  • 自定义滚动条@莫成尘

    先看代码 复制使用即可 以下代码均可复制粘贴使用 我将以注释的形式解释代码左右 您将看到以下效果 原生的滚动条比较方正 不够圆滑 很大程度上不能满足我们的审美 有时候需要修改其样式 滚动条的高度将随着内容的多少自适应
  • GOTC演讲回顾

    5月27 28日 由上海浦东软件园 开放原子开源基金会 Linux基金会亚太区和开源中国联合发起的2023全球开源技术峰会 Global Open source Technology Conference GOTC 在上海圆满召开 大会聚焦
  • Redis IO 多路复用底层的实现原理

    文章目录 前言 用户空间与内核空间 PIO 和 DMA PIO DMA 缓存I O和直接I O 缓存I O的读写操作 缓存I O的优点 缓存I O的缺点 直接I O的优点 IO的访问方式 磁盘IO 网络IO 磁盘IO和网络IO对比 同步IO
  • AG表格基础滚动分页-React版本

    AG表格滚动分页文档 AG表格在使用滚动分页时 不可使用rowData属性做为数据源 传入表格 因为AG的滚动分页 使用的是特殊表模型 所有正常模型下的API有可能会失效 使用AG滚动分页时 需把正常数据模型替换成滚动分页数据模型 示例 t
  • 30天自制操作系统学习-第2天

    第二天主要学习汇编语言与Makefile入门 1 继续开发 在这里先给出作者在第二天使用nask编写代码中涉及到的寄存器概念 AX accumulator 累加寄存器 CX counter 计数寄存器 DX data 数据寄存器 BX ba
  • 反射工具类导入Excel数据到数据库

    1 工作类代码 import org apache poi hssf usermodel HSSFWorkbook import org apache poi ss usermodel import org apache poi xssf
  • ubuntu20.04换国内清华源和安装docker

    写在前面 安装好ubuntu双系统后 默认的软件更新源是国外的 在国内使用速度很慢 用 apt install xxx 安装软件时可能出现 网络不可达 你的网络需要认证吗 无法定位软件包 等错误 所以我们需要更换成国内的源 这样才能正常安装
  • c++读写文件操作

    程序的运行产生的数据都是临时数据 不能持久的保存 一旦程序运行结束数据就会被释放 在C 中对文件进行操作必须包含头文件
  • Flutter开发中插件使用

    flutter的库是以package的方式来管理的 Package 分为两种 Dart package 它只能使用 Dart 和 Flutter 提供的 API 使用纯dart语言开发 一些Dart包可能包含Flutter特定功能 因此对F
  • chatgpt赋能python:Python编程优化技巧

    Python编程优化技巧 为什么需要编程优化 Python是一种解释性语言 运行速度较慢 编写高效的Python程序是很有必要的 当我们需要处理大量数据 或者运行时间敏感的任务时 优化Python程序对于提高效率是至关重要的 怎样提高Pyt
  • 华为OD机试 C++ 【查字典】

    题目 题目 描述 给你一个 头 就是词的开始部分 和一个单词清单 你需要找出哪些单词是以这个 头 开始的 输出 所有以这个 头 开始的单词 每个单词一行 如果一个都没有 输出 1 输入 abc 4 a ab abc abcd 输出 abc
  • 项目结构的合理性

    以下仅为个人观点 如有好的建议请多多指教 1 有时为了项目以后修改 迭代 或者相似功能的开发 可能会对某些模块进行封装 近期所做的项目整体进行了自动化封装 个人认为封装过度其实是对后续业务并没有太多好处 反而造成项目随着时间的推移 业务发展
  • sessionStorage 问题

    问题描述 列表页点击进详情页的时候数据没加载到 查看前端代码 在跳转的时候取的列表页数据存到sessionStorage里面 function getCollarDetails index var rows coupon list tabl
  • jQuery 入门教程(21): jQuery UI 示例

    上篇介绍了使用jQuery UI基本工作过程 后面就逐个介绍jQuery UI库内置的UI组件 支持的拖放 动画效果等 如果你之前看过Yii Framework教程 PHP Yii Framework封装了jQuery UI组件 有兴趣的可
  • SqlServer 存储过程(生成订单)

    当在 SQL Server 中处理订单时 使用存储过程可以提供更高效和可维护的解决方案 存储过程是一组预编译的 SQL 语句 可以在数据库中执行 并且可以通过参数进行自定义 通过使用存储过程 可以将常见的业务逻辑封装起来 以便在需要时进行重
  • error while loading shared libraries: ../../lib/libopencv_core.so

    error while loading shared libraries lib libopencv core so 原文 http blog chinaunix net uid 27134408 id 5122776 html 最近做Op
  • SonarQube - org.sonar.process.MessageException: Unsupported JDBC driver provider: mysql

    使用docker安装最新的SonarQube 启动SonarQube报错 Exception in thread main org sonar process MessageException Unsupported JDBC driver
  • [shell编程]、()、(())、[]、[[]]的区别

    默认的变量类型是字符串 所以 str1 str2 就是一串字符串 我们想要判断它们是否相等必须使用中括号 str1 str2 1 中括号 表示条件测试 注意这里的空格很重要 要注意在 后面和 前面都必须要有空格 常用判断 d FILE 如果
  • 企业为什么要融资和上市

    这里面涉及到两个概念 即融资和上市 让我们先来理理这两者之间的逻辑辩证关系 其实根据我们的观察和调研发现 目前市场上许多人对上市这件事有着十分魔性的认知 小A觉得上市前融资轮次越多越好 小B认为上市后就是为了圈钱 小C觉得IPO的速度越快越
  • ISP之DPC(坏点校正)模块

    DPC Defective Photosites Correction即坏点校正 一 DPC的意义 图像传感器上由于自身工艺技术造成的瑕疵 如光线采集的点存在缺陷 导致在光电转换过程中某些像素值不准确 我们称之为坏点 Defect Pixe