使用 Python 和 Gazebo 在 Ros 中过滤颜色

发布于 2025-01-13 18:41:21 字数 4825 浏览 2 评论 0原文

最近,我受委托使用 Gazebo 中已经制作的机器人,使用带有摄像头的 Ros,我已经能够通过 .py 代码看到该图像。现在他们要求我过滤颜色(绿色,红色和蓝色),我已经有了高值和低值,并且我可以用图像来完成它,但我不知道如何混合这两个程序,以便过滤掉什么通过颜色,我只知道机器人相机传输的是什么,而不是图像。

所有这一切都是在使用 Open CV 时

附加的两个代码

//////////////////////////////////////////////////////////////////////////////////////// 
Code to see the gazeebo virtual camera
//////////////////////////////////////////////////////////////////////////////////////// 

#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    while not rospy.is_shutdown():  
        if image_received: 
            cv2.waitKey(1) 
            r.sleep()  
    cv2.destroyAllWindows() 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
        #Add your code to save the image here: 
        #Save the image "img" in the current path  
        cv2.imwrite('robot_image.jpg', cv_image)        
        #Display the image in a window 
        cv2.imshow('Image from robot camera', cv_image) 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('load_image', anonymous=True) 
    show_image() 

//////////////////////////////////////////////////////////////////////////////////////// 
code to see an image segmented in RGB by windows
//////////////////////////////////////////////////////////////////////////////////////// 

#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
#Import the numpy library which will help with some matrix operations 
import numpy as np  
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    image = cv2.imread('/home/user/catkin_ws/src/opencv_for_robotics_images/Unit_2/Course_images/Filtering.png') 
    while not rospy.is_shutdown():  
        #I resized the image so it can be easier to work with 
        image = cv2.resize(image,(300,300)) 
        #Once we read the image we need to change the color space to HSV 
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
        #Hsv limits are defined 
        #here is where you define the range of the color you're looking for 
        #each value of the vector corresponds to the H,S & V values respectively 
        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        #This is the actual color detection  
        #Here we will create a mask that contains only the colors defined in your limits 
        #This mask has only one dimension, so its black and white } 
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 
        #We use the mask with the original image to get the colored post-processed image 
        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 
        r.sleep()  
    cv2.destroyAllWindows() 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('opencv_example1', anonymous=True) 
    show_image() 

recently I was commissioned to use a robot already made in gazebo, using Ros which has a camera and I have been able to see that image through .py code. Now they ask me to filter colors (green, red and blue), I already have the high and low values, and I can do it with an image, but I don't know how to mix both programs, so that what is filtered by color, I only know what transmit the robot's camera and not an image.

All of this while using Open CV

Attached both codes

//////////////////////////////////////////////////////////////////////////////////////// 
Code to see the gazeebo virtual camera
//////////////////////////////////////////////////////////////////////////////////////// 

#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    while not rospy.is_shutdown():  
        if image_received: 
            cv2.waitKey(1) 
            r.sleep()  
    cv2.destroyAllWindows() 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
        #Add your code to save the image here: 
        #Save the image "img" in the current path  
        cv2.imwrite('robot_image.jpg', cv_image)        
        #Display the image in a window 
        cv2.imshow('Image from robot camera', cv_image) 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('load_image', anonymous=True) 
    show_image() 

//////////////////////////////////////////////////////////////////////////////////////// 
code to see an image segmented in RGB by windows
//////////////////////////////////////////////////////////////////////////////////////// 

#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
#Import the numpy library which will help with some matrix operations 
import numpy as np  
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    image = cv2.imread('/home/user/catkin_ws/src/opencv_for_robotics_images/Unit_2/Course_images/Filtering.png') 
    while not rospy.is_shutdown():  
        #I resized the image so it can be easier to work with 
        image = cv2.resize(image,(300,300)) 
        #Once we read the image we need to change the color space to HSV 
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 
        #Hsv limits are defined 
        #here is where you define the range of the color you're looking for 
        #each value of the vector corresponds to the H,S & V values respectively 
        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        #This is the actual color detection  
        #Here we will create a mask that contains only the colors defined in your limits 
        #This mask has only one dimension, so its black and white } 
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 
        #We use the mask with the original image to get the colored post-processed image 
        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 
        r.sleep()  
    cv2.destroyAllWindows() 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('opencv_example1', anonymous=True) 
    show_image() 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

