我有一系列来自视频流的图像,我想用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()
答案 0 :(得分:7)
发生的事情是数据的最小值和最大值都在变化。 im.set_data
只是盲目地设置数据 - 它不会尝试更新颜色缩放。
最初,您绘制一个全零的数组,因此imshow
将图像缩放在0和0之间(加上一个微小的软糖因子)。但是,更新它的数据范围介于0到255之间。
您需要a)在最初绘制图像时将数据的vmin
和vmax
设置为最大范围,或者b)使用最小值和最大值更新颜色限制每次更新图像时的数据(使用im.set_clim
)。
由于您似乎期望数据为uint8
,因此最初在最初绘制空白图片时最好指定vmin
和vmax
。
尝试做:
# Blank starting image
self.im_im = self.im_ax.imshow(np.zeros((256, 256)), cmap=plt.cm.gray,
vmin=0, vmax=255)