DPC_PINTO算法
DPC_PINTO算法通过检查坏点的邻近像素来校正坏点。如果像素被判定为坏点,则用其周围像素的中值替换。该算法主要包含以下步骤:
- 读取原始图像:从文件中加载原始拜耳图像。
- 扩展图像:扩展图像以处理边界条件。
- 检测和校正坏点:使用邻近像素检测和校正坏点。
- 显示结果:可视化原始图像和校正后的图像
实现
步骤1:读取原始图像
首先,我们定义一个函数从文件中读取原始图像数据。图像以二进制格式存储,我们将其重塑为正确的维度。
-
import numpy as np import cv2 import time import matplotlib.pyplot as plt def read_raw(file_path, bayer_bits, row, col): with open(file_path, 'rb') as f: raw_data = np.fromfile(f, dtype=np.uint8 if bayer_bits == 8 else np.uint16) raw_data = raw_data.reshape((row, col)) return raw_data
步骤2:扩展图像
接下来,我们扩展图像以便于处理边界条件。这确保了算法在处理边缘像素时不会遇到索引问题
def expand_raw(img, expand_num): if expand_num % 2 != 0: raise ValueError('expand_num must be an even number!') height, width = img.shape img_expand = np.zeros((height + expand_num * 2, width + expand_num * 2), dtype=img.dtype) img_expand[expand_num:height + expand_num, expand_num:width + expand_num] = img img_expand[:expand_num, expand_num:width + expand_num] = img[:expand_num, :] img_expand[height + expand_num:, expand_num:width + expand_num] = img[-expand_num:, :] img_expand[:, :expand_num] = img_expand[:, expand_num:expand_num * 2] img_expand[:, width + expand_num:] = img_expand[:, width:width + expand_num] return img_expand
步骤3:检测和校正坏点
该算法的主要功能是检测和校正坏点。
judge_defect_pixel
函数检查周围像素并确定一个像素是否有缺陷。def judge_defect_pixel(around_p, current_p, th): median_v = np.median(around_p) diff = around_p - current_p if (np.all(diff > 0) or np.all(diff < 0)) and np.all(np.abs(diff) > th): return median_v else: return current_p
步骤4:应用DPC_PINTO算法
我们将DPC_PINTO算法应用于图像的一个子集。这涉及迭代像素并根据需要校正它们。
# --------全局变量--------- expand_num = 2 th = 2 # --------原始参数------- file_path = '../images/HisiRAW_4208x3120_8bits_RGGB.raw' bayer_format = 'RGGB' bayer_bits = 8 row = 4208 col = 3120 # ---------------------- start_time = time.time() raw_data = read_raw(file_path, bayer_bits, row, col) height, width = raw_data.shape # 从原始图像中截取一个小块 sub_row_start = 1000 sub_row_end = 1600 sub_col_start = 1000 sub_col_end = 1600 raw_data_sub = raw_data[sub_row_start:sub_row_end, sub_col_start:sub_col_end] height_sub, width_sub = raw_data_sub.shape img_expand = expand_raw(raw_data_sub, expand_num) dis_img = np.zeros((height_sub, width_sub), dtype=raw_data_sub.dtype) for i in range(expand_num, height_sub + expand_num, 2): for j in range(expand_num, width_sub + expand_num, 2): # 处理红色像素 (R) around_r_pixel = [img_expand[i - 2, j - 2], img_expand[i - 2, j], img_expand[i - 2, j + 2], img_expand[i, j - 2], img_expand[i, j + 2], img_expand[i + 2, j - 2], img_expand[i + 2, j], img_expand[i + 2, j + 2]] dis_img[i - expand_num, j - expand_num] = judge_defect_pixel(around_r_pixel, img_expand[i, j], th) # 处理绿色像素 (Gr) around_gr_pixel = [img_expand[i - 1, j], img_expand[i - 2, j + 1], img_expand[i - 1, j + 2], img_expand[i, j - 1], img_expand[i, j + 3], img_expand[i + 1, j], img_expand[i + 2, j + 1], img_expand[i + 1, j + 2]] dis_img[i - expand_num, j - expand_num + 1] = judge_defect_pixel(around_gr_pixel, img_expand[i, j + 1], th) # 处理蓝色像素 (B) around_b_pixel = [img_expand[i - 1, j - 1], img_expand[i - 1, j + 1], img_expand[i - 1, j + 3], img_expand[i + 1, j - 1], img_expand[i + 1, j + 3], img_expand[i + 3, j - 1], img_expand[i + 3, j + 1], img_expand[i + 3, j + 3]] dis_img[i - expand_num + 1, j - expand_num + 1] = judge_defect_pixel(around_b_pixel, img_expand[i + 1, j + 1], th) # 处理绿色像素 (Gb) around_gb_pixel = [img_expand[i, j - 1], img_expand[i - 1, j], img_expand[i, j + 1], img_expand[i + 1, j - 2], img_expand[i + 1, j + 2], img_expand[i + 2, j - 1], img_expand[i + 3, j], img_expand[i + 2, j + 1]] dis_img[i - expand_num + 1, j - expand_num] = judge_defect_pixel(around_gb_pixel, img_expand[i + 1, j], th)
完整代码
import numpy as np import cv2 import time import matplotlib.pyplot as plt def read_raw(file_path, bayer_bits, row, col): with open(file_path, 'rb') as f: raw_data = np.fromfile(f, dtype=np.uint8 if bayer_bits == 8 else np.uint16) raw_data = raw_data.reshape((row, col)) return raw_data def expand_raw(img, expand_num): if expand_num % 2 != 0: raise ValueError('expand_num must be an even number!') height, width = img.shape img_expand = np.zeros((height + expand_num * 2, width + expand_num * 2), dtype=img.dtype) img_expand[expand_num:height + expand_num, expand_num:width + expand_num] = img img_expand[:expand_num, expand_num:width + expand_num] = img[:expand_num, :] img_expand[height + expand_num:, expand_num:width + expand_num] = img[-expand_num:, :] img_expand[:, :expand_num] = img_expand[:, expand_num:expand_num * 2] img_expand[:, width + expand_num:] = img_expand[:, width:width + expand_num] return img_expand def judge_defect_pixel(around_p, current_p, th): median_v = np.median(around_p) diff = around_p - current_p if (np.all(diff > 0) or np.all(diff < 0)) and np.all(np.abs(diff) > th): return median_v else: return current_p # --------全局变量--------- expand_num = 2 th = 2 # --------原始参数------- file_path = '../images/HisiRAW_4208x3120_8bits_RGGB.raw' bayer_format = 'RGGB' bayer_bits = 8 row = 4208 col = 3120 # ---------------------- start_time = time.time() raw_data = read_raw(file_path, bayer_bits, row, col) height, width = raw_data.shape # 从原始图像中截取一个小块 sub_row_start = 1000 sub_row_end = 1600 sub_col_start = 1000 sub_col_end = 1600 raw_data_sub = raw_data[sub_row_start:sub_row_end, sub_col_start:sub_col_end] height_sub, width_sub = raw_data_sub.shape img_expand = expand_raw(raw_data_sub, expand_num) dis_img = np.zeros((height_sub, width_sub), dtype=raw_data_sub.dtype) for i in range(expand_num, height_sub + expand_num, 2): for j in range(expand_num, width_sub + expand_num, 2): # 处理红色像素 (R) around_r_pixel = [img_expand[i - 2, j - 2], img_expand[i - 2, j], img_expand[i - 2, j + 2], img_expand[i, j - 2], img_expand[i, j + 2], img_expand[i + 2, j - 2], img_expand[i + 2, j], img_expand[i + 2, j + 2]] dis_img[i - expand_num, j - expand_num] = judge_defect_pixel(around_r_pixel, img_expand[i, j], th) # 处理绿色像素 (Gr) around_gr_pixel = [img_expand[i - 1, j], img_expand[i - 2, j + 1], img_expand[i - 1, j + 2], img_expand[i, j - 1], img_expand[i, j + 3], img_expand[i + 1, j], img_expand[i + 2, j + 1], img_expand[i + 1, j + 2]] dis_img[i - expand_num, j - expand_num + 1] = judge_defect_pixel(around_gr_pixel, img_expand[i, j + 1], th) # 处理蓝色像素 (B) around_b_pixel = [img_expand[i - 1, j - 1], img_expand[i - 1, j + 1], img_expand[i - 1, j + 3], img_expand[i + 1, j - 1], img_expand[i + 1, j + 3], img_expand[i + 3, j - 1], img_expand[i + 3, j + 1], img_expand[i + 3, j + 3]] dis_img[i - expand_num + 1, j - expand_num + 1] = judge_defect_pixel(around_b_pixel, img_expand[i + 1, j + 1], th) # 处理绿色像素 (Gb) around_gb_pixel = [img_expand[i, j - 1], img_expand[i - 1, j], img_expand[i, j + 1], img_expand[i + 1, j - 2], img_expand[i + 1, j + 2], img_expand[i + 2, j - 1], img_expand[i + 3, j], img_expand[i + 2, j + 1]] dis_img[i - expand_num + 1, j - expand_num] = judge_defect_pixel(around_gb_pixel, img_expand[i + 1, j], th) # 创建一个包含两个子图的大图 fig, axes = plt.subplots(1, 2, figsize=(12, 6)) # 显示原始图像块 axes[0].imshow(raw_data_sub, cmap='gray') axes[0].set_title('Original Sub Image') # 显示校正后的图像块 axes[1].imshow(dis_img, cmap='gray') axes[1].set_title('Corrected Sub Image') # 显示处理时间 print('Cost time: {:.2f} seconds'.format(time.time() - start_time)) plt.show()