【发布时间】:2022-06-24 15:52:52
【问题描述】:
我正在对一个图像数据集执行数据清理,其中存在人脸的重复图像。重复的图像可能并不完全相似,但它们几乎相同。
为了实现这一点,我使用average hashing 首先找到所有图像的哈希值,然后找到哈希值 w.r.t 的差异。目录中的所有图像。差异小于 15 的图像被认为是重复的,并且只有一个来自重复的图像应存在于清理后的数据集中。
下面是代码实现:
首先,我们计算所有图像的hash_values 并返回image_ids 和各自的hash_values
def calculate_hash(dir):
"""Generate Hash Values for all images in a directory
Args:
dir (str): Directory to search for images
Returns:
hash_values (list): List of hash values for all images in the directory
image_ids (list): List of image ids for all images in the directory
"""
hash_values = []
image_ids = []
for file in os.listdir(dir):
path = os.path.join(dir, file)
img = Image.open(path)
hash = imagehash.average_hash(img)
hash_values.append(hash)
image_ids.append(file)
return image_ids, hash_values
# Obtain image_ids and respective hash values
image_ids, hash_values = calculate_hash("D:/test_dir/images/test_duplicates")
然后我们准备一个数据框,其中包含image_ids、hash_values 以及所有 image_id 差异的附加列,并将其设置为 0。
def prepare_dataframe(image_ids, hash_values):
# Create DataFrame with hash values and image ids
df = pd.DataFrame(
{
"image_ids": image_ids,
"hash_values": hash_values,
}
)
# Create new columns in df with image_ids having hash difference value=0
for i in range(len(df.image_ids)):
df[f"diff_{image_ids[i]}"] = 0
return df
# Obtain dataframe
df = prepare_dataframe(image_ids, hash_values)
这就是准备好的数据框的样子。图像 1,2 完全不同。并且图像 3.1、3.2、3.3 是重复的(通过目视检查)。最终清理后的数据应该只包含图像 1,2,3.1。
现在我计算每个image_id w.r.t 每个image_id 的哈希值差异
def calculate_differences(df):
# Obtain difference for every image_id one by one
for i in range(len(df.hash_values)):
differences = []
for j in range(len(df.hash_values)):
differences.append(df.hash_values[i] - df.hash_values[j])
# Store the difference values for every image_id
df.iloc[i, 2:] = differences
return df
df = calculate_differences(df)
这为我们提供了以下数据框:
从哈希差值中可以清楚地看出 3.1、3.2 和 3.3 是重复的。但我不明白如何提取所需的输出,即unique_image_ids = [1,2,3.1]列表
我编写了以下代码,但它会删除任何具有重复的图像,即 3.1 也会从最终数据帧中删除。
# For every image_id, find the column values having value < 15 more than once and delete respective rows
def remove_duplicates(df):
for i in range(len(df.image_ids)):
clean_df = df.drop(df[df[f"diff_{df.image_ids[i]}"] < 15].index)
return clean_df
clean_df = remove_duplicates(df)
所需的输出也应该有图像 3.1,但它没有出现在数据框中。
有没有优化的方法来实现这一点?
【问题讨论】:
标签: python pandas dataframe image deep-learning