常见记录——图像数据清洗
图像数据清洗是数据预处理的一个重要步骤,它可以提高图像识别和图像处理的准确性。以下是一般的图像数据清洗流程:
收集数据:收集需要清洗的图像数据。
数据预处理:对数据进行格式转换,例如转换为灰度图像或RGB图像。
数据标注:将数据进行标注,例如将图像中的对象或者区域进行标注,方便后续训练和评估。
数据清洗:进行数据清洗,包括以下步骤:
数据去重:删除重复的图像。
数据过滤:删除低质量、不标准、不合理的图像。
数据修复:修复数据中出现的缺失、噪声、伪影等问题。
数据增强:增加数据的数量和多样性,例如对图像进行旋转、平移、缩放、翻转等操作,以及在图像中添加噪声等。
数据分割:将数据分成训练集、验证集和测试集,以进行模型训练、调参和评估。
数据存储:将清洗后的数据保存到数据库或者本地文件系统中。
需要注意的是,不同的应用场景可能需要不同的清洗流程和标准,因此在进行图像数据清洗时,需要根据具体的情况进行调整和优化。
具体细化方法:
下面是具体的细化方法:
1、数据去重:
比较图像的哈希值或特征向量,将相似度高的图像视为重复图像,进行删除。
根据文件名或图像元数据(如时间、地点、拍摄设备等)进行去重。
python 代码示例:
下面是一份使用Python进行图像数据去重的示例代码:
import imagehash from PIL import Image import os def remove_duplicates(images_dir): # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 创建一个字典用于存储哈希值和对应的图像文件名 hashes = {} # 遍历所有图像文件 for image_file in image_files: # 打开图像文件并计算哈希值 with Image.open(os.path.join(images_dir, image_file)) as img: hash_value = str(imagehash.average_hash(img)) # 如果哈希值已经存在,说明是重复图像,将其删除 if hash_value in hashes: os.remove(os.path.join(images_dir, image_file)) # 如果哈希值不存在,将其添加到字典中 else: hashes[hash_value] = image_file
这个示例代码使用了Python的Pillow库来打开图像文件,并使用了imagehash库来计算图像的哈希值。在遍历图像文件时,将每个图像的哈希值与字典中已经存在的哈希值进行比较,如果重复,则将该文件删除。需要注意的是,这个示例代码只适用于JPEG和PNG格式的图像文件,如果需要支持其他格式的图像文件,则需要对代码进行适当修改。
2、数据过滤:
检测图像的清晰度、对比度、色彩饱和度等指标,将低质量图像进行删除或标记。
根据标注数据,检测是否符合标注规范,删除不符合规范的图像。
根据业务需求,进行特定条件的过滤,如删除非指定区域内的图像,删除重复出现的背景图像等。
python代码示例:
import cv2 import os def filter_images(images_dir): # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 遍历所有图像文件 for image_file in image_files: # 打开图像文件并进行质量检测 img = cv2.imread(os.path.join(images_dir, image_file)) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) mean_val = cv2.mean(gray)[0] # 如果平均灰度值小于50,则认为图像质量不好,将其删除 if mean_val < 50: os.remove(os.path.join(images_dir, image_file))
这个示例代码使用了Python的OpenCV库来打开和处理图像文件。在遍历图像文件时,使用cv2.imread()函数读取图像,并将其转换为灰度图像。然后,使用cv2.mean()函数计算灰度图像的平均值,如果平均值小于50,则认为图像质量不好,将该文件删除。需要注意的是,这个示例代码只进行了简单的质量检测,如果需要更加严格的质量控制,可以根据具体情况进行修改。
3、数据修复:
使用图像处理算法进行图像去噪、填充、缺失区域修复等操作。
根据已有标注数据进行图像修正,如修改标注框的位置、大小等。
python 示例代码:
import cv2 import numpy as np import os def repair_images(images_dir): # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 遍历所有图像文件 for image_file in image_files: # 打开图像文件并进行修复 img = cv2.imread(os.path.join(images_dir, image_file)) # 使用中值滤波进行去噪 img = cv2.medianBlur(img, 5) # 使用腐蚀操作进行伪影修复 kernel = np.ones((5,5),np.uint8) img = cv2.erode(img, kernel, iterations=1) # 保存修复后的图像 cv2.imwrite(os.path.join(images_dir, image_file), img)
这个示例代码使用了Python的OpenCV库来打开和处理图像文件。在遍历图像文件时,使用cv2.imread()函数读取图像,并进行中值滤波和腐蚀操作进行去噪和伪影修复。需要注意的是,这个示例代码只进行了简单的图像修复,如果需要更加精细的修复,可以根据具体情况进行修改。另外,由于图像修复可能会改变图像的颜色、亮度等特征,因此需要对修复后的图像进行必要的验证和评估。
4、数据增强:
对图像进行旋转、平移、缩放、翻转等操作,以增加数据的数量和多样性。
在图像中添加噪声、模糊、颜色变换等,以增加数据的多样性和泛化能力。
python 示例代码:
import cv2 import numpy as np import os def augment_images(images_dir): # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 遍历所有图像文件 for image_file in image_files: # 打开图像文件并进行增强 img = cv2.imread(os.path.join(images_dir, image_file)) # 随机进行图像旋转、平移、缩放、翻转等操作 rows, cols, _ = img.shape M = cv2.getRotationMatrix2D((cols/2,rows/2), np.random.randint(-30, 30), 1) img = cv2.warpAffine(img, M, (cols, rows)) M = np.float32([[1,0,np.random.randint(-50,50)],[0,1,np.random.randint(-50,50)]]) img = cv2.warpAffine(img, M, (cols,rows)) img = cv2.resize(img, None, fx=np.random.uniform(0.8, 1.2), fy=np.random.uniform(0.8, 1.2)) if np.random.randint(0, 2): img = cv2.flip(img, 1) # 随机添加噪声、模糊、颜色变换等 if np.random.randint(0, 2): img = cv2.GaussianBlur(img, (5, 5), 0) if np.random.randint(0, 2): noise = np.zeros_like(img) cv2.randn(noise, 0, 20) img = cv2.add(img, noise) if np.random.randint(0, 2): hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) hsv[..., 0] += np.random.randint(-10, 10) hsv[..., 1] += np.random.randint(-30, 30) hsv[..., 2] += np.random.randint(-30, 30) img = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) # 保存增强后的图像 cv2.imwrite(os.path.join(images_dir, f"aug_{image_file}"), img)
这个示例代码使用了Python的OpenCV库来打开和处理图像文件。在遍历图像文件时,对每个图像随机进行旋转、平移、缩放、翻转等操作,以增加数据的数量和多样性。然后,随机添加噪声、模糊、颜色变换等,以增加数据的多样性和泛化能力。需要注意的是,这个示例代码只展示了常见的图像增强操作,如果需要更加复杂的增强,可以根据具体情况进行修改。另外,在进行图像增强时,需要注意不要对图像进行过度处理,以避免增强后的图像失去原有的特征和信息。
5、数据分割:
根据比例分割数据集,例如将数据集分成训练集、验证集和测试集。
根据时间、地点等因素进行分割,例如将数据按照时间进行分割,保证测试集与训练集没有时间上的重合。
python示例代码:
import os import shutil from sklearn.model_selection import train_test_split def split_data(images_dir, train_dir, val_dir, test_dir, train_size=0.8, val_size=0.1, test_size=0.1): # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 分割数据集 train_files, val_test_files = train_test_split(image_files, test_size=val_size+test_size, random_state=42) val_files, test_files = train_test_split(val_test_files, test_size=test_size/(val_size+test_size), random_state=42) # 复制图像文件到对应的目录中 for file in train_files: shutil.copy(os.path.join(images_dir, file), os.path.join(train_dir, file)) for file in val_files: shutil.copy(os.path.join(images_dir, file), os.path.join(val_dir, file)) for file in test_files: shutil.copy(os.path.join(images_dir, file), os.path.join(test_dir, file))
这个示例代码使用了Python的os和shutil库来操作文件系统,以及使用了scikit-learn库的train_test_split函数进行数据集分割。在调用train_test_split函数时,需要传入图像文件名列表,并指定训练集、验证集和测试集的比例。然后,将每个图像文件复制到对应的目录中,以进行后续的模型训练、调参和评估。需要注意的是,这个示例代码只进行了简单的数据分割,如果需要更加精细的分割,可以根据具体情况进行修改。另外,在进行数据分割时,需要确保训练集、验证集和测试集的数据分布和标注规范一致,以保证模型训练和评估的公正性和准确性。
6、数据存储:
将清洗后的数据保存到数据库或者本地文件系统中。
在保存数据时,可以根据需要对图像进行压缩、格式转换等操作,以便后续的使用和传输。
python 示例代码:
import os import shutil def save_data(images_dir, output_dir): # 创建输出目录 os.makedirs(output_dir, exist_ok=True) # 获取目录中的所有图像文件名 image_files = [f for f in os.listdir(images_dir) if f.endswith('.jpg') or f.endswith('.png')] # 将图像文件复制到输出目录中 for file in image_files: shutil.copy(os.path.join(images_dir, file), os.path.join(output_dir, file))
这个示例代码使用了Python的os和shutil库来操作文件系统。在函数中,首先创建了一个输出目录,并使用os.makedirs()函数来确保目录已经存在。然后,获取指定目录中的所有图像文件名,并使用shutil.copy()函数将每个图像文件复制到输出目录中。需要注意的是,这个示例代码只是简单地将图像文件复制到输出目录中,如果需要对图像进行压缩、格式转换等操作,可以在函数中添加相应的代码。
在进行图像数据清洗时,需要根据具体的业务需求进行调整和优化,以确保清洗后的数据质量和适用性。