2013-08-22 40 views
2

我有一系列來自視頻流的圖像,我想用Matplotlib(以灰度顯示)顯示。出於某種原因,我可以讓它們以完美的顏色顯示,但不是當我將它們轉換爲灰度時。使用matplotlib更新灰度圖像

由於我有很多圖像,我使用set_data(image)而不是imshow(image),因爲它更快。這些命令的彩色圖像都能正常工作,但灰度只適用於imshow()。如果我使用set_data(),我只是得到一個黑色的圖像,無論我發送了什麼數據。

有什麼想法可以在這裏發生什麼?

我的代碼以供參考。我已經強調了一個重要的評論,但我已經包含了所有其他代碼,以防其他問題導致此問題。代碼的其餘部分基本上建立了一個隊列,裏面填充了來自攝像頭的圖像,並且我想在顯示它們時顯示它們。

import matplotlib.pyplot as plt 
from matplotlib import cm 
from cv_bridge import CvBridge, CvBridgeError 
import cv 
from collections import deque 
import rospy 
from sensor_msgs.msg import Image 
import numpy as np 

class CameraViewer(): 

    def __init__(self, root='navbot'): 

    self.root = root 
    self.im_data = deque() 
    self.bridge = CvBridge() # For converting ROS images into a readable format 

    self.im_fig = plt.figure(1) 
    self.im_ax = self.im_fig.add_subplot(111) 
    self.im_ax.set_title("DVS Image") 
    self.im_im = self.im_ax.imshow(np.zeros((256, 256),dtype='uint8'), cmap=plt.cm.gray) # Blank starting image 
    #self.im_im = self.im_ax.imshow(np.zeros((256, 256),dtype='float32'), cmap=plt.cm.gray) # Tried a different format, also didn't work 
    self.im_fig.show() 
    self.im_im.axes.figure.canvas.draw() 

    def im_callback(self, data): 

    cv_im = self.bridge.imgmsg_to_cv(data, "mono8") # Convert Image from ROS Message to greyscale CV Image 
    im = np.asarray(cv_im) # Convert from CV image to numpy array 
    #im = np.asarray(cv_im, dtype='float32')/256 # Tried a different format, also didn't work 
    self.im_data.append(im) 

    def run(self): 

    rospy.init_node('camera_viewer', anonymous=True) 

    sub_im = rospy.Subscriber(self.root + '/camera/image', Image, self.im_callback) 

    while not rospy.is_shutdown(): 
     if self.im_data: 
     im = self.im_data.popleft() 

     ####################################################### 
     # The following code is supposed to display the image: 
     ####################################################### 

     self.im_im.set_cmap('gray') # This doesn't seem to do anything 
     self.im_im.set_data(im) # This won't show greyscale images 
     #self.im_ax.imshow(im, cmap=plt.cm.gray) # If I use this, the code runs unbearably slow 
     self.im_im.axes.figure.canvas.draw() 

def main(): 

    viewer = CameraViewer(root='navbot') 
    viewer.run() 

if __name__ == '__main__': 
    main() 

回答

6

發生什麼事情是數據的最小值和最大值發生了變化。 im.set_data只是盲目設置數據 - 它不會嘗試更新顏色縮放比例。

最初,您繪製了一個全零的數組,因此imshow將圖像在0和0之間縮放(加上一個微小的模糊因子)。但是,您更新的數據範圍介於0和255之間。

您需要a)將數據的vminvmax設置爲最初繪製圖像時的最大範圍,或者b)每次更新圖像時使用數據的最小值和最大值更新顏色限制(使用im.set_clim)。

因爲您似乎預計數據爲uint8's,所以最好在初次繪製空白圖像時指定vminvmax

嘗試這樣做:

# Blank starting image 
self.im_im = self.im_ax.imshow(np.zeros((256, 256)), cmap=plt.cm.gray, 
           vmin=0, vmax=255) 
+0

謝謝!這工作完美:) – Brent