我已经使用 OpenCV 创建了一个用于图像旋转的管道,以及另一个将多线程应用于管道的函数。
管道:
def rotation_pipeline(img, rotation):
# Rotation options
rotation_options = {
'90':cv2.ROTATE_90_CLOCKWISE,
'180':cv2.ROTATE_180,
'270':cv2.ROTATE_90_COUNTERCLOCKWISE
}
# Rotate single image
img_name = img.split('/')[-1]
read_image = cv2.imread(img)
rotated_image = cv2.rotate(read_image, rotation_options[rotation])
cv2.imwrite(f'../processed_data/jpeg/augmented/{rotation}_degree_{img_name}', rotated_image)
print(f'{img_name} rotated {rotation} degrees.')
和多线程功能:
# Rotations
def rotate_images(rotation):
'''
Options for `rotation` are '90', '180', and '270'.
'''
# Read in metadata
PATH = '../data/jpeg/train/'
df = pd.read_csv('../data/train.csv')
augmentation_df = df[df['target'] == 1]
# Obtain image names
melanoma_names = augmentation_df['image_name'].values
image_paths = PATH + melanoma_names + '.jpg'
# Create new metadata
augmentation_df['image_name'] = augmentation_df['image_name'].map(lambda x: f'{rotation}_degree_'+x)
# Multithread rotations
with concurrent.futures.ThreadPoolExecutor() as executor:
executor.map(rotation_pipeline, image_paths, ('rotation',rotation))
# Add metadata to csv
if 'augmented_metadata.csv' in os.listdir('../processed_data/'):
augmented_csv = pd.read_csv('../processed_data/augmented_metadata.csv')
augmentation_df = pd.concat([augmented_csv, augmentation_df], axis=0)
augmentation_df.to_csv('../processed_data/augmented_metadata.csv')
该代码旨在包含在我的预处理管道中,如下所示:
rotate_images('90')
rotate_images('180')
rotate_images('270')
我已经用 rotate_melanoma_images('90')
在笔记本中测试了代码。但这仅运行单个图像。我检查了输出目录并确认只旋转了一个图像。
如果有多个迭代器,迭代器会在最短的迭代器用完时停止。
我假设只运行一个项目的原因是因为只有一个 arg,所以“最短的可迭代对象已用完”。话虽如此,似乎有一种方法可以为列表中的 每个 项使用 concurrent.futures.ThreadPoolExecutor
将参数添加到函数中。不过,我无法在网上找到任何解释如何执行此操作的内容——有人知道这是如何工作的吗?