ROS+Python-opencv(2)

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 PS-Micro, Co. Ltd.
#
# SPDX-License-Identifier: Apache-2.0
#

#该python文件可以当作节点放在工作空间中启动

import time

import rospy
import cv2
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
import numpy as np
from math import *
from geometry_msgs.msg import Pose

HUE_LOW = 170
HUE_HIGH = 185
SATURATION_LOW = 170
SATURATION_HIGH = 255
VALUE_LOW = 70
VALUE_HIGH = 255

lower[0] = [156, 43, 46]  # 红色阈值下界
higher[0] = [180, 255, 255]  # 红色阈值上界
lower[1] = [25, 43, 46]  # 黄色阈值下界
higher[1] = [35, 255, 255]  # 黄色阈值上界
lower[2] = [90, 43, 46]  # 蓝色
higher[2] = [124, 255, 255]
lower[3] = [35, 43, 46]  # 绿色
higher[3] = [99, 255, 255]
lower[4] = [0, 43, 46]  # 红色阈值下界
higher[4] = [10, 255, 255]  # 红色阈值上界

class ImageConverter:
    def __init__(self):
        # 创建图像缓存相关的变量
        self.cv_image = None
        self.get_image = False

        # 创建cv_bridge
        self.bridge = CvBridge()

        # 声明图像的发布者和订阅者
        self.image_pub = rospy.Publisher("object_detect_image",
                                         Image,
                                         queue_size=1)
        self.target_pub = rospy.Publisher("object_detect_pose",
                                          Pose,
                                          queue_size=1)
        self.image_sub = rospy.Subscriber("/iris_0/camera/image_raw",
                                          Image,
                                          self.callback,
                                          queue_size=1)

    def callback(self, data):
        # 判断当前图像是否处理完
        if not self.get_image:
            # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
            try:
                self.cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
            except CvBridgeError as e:
                print(e)
            # 设置标志,表示收到图像
            self.get_image = True

    def detect_object(self):
        # 创建HSV阈值列表
        boundaries = [([HUE_LOW, SATURATION_LOW,
                        VALUE_LOW], [HUE_HIGH, SATURATION_HIGH, VALUE_HIGH])]

        # 遍历HSV阈值列表
        for (lower, upper) in boundaries:
            # 创建HSV上下限位的阈值数组
            lower = np.array(lower, dtype="uint8")
            upper = np.array(upper, dtype="uint8")

        # 高斯滤波,对图像邻域内像素进行平滑
        hsv_image = cv2.GaussianBlur(self.cv_image, (5, 5), 0)

        # 颜色空间转换,将RGB图像转换成HSV图像
        hsv_image = cv2.cvtColor(hsv_image, cv2.COLOR_BGR2HSV)
        
        # 根据阈值,去除背景
        mask = cv2.inRange(hsv_image, lower, upper)
        output = cv2.bitwise_and(self.cv_image, self.cv_image, mask=mask)

        # 将彩色图像转换成灰度图像
        cvImg = cv2.cvtColor(output, 6)  # cv2.COLOR_BGR2GRAY
        npImg = np.asarray(cvImg)
        thresh = cv2.threshold(npImg, 1, 255, cv2.THRESH_BINARY)[1]

        # 检测目标物体的轮廓
        cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST,
                                                cv2.CHAIN_APPROX_NONE)

        # 遍历找到的所有轮廓线
        for c in cnts:

            # 去除一些面积太小的噪声
            if c.shape[0] < 100:
                continue

            # 提取轮廓的特征
            M = cv2.moments(c)

            if int(M["m00"]) not in range(50, 1000000):
                continue

            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])

            print("x: {}, y: {}, size: {}".format(cX, cY, M["m00"]))

            # 把轮廓描绘出来,并绘制中心点
            cv2.drawContours(self.cv_image, [c], -1, (0, 0, 255), 2)
            cv2.circle(self.cv_image, (cX, cY), 5, (255, 255, 255), -1)
            
            # 将目标位置通过话题发布
            objPose = Pose()
            objPose.position.x = cX
            objPose.position.y = cY
            objPose.position.z = M["m00"]
            self.target_pub.publish(objPose)

        # 再将opencv格式额数据转换成ros image格式的数据发布
        try:
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(self.cv_image, "bgr8"))
        except CvBridgeError as e:
            print (e)
    def loop(self):
        if self.get_image:
            self.detect_object()
            self.get_image = False


