ISP之DPC(坏点校正)模块

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后图片 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在Matlab中进行坏点校正可以使用静态坏点校正和动态坏点校正两种方法。静态坏点校正是基于已有的静态坏点表,比较当前点的坐标是否与静态坏点表中的某个坐标一致,若一致则判定为坏点,然后再计算校正结果对其进行校正。然而,静态坏点校正的实用性不是很强,因为每个sensor的坏点都不一样,需要sensor厂商给出每个sensor的静态坏点表,但是很多sensor厂商并没有给出。另外,静态坏点校正有大小的限制,不可以无限制的校正。\[1\] 另一种方法是图像的坏点校正(DPC),通常在Bayer域进行。如果Bayer域为R/G/B三通道,则分别进行坏点校正;如果Bayer域为RGBIR格式,则分别对R/Gr/Gb/B四通道独立进行。动态坏点校正和静态坏点校正是两个相互独立的过程,可以同时开启,也可以只开启一个,根据需要进行设置。\[2\] 总的来说,坏点校正的目的是修复图像中的坏点,特别是对于一些低成本、消费品的sensor来说,坏点数会比较多。坏点校正可以提高图像的清晰度和完整性,使得图像更加准确和可靠。\[3\] #### 引用[.reference_title] - *1* *2* *3* [图像处理之坏点校正及源码实现](https://blog.csdn.net/weixin_35426022/article/details/116021718)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值