在《每天进步一点点:使用Python批量修改图片尺寸》一文中,我曾提到之所以选择使用OpenCV库而不是Pillow,是因为OpenCV库使用C++实现,而Pillow是纯Python实现,所以使用OpenCV会比Pillow高效一点点。
(图源 :pixabay)
当我用Python+OpenCV成功实现想要的功能后,出于学习的目的,我又使用Pillow把相应功能重新实现一遍。但是在测试过程中,直观的感受是Python+Pillow反而比Python+OpenCV要快一点点。
那么在缩减图片这个操作上,两者到底谁更高效一些呢?我突然生出了将它们比较一番的心思。说干就干,与其道听途说或者盲目猜测,何不用程序拿数据说话呢?
为了更好的进行比较,我将两者缩减图片的函数调整为差不多的样子,分别如下:
def resize_image_by_opencv(file_path, scale_percent):
print("Process by OpenCV")
img = cv2.imread(file_path)
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
resized_img = cv2.resize(img, (width, height))
cv2.imwrite(file_path, resized_img)
以上代码为使用OpenCV调整图片。
def resize_image_by_pillow(file_path, scale_percent):
print("Process by Pillow")
img = Image.open(file_path)
width = int(img.size[0] * scale_percent / 100)
height = int(img.size[1] * scale_percent / 100)
resized_img = img.resize((width, height))
resized_img.save(file_path)
以上代码为使用Pillow调整图片。
然后在程序中加上测量耗时的代码:
import time
def main(argv=None):
start = time.time()
#cpu_start = time.clock()
process_start = time.process_time()
perf_start = time.perf_counter()
for file_name in os.listdir(folder_path):
if file_name.endswith('.jpg') or file_name.endswith('.png'):
print(file_name)
file_path = os.path.join(folder_path, file_name)
resize_image_by_opencv(file_path, scale_percent)
#resize_image_by_pillow(file_path, scale_percent)
end = time.time()
#cpu_end = time.clock()
process_end = time.process_time()
perf_end = time.perf_counter()
#print("CPU Time:", cpu_end - cpu_start)
print("Proc Time:", process_end - process_start)
print("Exec Time:", end - start)
print("Perf Time:", perf_end - perf_start)
接下来就是进行测试啦,从去大洋山爬山的相册中选择出38张照片,第一次运行程序,亦即使用OpenCV进行图片缩减。
这里额外说一下,在批处理文件中,我在文件第一行添加了如下语句:
color 17
上述代码的意思是将前景色设置为白色,将背景色设置为蓝色,这样看起来比较舒服(以前TC2.0以及Basic啥的界面全是这个颜色)
执行部分输出如下:
然后进行第二次测试,删除目录中的图片,重新从去大洋山爬山的相册中选择出38张照片,将main函数中调整图片尺寸的代码修改为使用Pillow,亦即:
#resize_image_by_opencv(file_path, scale_percent)
resize_image_by_pillow(file_path, scale_percent)
然后重新执行批处理脚本:
将两次操作中时间部分截取出来。
使用OpenCV:
Proc Time: 8.484375
Exec Time: 5.6140031814575195
Perf Time: 5.613874399998167
使用Pillow:
Proc Time: 4.65625
Exec Time: 4.69614839553833
Perf Time: 4.696085299998231
可见在调整图片尺寸这个简单的应用中,Python+Pillow要优于Python+OpenCV的。处理38张图片,实际耗时快了大约1秒左右。
这里我们还注意到一个问题,就是使用OpenCV,CPU时间的耗费要远高于Python+Pillow,大概因为不是原生Python代码,需要反复调用的缘故。
所以,至少在调整图片这个应用情形下,使用Python+Pillow无疑是最佳选择。
那么你可能会问,之前不是说:
OpenCV库使用C++实现,而Pillow是纯Python实现,所以使用OpenCV会比Pillow高效一点点。
我觉得一方面“纸上得来终觉浅,绝知此事要躬行”,不能人云亦云,道听途说,要自己实际测试一下;而另一方面,实在是调整图片尺寸只是所有图片操作中最最最简单的一个,杀鸡用牛刀,OpenCV的优势完全没有体现出来,如果要做一些极为复杂的图片操作,我相信结果会完全不一样的。
至于我做这个测试,纯属无聊,毕竟不为无益之事,何以遣有涯之生!
补充说一下代码中time.clock()
的问题,在Python3.8之前可以使用如下代码来测试CPU时间:
import time
start = time.clock()
......
end = time.clock()
print("CPU Time: ", end - start)
但是它在Linux与Windows下行为不太一致,所以Python3.8开始,就把这个移除啦,使用time.process_time()
和time.perf_counter()
作为替代。
看来各种程序、代码库再不断更新,我们也必须随时跟进呢,否则就落伍了呢。
好了,经过O哥一顿猛如虎的操作,每次发图片贴,又可以节省一秒的时间,好开心呀,毕竟时间就是生命,时间就是金钱呀。😊