if __name__ == '__main__':
    try:
        # 初始化ros节点
        rospy.init_node("object_detect")
        rospy.loginfo("Starting detect object")
        image_converter = ImageConverter()
        rate = rospy.Rate(100)
        while not rospy.is_shutdown():
            image_converter.loop()
            rate.sleep()
    except KeyboardInterrupt:
        print ("Shutting down object_detect node.")
        cv2.destroyAllWindows()

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2021 PS-Micro, Co. Ltd.
#
# SPDX-License-Identifier: Apache-2.0
#

#该python文件可以当作节点放在工作空间中启动

import time

import rospy
import cv2
from cv_bridge import CvBridge, CvBridgeError
from sensor_msgs.msg import Image
import numpy as np
from math import *
from geometry_msgs.msg import Pose

HUE_LOW = 170
HUE_HIGH = 185
SATURATION_LOW = 170
SATURATION_HIGH = 255
VALUE_LOW = 70
VALUE_HIGH = 255

lower[0] = [156, 43, 46]  # 红色阈值下界
higher[0] = [180, 255, 255]  # 红色阈值上界
lower[1] = [25, 43, 46]  # 黄色阈值下界
higher[1] = [35, 255, 255]  # 黄色阈值上界
lower[2] = [90, 43, 46]  # 蓝色
higher[2] = [124, 255, 255]
lower[3] = [35, 43, 46]  # 绿色
higher[3] = [99, 255, 255]
lower[4] = [0, 43, 46]  # 红色阈值下界
higher[4] = [10, 255, 255]  # 红色阈值上界
class ImageConverter:
    def __init__(self):
        # 创建图像缓存相关的变量
        self.cv_image = None
        self.get_image = False

        # 创建cv_bridge
        self.bridge = CvBridge()

        # 声明图像的发布者和订阅者
        self.image_pub = rospy.Publisher("object_detect_image",
                                         Image,
                                         queue_size=1)
        self.target_pub = rospy.Publisher("object_detect_pose",
                                          Pose,
                                          queue_size=1)
        self.image_sub = rospy.Subscriber("/iris_0/camera/image_raw",
                                          Image,
                                          self.callback,
                                          queue_size=1)

    def callback(self, data):
        # 判断当前图像是否处理完
        if not self.get_image:
            # 使用cv_bridge将ROS的图像数据转换成OpenCV的图像格式
            try:
                self.cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")
            except CvBridgeError as e:
                print(e)
            # 设置标志,表示收到图像
            self.get_image = True

    def detect_object(self):
        # 创建HSV阈值列表
        boundaries = [([HUE_LOW, SATURATION_LOW,
                        VALUE_LOW], [HUE_HIGH, SATURATION_HIGH, VALUE_HIGH])]

        # 遍历HSV阈值列表
        for (lower, upper) in boundaries:
            # 创建HSV上下限位的阈值数组
            lower = np.array(lower, dtype="uint8")
            upper = np.array(upper, dtype="uint8")

        # 高斯滤波,对图像邻域内像素进行平滑
        hsv_image = cv2.GaussianBlur(self.cv_image, (5, 5), 0)

        # 颜色空间转换,将RGB图像转换成HSV图像
        hsv_image = cv2.cvtColor(hsv_image, cv2.COLOR_BGR2HSV)
        
        # 根据阈值,去除背景
        mask = cv2.inRange(hsv_image, lower, upper)
        output = cv2.bitwise_and(self.cv_image, self.cv_image, mask=mask)

        # 将彩色图像转换成灰度图像
        cvImg = cv2.cvtColor(output, 6)  # cv2.COLOR_BGR2GRAY
        npImg = np.asarray(cvImg)
        thresh = cv2.threshold(npImg, 1, 255, cv2.THRESH_BINARY)[1]

        # 检测目标物体的轮廓
        cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_LIST,
                                                cv2.CHAIN_APPROX_NONE)

        # 遍历找到的所有轮廓线
        for c in cnts:

            # 去除一些面积太小的噪声
            if c.shape[0] < 100:
                continue

            # 提取轮廓的特征
            M = cv2.moments(c)

            if int(M["m00"]) not in range(50, 1000000):
                continue

            cX = int(M["m10"] / M["m00"])
            cY = int(M["m01"] / M["m00"])

            print("x: {}, y: {}, size: {}".format(cX, cY, M["m00"]))

            # 把轮廓描绘出来,并绘制中心点
            cv2.drawContours(self.cv_image, [c], -1, (0, 0, 255), 2)
            cv2.circle(self.cv_image, (cX, cY), 5, (255, 255, 255), -1)
            
            # 将目标位置通过话题发布
            objPose = Pose()
            objPose.position.x = cX
            objPose.position.y = cY
            objPose.position.z = M["m00"]
            self.target_pub.publish(objPose)

        # 再将opencv格式额数据转换成ros image格式的数据发布
        try:
            self.image_pub.publish(self.bridge.cv2_to_imgmsg(self.cv_image, "bgr8"))
        except CvBridgeError as e:
            print (e)
    def loop(self):
        if self.get_image:
            self.detect_object()
            self.get_image = False


