python - 由于 channel 信息,灰色图像上的 ROS CvBridge 无法正常工作

标签 python image opencv ros

我想要的是
我希望调整灰色图像的大小并发布它,以便我可以在另一个 ROS 节点中使用它。但是,我遇到了 channel 信息问题,即 OpenCV 或 CvBridge。
错误
当收听相机(网络摄像头/kinect)并将其转换为“mono8”(灰色)时,您将获得以下信息(行、列、 channel ),其中 channel = 1。出于某种原因,如果您保存此图像并再次阅读它突然 channel = 3。为什么这很重要?如果您在具有 3 个 channel 的图像上使用 cv2.resize(image,x,y),则输出图像为 (x,y,channels=3),但是当只有 1 个 channel 时,此信息将丢失并且您的输出为 ( x,y)。问题在于如果没有 channel 信息,CvBridge 将无法工作。
以下代码有效,因为 cv2.resize 在 3 个 channel 上执行:

#!/usr/bin/env python
PKG = 'something'
import roslib; roslib.load_manifest(PKG)
import rospy
import cv2
import sys
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError

class Test:

    def __init__(self):
        self.image_sub = rospy.Subscriber("/camera/rgb/image_raw",Image, self.callback)
        self.image_sub = rospy.Subscriber("test_image",Image, self.callback2)
        self.image_pub = rospy.Publisher("test_image", Image)
        self.bridge = CvBridge()

    def callback(self, image):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(image, 'mono8')
        except CvBridgeError, e:
            print e
        
        print cv_image.shape ### output: (480, 640, 1)
        cv2.imshow("Test", cv_image)
        cv2.imwrite("Test.png", cv_image)
        cv2.waitKey(3)

        test2 = cv2.imread("Test.png")
        print test2.shape ### output: (480, 640, 3)
        cv2.imshow("Test 2",test2)
        cv2.waitKey(3)
        test2 = cv2.resize(test2,(250,240))
        print test2.shape ### output: (250, 240, 3)
        self.image_pub.publish(self.bridge.cv2_to_imgmsg(test2))

    def callback2(self, image):
        try:
            cv_image = self.bridge.imgmsg_to_cv2(image)
        except CvBridgeError, e:
            print e
        
        cv2.imshow("Test3", cv_image)
        cv2.waitKey(3)

def main(args):
    test = Test()
    rospy.init_node('image_converter', anonymous=True)

    try:
        rospy.spin()
    except KeyboardInterrupt:
        print "Shutting down"
    cv2.destroyAllWindows()


if __name__ == '__main__':
    main(sys.argv)
但是以下不起作用(这次尝试发布调整大小):
    print cv_image.shape ### output: (480, 640, 1)
    cv2.imshow("Test", cv_image)
    cv2.imwrite("Test.png", cv_image)
    cv2.waitKey(3)
    
    test2 = cv2.resize(test2,(250,240))
    print test2.shape ### output: (250, 240)
    self.image_pub.publish(self.bridge.cv2_to_imgmsg(test2)) ### ERROR

    test2 = cv2.imread("Test.png")
    print test2.shape
    cv2.imshow("Test 2",test2)
    cv2.waitKey(3)
其他错误
将“mono8”更改为“8UC3”会出现以下错误:[yuv422] 是一种颜色格式,但 [8UC3] 不是,因此它们必须具有相同的 OpenCV 类型、CV_8UC3、CV16UC1
我真正的问题
如何调整灰色图像的大小并将其发布到 ROS 中而不会丢失 channel 信息或以某种方式将其转换为 3 个 channel ?我唯一担心的是我可以发送调整大小的信息, channel 数量对我来说并不重要。
信息
Ubuntu 12.04,
ROS水电,
OpenCV 2.4.9

最佳答案

在 CvBridge 的 master 分支中,现在修复了您可以在没有 channel 信息的情况下发送图像:https://github.com/ros-perception/vision_opencv/issues/49 .

对于不在 master 分支上的人:

#Ugly gray 3 channel hack for CvBridge (old version)
#Save image
cv2.imwrite(self.dir_image_save+'tempface.png', cv2_image)
#Load
cv2_image = cv2.imread(self.dir_image_save+'tempface.png')

现在你得到了一个 3 channel 的灰度图像(但很难看)。

关于python - 由于 channel 信息,灰色图像上的 ROS CvBridge 无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26610235/

相关文章:

python - 在opencv中更改图像的比例和数据类型

image-processing - OpenCV 目标检测 - 中心点

python - 与 numpy 的 np.random.RandomState 和 Python 的 random.Random 相互转换?

python - request.headers 与 request.environ

ios - 使用 Xcode 手动将图像数据放入 Plist 文件

android - 在 Android 上实现益智游戏

C# 将所有可滚动面板保存为图像

python - 如何连续运行多个 Selenium 测试

python - 在Python中构建嵌套字典从文件中逐行读取

python - 读取彩色数字图像是什么数字以进行控制台