【发布时间】:2021-05-30 09:35:48
【问题描述】:
我希望我的图像只有 10 种特定颜色,在 color_list 中指定。 所以我循环遍历每个像素,如果该像素的颜色不包含在颜色列表中,我分配相邻区域的颜色。但由于图像是 2k x 2k 像素。这个循环需要 3 分钟左右。 我确信我这样做的方式不是最佳的。我怎样才能优化我这样做的方式?
atlas_img_marked, atlas_img_cleaned = clean_img_pixels(atlas_img, color_list)
def clean_img_pixels(atlas_img, color_list):
dd = 3
for ii in range(atlas_img.shape[0]-1):
for jj in range(atlas_img.shape[1]-1):
pixelcolor = (atlas_img[ii,jj,0],atlas_img[ii,jj,1],atlas_img[ii,jj,2])
if pixelcolor not in color_list:
pixel2color = (atlas_img[ii-dd,jj,0],atlas_img[ii-dd,jj,1],atlas_img[ii-dd,jj,2])
if (pixel2color == (0,0,0)) | (pixel2color not in color_list):
pixel2color = (atlas_img[ii+dd,jj,0],atlas_img[ii+dd,jj,1],atlas_img[ii+dd,jj,2])
if (pixel2color == (0,0,0)) | (pixel2color not in color_list):
pixel2color = (atlas_img[ii+5,jj,0],atlas_img[ii+5,jj,1],atlas_img[ii+5,jj,2])
atlas_img_cleaned[ii,jj] = pixel2color
return atlas_img_cleaned
更准确地说,这里是耗时最长的部分:
out_colors = []
for ii in range(atlas_img.shape[0]-1):
for jj in range(atlas_img.shape[1]-1):
pixelcolor = (atlas_img[ii,jj,0],atlas_img[ii,jj,1],atlas_img[ii,jj,2])
if pixelcolor not in color_list:
out_colors.append((ii,jj))
耗时 177 秒
这样试了:
out_colors = [(ii,jj) for (ii,jj) in itertools.product(range(atlas_img.shape[0]), range(atlas_img.shape[1])) if (atlas_img[ii,jj,0],atlas_img[ii,jj,1],atlas_img[ii,jj,2]) not in color_list]
但并没有太大的区别。耗时 173 秒
这是颜色列表:
color_list = [(52, 26, 75), (9, 165, 216), (245, 34, 208), (146, 185, 85), (251, 6, 217), (223, 144, 239), (190, 224, 121), (252, 26, 157), (150, 130, 142), (51, 129, 172), (97, 85, 204), (1, 108, 233), (138, 201, 180), (210, 63, 175), (26, 138, 43), (216, 141, 61), (38, 89, 118), (0, 0, 0)]
【问题讨论】:
-
把
color_list变成set可能会让你有所进步。 -
嗯,我不确定这是不是让它变慢的原因
-
使用分析器,看看它大部分时间都花在了哪里。一些简单的尝试可能是:交换你的 for 循环并减少 if 语句的数量。列表与集合还应该给你一些有形的运行时间。
-
如果你有它作为 numpy 数组,那么你应该使用 numpy 函数而不是
for-loops。For-loops 大大降低了 numpy 代码的速度。 -
@snakecharmerb 所以使用集合而不是列表确实有所作为。谢谢。使用 PIL,将运行时间从 177 秒减少到 4 秒。并使用集合,进一步减少到 3 秒
标签: python performance loops optimization