if __name__ == '__main__':
    try:
        # 初始化ros节点
        rospy.init_node("object_detect")
        rospy.loginfo("Starting detect object")
        image_converter = ImageConverter()
        rate = rospy.Rate(100)
        while not rospy.is_shutdown():
            image_converter.loop()
            rate.sleep()
    except KeyboardInterrupt:
        print ("Shutting down object_detect node.")
        cv2.destroyAllWindows()

  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
ROS中结合OpenCV进行图像检测,可以使用以下步骤: 1. 订阅图像话题 首先,需要订阅相机或其他设备发布的图像话题,并将其转换为OpenCV可处理的格式。可以使用ROS自带的`cv_bridge`包将ROS图像消息转换为OpenCV图像格式。以下是一个示例代码,订阅名为`/camera/image_raw`的图像话题,并将其转换为OpenCV图像: ```python import rospy import cv2 from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError bridge = CvBridge() def image_callback(msg): try: cv_image = bridge.imgmsg_to_cv2(msg, "bgr8") except CvBridgeError as e: print(e) else: # 在这里进行图像检测 # ... rospy.init_node('image_subscriber') image_topic = "/camera/image_raw" rospy.Subscriber(image_topic, Image, image_callback) rospy.spin() ``` 在上述代码中,`image_callback`函数将接收到的ROS图像消息转换为OpenCV图像,并在其中进行图像检测。 2. 进行图像检测 一旦将图像转换为OpenCV格式,就可以使用OpenCV库中的函数进行图像处理和检测。例如,可以使用OpenCV中的`cv2.CascadeClassifier`类来进行人脸检测。以下是一个示例代码: ```python import rospy import cv2 from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError bridge = CvBridge() face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') def image_callback(msg): try: cv_image = bridge.imgmsg_to_cv2(msg, "bgr8") except CvBridgeError as e: print(e) else: gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: cv2.rectangle(cv_image,(x,y),(x+w,y+h),(255,0,0),2) cv2.imshow("Image window", cv_image) cv2.waitKey(3) rospy.init_node('image_subscriber') image_topic = "/camera/image_raw" rospy.Subscriber(image_topic, Image, image_callback) rospy.spin() ``` 在上述代码中,`haarcascade_frontalface_default.xml`是一个预训练的分类器文件,用于人脸检测。代码中使用`cv2.CascadeClassifier`类加载该文件,并使用`detectMultiScale`函数进行人脸检测。检测到人脸后,代码在图像中绘制矩形框以标记人脸。 3. 显示图像结果 最后,将检测结果显示在图像窗口中。可以使用OpenCV的`cv2.imshow`函数显示图像,用`cv2.waitKey`函数等待键盘输入,以保持图像窗口的显示。以下是示例代码: ```python cv2.imshow("Image window", cv_image) cv2.waitKey(3) ``` 希望这些步骤可以帮助您在ROS中结合OpenCV进行图像检测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值