图像处理:模拟色差的实战案例
在做瓷砖瑕疵检测的过程中,需要检测色差。但在实际生产环境中,瓷砖色差检测的数据量较少,无法直接获取足够的数据来训练和优化深度学习模型。于是就考虑通过人为生成色差数据的方式来扩充数据集,进行色差的模拟。
1. 什么是色差?
色差(Color Difference)是指两种颜色之间的视觉差异。在色彩科学中,CIEDE2000 是目前最先进的色差计算方法之一。然而,CIEDE1976 也常用于基础的色差分析。本项目主要使用 CIEDE1976 来计算颜色的变化程度。
2. 代码实现
编写一个 Python 脚本,该脚本能够读取一组图像,并生成不同色差版本的图像,同时计算其色差值。
2.1 依赖库
在开始之前,请确保你已经安装了必要的库:
pip install opencv-python numpy colormath
2.2 计算色差
我们使用 colormath
库来计算 CIEDE1976 色差:
from colormath.color_objects import LabColor
from colormath.color_diff import delta_e_cie1976
def calculate_delta_e(lab1, lab2):
"""
计算 CIEDE1976 色差
:param lab1: (L, a, b) of first color
:param lab2: (L, a, b) of second color
:return: ΔE 色差值
"""
color1 = LabColor(lab1[0], lab1[1], lab1[2])
color2 = LabColor(lab2[0], lab2[1], lab2[2])
return delta_e_cie1976(color1, color2)
2.3 模拟色差
使用 OpenCV 将图像转换到 Lab 颜色空间,并对 L、a、b 通道进行调整:
注意:在处理ab通道时,如果按照255进行设置偏置,可能存在溢出,导致图片显示黑点,所以要进行归一化 a, b 到 [-128, 127]
import cv2
import numpy as np
def apply_lab_shift(image, l_shift, a_shift, b_shift):
"""
在 Lab 颜色空间执行色差模拟
"""
lab_image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB).astype(np.float32)
L, a, b = cv2.split(lab_image)
# 归一化 a, b 到 [-128, 127]
a -= 128
b -= 128
L = np.clip(L + l_shift, 0, 255)
a = np.clip(a + a_shift, -128, 127)
b = np.clip(b + b_shift, -128, 127)
# 还原到 OpenCV 存储格式 [0,255]
a += 128
b += 128
shifted_lab = cv2.merge([L, a, b]).astype(np.uint8)
return cv2.cvtColor(shifted_lab, cv2.COLOR_LAB2BGR)
2.4 处理图片并保存结果
import os
def process_images(input_folder, output_folder, log_file):
if not os.path.exists(output_folder):
os.makedirs(output_folder)
with open(log_file, 'w') as log:
for root, _, files in os.walk(input_folder):
for file_name in files:
if file_name.lower().endswith(('.jpg', '.png', '.jpeg')):
image_path = os.path.join(root, file_name)
image = cv2.imread(image_path)
if image is None:
print(f"无法读取 {file_name},跳过...")
continue
base_name, ext = os.path.splitext(file_name)
save_path = os.path.join(output_folder, base_name)
os.makedirs(save_path, exist_ok=True)
# 生成不同色差版本
shifts = {"n": (0.5, 0.4, -0.4), "s": (2, 1.2, -1.2), "l": (3, 2.5, -3.5)}
for key, (l, a, b) in shifts.items():
shifted = apply_lab_shift(image, l, a, b)
cv2.imwrite(os.path.join(save_path, f"{base_name}_{key}{ext}"), shifted)
# 计算 ΔE
lab_orig = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
lab_shifted = cv2.cvtColor(shifted, cv2.COLOR_BGR2LAB)
delta_e = calculate_delta_e(lab_orig.mean(axis=(0, 1)), lab_shifted.mean(axis=(0, 1)))
log.write(f"{file_name} - {key}色差 ΔE: {delta_e:.2f}\n")
print(f"处理完成,结果保存在 {output_folder}")
2.5 运行代码
if __name__ == "__main__":
current_folder = os.path.dirname(os.path.abspath(__file__))
input_folder = os.path.join(current_folder, "input_images")
output_folder = os.path.join(current_folder, "color_diff_images")
log_file = os.path.join(output_folder, "process_log.txt")
process_images(input_folder, output_folder, log_file)
3. 运行效果
当我们运行代码后,程序会:
- 读取
input_images
文件夹中的图片。 - 生成无色差(ΔE≈0.5)、小色差(ΔE≈0.5-3)、大色差(ΔE≈10-15)的版本。
- 计算色差并记录到
process_log.txt
。
最终,我们可以在 color_diff_images
目录下找到处理后的图像,并通过日志查看每张图像的 ΔE 数值。
#CIELab#
#色差生成#