matplotlib funcanimation执行时间太长

时间:2018-06-02 10:50:26

标签: matplotlib ipython

我正在尝试加载存储在列表中的图像,作为动画gif通过matplotlib funcanimation以及该图像的直方图。

以下是问题:
1.使用%matplotlib笔记本,大约需要112到117秒。质量低。
2.使用%matplotlib内联,需要高达5分钟(300秒)。质量更好。
3.使用%matplotlib内联,如果启用了blit,则set_animated函数出错

以下是我的代码:
代码在笔记本Uber Slow Code Issue 1.ipynbHere是涉及图像的整个项目。

请帮助。

代码使用%matplotlib内联快速查看:

%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则中断)

output

0 个答案:

没有答案