matplotlib - matplotlib funcanimation 执行时间太长
问题描述
我正在尝试加载存储在列表中的图像,作为动画 gif 通过 matplotlib funcanimation 以及该图像的直方图。
以下是问题:
1. 使用 %matplotlib notebook,大约需要 112 到 117 秒。低质量。
2. 使用 %matplotlib inline,需要 5 分钟(300 秒)。更好的质量。
3. 使用 %matplotlib inline,如果启用 blit,set_animated 函数会出错
下面是我的代码:
代码在笔记本Uber Slow Code Issue 1.ipynb中。
这是涉及图像的整个项目。
请帮忙。
带有 %matplotlib inline 的代码可在此处快速查看:
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from IPython.display import display, Image, HTML
import time
import cv2
from loaders import STANDARDIZED_LIST
# 3 rows, 4 cols
f, axArray = plt.subplots(3, 4, figsize=(11,5.5))
# MATPLOTLIB 'NOTEBOOK' BACKEND SPECIFIC
#rc('animation', html='html5')
#plt.rcParams["animation.html"] = "jshtml"
f.tight_layout()
# --------------------- PREPROCESSING HELPER FUNCTIONS ----------------------
def crop(image_list):
"""
crop 5 px on either side vertically
"""
image_cropped_list = []
for each_image_label_pair in image_list:
image = each_image_label_pair[0]
image_cropped = image[:, 5:-5, :]
image_cropped_list.append((image_cropped, each_image_label_pair[1]))
print(len(image_cropped_list))
return image_cropped_list
# create separate list images for each channel
def create_separate_lists(image_list):
"""
Returns 3 separate list of each label (so no label attachment)
"""
r_list = []
y_list = []
g_list = []
for each_image_label_pair in image_list:
image = each_image_label_pair[0]
label = each_image_label_pair[1] # one hot encoded
if label[0] == 1: # red
r_list.append(image)
elif label[1] == 1: # yellow
y_list.append(image)
else: # green
g_list.append(image)
return (r_list, y_list, g_list)
# ----------------- PRE PROCESSING SECTION ---------------------------
# CROP THE IMAGES
STANDARDIZED_CROPPED_LIST = crop(STANDARDIZED_LIST)
# create separate lists for each label
(r_list, y_list, g_list) = create_separate_lists(STANDARDIZED_CROPPED_LIST)
#print(len(r_list), len(y_list), len(g_list))
# get max length (list which has max no of images)
max_list = max([len(r_list), len(y_list), len(g_list)])
# ----------------- ANIMATION SECTION ------------------------------
# TO VIEW ALL THE PREPROCESSED IMAGES AT ONCE..
# calculate histogram
def hsv_histograms(rgb_image):
# Convert to HSV
hsv = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2HSV)
# Create color channel histograms
h_hist = np.histogram(hsv[:,:,0], bins=32, range=(0, 180))
s_hist = np.histogram(hsv[:,:,1], bins=32, range=(0, 256))
v_hist = np.histogram(hsv[:,:,2], bins=32, range=(0, 256))
# Generating bin centers
bin_edges = h_hist[1]
bin_centers = (bin_edges[1:] + bin_edges[0:len(bin_edges)-1])/2
return bin_centers, h_hist, s_hist, v_hist
# initiate artists once
def initArtists():
"""
To optimize performance, we use same artists, so they have to be initialized/created once
like below and then re use in animation loop
"""
axArtistsArray = [[plt.plot([],[]) for _ in range(4)] for _ in range(3)]
first_image_lists = [r_list[0], y_list[0], g_list[0]]
for i in range(3): # 3 rows
(bin_centers, h_hist, s_hist, v_hist) = hsv_histograms(first_image_lists[i])
axArtistsArray[i][0] = axArray[i][0].imshow(first_image_lists[i])
axArtistsArray[i][1] = axArray[i,1].bar(bin_centers,h_hist[0]) # bar(x, height)
axArtistsArray[i][2] = axArray[i,2].bar(bin_centers,s_hist[0])
axArtistsArray[i][3] = axArray[i,3].bar(bin_centers,v_hist[0])
axArray[i,1].set_xlim(0,180)
axArray[i,2].set_xlim(0,256)
axArray[i,3].set_xlim(0,256)
axArray[0,1].set_title('H channel')
axArray[0,2].set_title('S channel')
axArray[0,3].set_title('V channel')
return axArtistsArray
# animation function. This is called sequentially
def animate(i):
# ensure no out of range in each lists
r_index = i % len(r_list)
y_index = i % len(y_list)
g_index = i % len(g_list)
first_image_lists = [r_list[r_index], y_list[y_index], g_list[g_index]]
for row_index in range(3): # 3 rows: 0, 1, 2
# image
col_index = 0
image = first_image_lists[row_index]
axArtistsArray[row_index][col_index].set_data(image)
(bin_centers, h_hist, s_hist, v_hist) = hsv_histograms(image)
# H channel
col_index = 1
for each_bar_height, each_bar in enumerate(axArtistsArray[row_index][col_index]):
each_bar.set_height(h_hist[0][each_bar_height])
# S channel
col_index = 2
for each_bar_height, each_bar in enumerate(axArtistsArray[row_index][col_index]):
each_bar.set_height(s_hist[0][each_bar_height])
# V channel
col_index = 3
for each_bar_height, each_bar in enumerate(axArtistsArray[row_index][col_index]):
each_bar.set_height(v_hist[0][each_bar_height])
"""
axArtistsArray[0][0].set_data(r_list[r_index])
axArtistsArray[1][0].set_data(y_list[y_index])
axArtistsArray[2][0].set_data(g_list[g_index])
"""
return (axArtistsArray,)
# INITIATE ARTISTS
axArtistsArray = initArtists()
#plt.subplots_adjust(hspace=None)
# call the animator.
start_time = time.time()
anim = animation.FuncAnimation(f, animate, frames=np.arange(0,max_list), interval=1000, blit=False)
#if output not cleared an empty output area created additionally...
from IPython.display import clear_output
clear_output()
plt.close() # to avoid an additional empty plot which we do not want to see
HTML(anim.to_html5_video())
当前输出:
(%matplotlib 内联输出,执行需要 5 分钟,如果 blit=True 则中断)
解决方案
推荐阅读
- mysql - MySQL 默认字符集选项
- c# - 如何在多个浏览器上处理“AspNetCore.Correlation.OpenIdConnect cookie not found”错误
- php - FFmpeg - 不允许操作
- java - 使用 replaceAll() 修改现有元素时列表不更新
- xml - Powershell脚本将一个大文件拆分为多个文件,每个文件中有两对标签,文件名有命名约定
- apache-spark - 使用多列更新 Apache Spark / Databricks 中的表
- elasticsearch - ElasticSearch 批量插入导致 WriteStateException 和未分配的分片
- javascript - 如何将 GitHub 项目和时间线嵌入网站
- sql - 有没有办法在添加间隔的同时保留一个月的最后一天?
- angular-tree-component - 角树组件虚拟滚动不起作用