是你 2025-01-20 18:41:21

首先,该代码中存在很多结构问题。您应该考虑使用类并通过实现相互通信的单独节点来遵循 ROS 理念。另请参阅 rospy 教程。

要“混合”这两个程序,您可以创建一个函数来处理接收图像的第一个程序中的颜色

def process_image(image):
        image = cv2.resize(image,(300,300)) 
        
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 

        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 

,并在每次接收图像时调用它一次(在回调内)。通常最好将所有这些处理划分为多个线程,但是,作为起点,您可以使用如下内容:


#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    while not rospy.is_shutdown():  
        if image_received: 
            cv2.waitKey(1) 
            r.sleep()  
    cv2.destroyAllWindows() 
def process_image(image):
        image = cv2.resize(image,(300,300)) 
        
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 

        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
        #Add your code to save the image here: 
        #Save the image "img" in the current path  
        cv2.imwrite('robot_image.jpg', cv_image)        
        ## Calling the processing function
        process_image(cv_image)
        cv2.imshow('Image from robot camera', cv_image) 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('load_image', anonymous=True) 
    show_image() 

您还应该避免在函数内声明全局变量。

First of all there a lot structural problems in that code. You should consider using Classes and follow the ROS philosophy by implementing separates nodes that communicates with each other. Please take a look also to the rospy tutorials.

To "mix" both programs you can either create a function that processes the color in your first program that receives the image

def process_image(image):
        image = cv2.resize(image,(300,300)) 
        
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 

        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 

And calling it once every time you receive an image (inside the callback). Usually it's preferable to divide all this processing in multiple threads, but, as a start point you could use something like this:


#!/usr/bin/env python 
import rospy 
from sensor_msgs.msg import Image 
from cv_bridge import CvBridge, CvBridgeError 
import cv2 
bridge_object = CvBridge() # create the cv_bridge object 
image_received = 0 #Flag to indicate that we have already received an image 
cv_image = 0 #This is just to create the global variable cv_image  
def show_image(): 
    image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback) 
    r = rospy.Rate(10) #10Hz  
    while not rospy.is_shutdown():  
        if image_received: 
            cv2.waitKey(1) 
            r.sleep()  
    cv2.destroyAllWindows() 
def process_image(image):
        image = cv2.resize(image,(300,300)) 
        
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) 

        min_green = np.array([50,220,220]) 
        max_green = np.array([60,255,255]) 
        min_red = np.array([170,220,220]) 
        max_red = np.array([180,255,255]) 
        min_blue = np.array([110,220,220]) 
        max_blue = np.array([120,255,255]) 
        
        mask_g = cv2.inRange(hsv, min_green, max_green) 
        mask_r = cv2.inRange(hsv, min_red, max_red) 
        mask_b = cv2.inRange(hsv, min_blue, max_blue) 

        res_b = cv2.bitwise_and(image, image, mask= mask_b) 
        res_g = cv2.bitwise_and(image,image, mask= mask_g) 
        res_r = cv2.bitwise_and(image,image, mask= mask_r) 
        cv2.imshow('Green',res_g) 
        cv2.imshow('Red',res_b) 
        cv2.imshow('Blue',res_r) 
        cv2.imshow('Original',image) 
        cv2.waitKey(1) 
def camera_callback(data): 
    global bridge_object 
    global cv_image 
    global image_received 
    image_received=1 
    try: 
        print("received ROS image, I will convert it to opencv") 
        # We select bgr8 because its the OpenCV encoding by default 
        cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8") 
        #Add your code to save the image here: 
        #Save the image "img" in the current path  
        cv2.imwrite('robot_image.jpg', cv_image)        
        ## Calling the processing function
        process_image(cv_image)
        cv2.imshow('Image from robot camera', cv_image) 
    except CvBridgeError as e: 
        print(e) 
if __name__ == '__main__': 
    rospy.init_node('load_image', anonymous=True) 
    show_image() 

You should also avoid declaring globals variables inside a function.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文