OpenCV获取错误“Cant parse controls”,Python ROS中的输入参数不提供序列协议

qmelpv7a  于 2023-05-18  发布在  Python
关注(0)|答案(1)|浏览(196)

我正在为我的机器人做一个线路检测功能。我试着合并2个不同的代码,因为其中的第一个不适用于ros。我得到的错误在cv2.drawContours()函数和我不知道如何禁用这个问题
下面是我的代码:

#! /usr/bin/env python
import rospy
import cv2
import numpy as np
from sensor_msgs.msg import Image
from sensor_msgs.msg import CompressedImage
from cv_bridge import CvBridge, CvBridgeError
import traceback
import sys

class LineDetector:
    def __init__(self):
        self.rate = rospy.Rate(rospy.get_param("/rate/lineDetector"))
        self.bridge = CvBridge()
        self.image_sub = rospy.Subscriber("/camera/image_raw", Image, self.image_callback_raw)
        self.image_sub_rpi =rospy.Subscriber("/raspicam_node/image/compressed", CompressedImage, self.image_callback_compressed)
        self.image_pub = rospy.Publisher("processed_image", Image, queue_size=1)
        self.low_b =np.uint8([5,5,5])
        self.high_b=np.uint8([0,0,0])
        self.c=0
    def image_callback_raw(self, msg):
      
        try:
            cv_image = self.bridge.imgmsg_to_cv2(msg, "passthrough")
            self.process_image(cv_image)
        except Exception as e:
            traceback.print_exc()
            rospy.logerr(e)
            rospy.logerr("CvBridge Error, skipped image frame!")

    def image_callback_compressed(self, msg):
        try:
            np_arr = np.frombuffer(msg.data, np.uint8)
            image_np = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
            self.process_image(image_np)
        except Exception as e:
            rospy.logerr(e)
            rospy.logerr("skipped processed image frame!")
        
    def process_image(self, cv_image):

        mask=cv2.inRange(cv_image,self.low_b,self.high_b)
        contours, hierarchy =cv2.findContours(mask, 1, cv2.CHAIN_APPROX_NONE)
        if len(contours)>0:
            self.c = max(contours, key=cv2.contourArea)
            M = cv2.moments(self.c)
            if M["m00"] != 0:
                cx = int(M["m10"]/M['m00'])
                cy = int(M["m01"]/M["m00"])
                print("CX: "+str(cx)+"  CY: "+str(cy))
                if cx >= 120:
                    print("Turn Left")
                if cx < 120 and cx > 40:
                    print ("On Track")
                if cx <=40:
                    print("Turn Right")
                cv2.circle(cv_image, (cx,cy), 5, (255,255,255), -1)
        else:
            print("I dont see the line")
        cv2.drawContours(cv_image, self.c, -1,(0,255,0),-1)
        image_message = self.bridge.cv2_to_imgmsg(cv_image, "passthrough")
        self.image_pub.publish(image_message)



    def run(self):
        while not rospy.is_shutdown():
            self.rate.sleep()    

if __name__ == '__main__':
    rospy.init_node('line_detector')
    line_detector = LineDetector()
    rospy.spin()

你知道如何实现c在drawcontours函数中工作吗?
饰Pascal
用轮廓切换c..没多大帮助

vyswwuz2

vyswwuz21#

drawContours()函数只应在实际检测到轮廓时调用(当len(contours)>0时):

def process_image(self, cv_image):
        print("processing")
        mask=cv2.inRange(cv_image,self.low_b,self.high_b)
        # I suggest you to visualize your mask
        #cv2.imshow("mask",mask)
        #cv2.waitKey(1)
        contours, _ =cv2.findContours(mask, 1, cv2.CHAIN_APPROX_NONE) # hierarchy is redundant
        if len(contours)>0:
            self.c = max(contours, key=cv2.contourArea)
            M = cv2.moments(self.c)
            if M["m00"] != 0:
                cx = int(M["m10"]/M['m00'])
                cy = int(M["m01"]/M["m00"])
                print("CX: "+str(cx)+"  CY: "+str(cy))
                if cx >= 120:
                    print("Turn Left")
                if cx < 120 and cx > 40:
                    print ("On Track")
                if cx <=40:
                    print("Turn Right")
                cv2.circle(cv_image, (cx,cy), 5, (255,255,255), -1)
            
            # we can draw contours only in case that they were detected
            cv2.drawContours(cv_image, self.c, -1,(0,255,0),-1) 
        else:
            print("I dont see the line")
        image_message = self.bridge.cv2_to_imgmsg(cv_image, "rgb8") # fixed encoding
        self.image_pub.publish(image_message)

此外,请注意,您可能还需要将passthrough编码更改为rbg8,以启用图像到ROS图像msg的转换。
然而,我认为另一个问题在于您设置的RGB阈值(low_bhigh_b)。这些值显然取决于您的具体情况,但我建议您将它们设置得更高一些:

self.low_b =np.uint8([0,0,0]) 
        self.high_b=np.uint8([100,100,100])

(It也最好将mask可视化用于调试建议,正如我在上面的代码片段中提到的那样)。这是image_message的可视化结果:

相关问题