0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ROS2 HSV值获取

新机器视觉 来源:古月居 2024-01-30 16:13 次阅读

计算机视觉中,颜色提取是一种常用的图像处理技术,其中HSV(色相、饱和度、明度)是一种常见的颜色空间,用于描述和提取图像中的颜色信息

HSV颜色空间将颜色表示为三个分量:色相(H)、饱和度(S)和明度(V)。

•色相(Hue):色相是颜色的类型或类别,描述了颜色在光谱中的位置。在HSV模型中,色相表示为一个角度值,通常在0到360度之间,将整个颜色光谱分为不同的颜色区域,如红、橙、黄、绿、蓝、紫等。

•饱和度(Saturation):饱和度表示颜色的纯度或强度,即颜色的深浅程度。饱和度为0时,颜色变为灰阶;饱和度为最大值时,颜色呈现出最鲜艳的状态。饱和度的取值范围通常在0到1之间,也可以表示为0%到100%。

•明度(Value):明度表示颜色的明亮度,即颜色的亮度和深度。明度为0时,颜色为黑色;明度为最大值时,颜色为白色。明度的取值范围通常在0到1之间,也可以表示为0%到100%。

通过这三个参数的组合,可以在HSV模型中精确地描述各种颜色,使得调整和理解颜色更加直观和容易。在图像处理中,HSV模型常用于调整图像的颜色平衡、色调和亮度等方面。

硬件环境

操作环境及软硬件配置如下:

OriginEye 智能相机

•PC:Ubuntu (≥20.04) + ROS2 (≥Foxy)

代码

 import cv2
  import numpy as np
  import rclpy
  from rclpy.node import Node
  from sensor_msgs.msg import Image
  from cv_bridge import CvBridge
  from collections import deque
  import textwrap


  class GetHsv(Node):
    def __init__(self):
      super().__init__('get_hsv')
      self.get_logger().info("Start get HSV")
      self.bridge = CvBridge()
      self.image_sub = self.create_subscription(Image, '/image_raw', self.image_callback, 10)
      self.pub = self.create_publisher(Image, '/camera/process_image', 10)
      self.count = 0
      self.box_width = 60
      self.collect_times = 300
      self.HSV_value = deque(maxlen=self.collect_times)
      self.H_range, self.S_range, self.V_range = 10, 80, 80
      self.lower_HSV = None
      self.upper_HSV = None


    def image_callback(self, msg):
      image = self.bridge.imgmsg_to_cv2(msg, 'bgr8')


      if self.count < self.collect_times:
        self.draw_rectangle(image)
      elif self.count < self.collect_times + self.collect_times:
        self.collect_hsv_value(image)
      else:
        self.save_hsv_value(image)


      self.count += 1
      self.pub.publish(self.bridge.cv2_to_imgmsg(image, 'bgr8'))


    def draw_rectangle(self, image):
      text = 'please put the color being tested in the rectangle box!'
      self.add_text(image, text)
      rect_x = (image.shape[1] - self.box_width) // 2
      rect_y = (image.shape[0] - self.box_width) // 2
      cv2.rectangle(image, (rect_x, rect_y), (
          rect_x + self.box_width, rect_y + self.box_width), (0, 255, 0), 3)


    def collect_hsv_value(self, image):
      text = 'HSV_value is collecting!'
      self.add_text(image, text)
      frame_x = (image.shape[1] - self.box_width) // 2
      frame_y = (image.shape[0] - self.box_width) // 2
      frame = image[frame_y:frame_y + self.box_width, frame_x:frame_x + self.box_width]
      self.HSV_value.append(self.calculate_mean_hsv(frame))


    def save_hsv_value(self, image):
      text = 'HSV_value is collected!'
      self.add_text(image,text)
      mean_HSV = np.mean(self.HSV_value, axis=0)
      self.lower_HSV, self.upper_HSV = self.calculate_hsv_range(mean_HSV)
      self.write_hsv_to_file(self.lower_HSV, self.upper_HSV)


    def calculate_mean_hsv(self, img):
      hsv_image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
      return np.mean(hsv_image, axis=(0, 1))


    def calculate_hsv_range(self, HSV_value):
      lower_H = np.clip(int(HSV_value[0] - self.H_range), 0, 180)
      upper_H = np.clip(int(HSV_value[0] + self.H_range), 0, 180)
      lower_S = np.clip(int(HSV_value[1] - self.S_range), 40, 255)
      upper_S = np.clip(int(HSV_value[1] + self.S_range), 40, 255)
      lower_V = np.clip(int(HSV_value[2] - self.V_range), 40, 255)
      upper_V = np.clip(int(HSV_value[2] + self.V_range), 40, 255)
      return np.array([lower_H, lower_S, lower_V]), np.array([upper_H, upper_S, upper_V])


    def write_hsv_to_file(self, lower_HSV, upper_HSV):
      content = f"block_HSV is : {lower_HSV[0]},
        {lower_HSV[1]},{lower_HSV[2]} {upper_HSV[0]},{upper_HSV[1]},{upper_HSV[2]}
"
      filename = "/userdata/dev_ws/color_block_HSV.txt"
      with open(filename, "w+") as f:
        f.write(content)


      self.get_logger().info(f"HSV value has been saved in {filename}")
      self.get_logger().info(content)


    def add_text(self, image, text):
      text = textwrap.wrap(text, width = 80)
      text_y = image.shape[0] // 2 - 30
      for line in text:
        text_size, _ = cv2.getTextSize(line, cv2.FONT_HERSHEY_SIMPLEX, 1.2, 2)
        text_x = (image.shape[1] - text_size[0]) // 2
        cv2.putText(image, line, (text_x, text_y), 
          cv2.FONT_HERSHEY_SIMPLEX, 1.2, (0, 255, 0), 2, cv2.LINE_AA)


  def main(args=None):
    rclpy.init(args=args)
    get_hsv = GetHsv()
    rclpy.spin(get_hsv)
    get_hsv.destroy_node()
    rclpy.shutdown()


  if __name__ == '__main__':
    main()

简要说明

这段代码的作用是通过将相机对准你希望捕捉的图像HSV值,进行一轮采集后便会将采集的HSV值存放在指定路径了。

1、为什么要做HSV值获取,HSV色彩空间相对于rgb色域有什么有特殊点吗?

简单来说,HSV色彩空间相对于RGB色域更符合人类对颜色的感知方式,更方便地进行颜色处理和分析,并且提供了更直观和灵活的颜色定义和比较方式。举个例子,人描述一个颜色通常不会直接说它的rgb值,而是描述淡绿色,艳红色等,而这正是HSV色彩空间描述的方式。

2、应用HSV时为什么通常使用upper、lower两组数据?

使用两组阈值的好处是可以更准确地定义要提取的颜色范围,同时考虑到色调环的边界情况。这样可以避免颜色提取结果受到色调环边界的影响,提高颜色提取的准确性和稳定性。

3、是否可以将图像直接使用opencv做处理?

还需要解耦图像信息,例如ROS的图像需要使用CVBridge处理成Opencv能处理的图片,又比如在处理NV12时,需要将Hbmem转成常规opencv识别的nv12格式。但无一例外我们可以称之为解耦了。

4、 HSV如何和RGB进行转换呢?

首先,将HSV中的色相、饱和度和明度分别归一化到区间[0, 1]。

归一化的色相(H’):H' = H / 360

归一化的饱和度(S’):S' = S / 100

归一化的明度(V’):V' = V / 100

接下来,使用以下公式计算RGB值:

如果饱和度为0,则RGB值为灰度色:

R = G = B = V'

如果饱和度不为0,则使用以下公式:

C = V' * S'
X = C * (1 - |(H' mod 2) - 1|
m = V' - C

然后,根据色相的不同情况,计算最终的RGB值:

当0 <= H' < 1/6 时:(R', G', B') = (C, X, 0)

当 1/6 <= H' < 2/6 时:(R', G', B') = (X, C, 0)

当 2/6 <= H' < 3/6 时:(R', G', B') = (0, C, X)

当 3/6 <= H' < 4/6 时:(R', G', B') = (0, X, C)

当 4/6 <= H' < 5/6 时:(R', G', B') = (X, 0, C)

当 5/6 <= H' <= 1 时:(R', G', B') = (C, 0, X)

最后,将得到的RGB值映射到区间[0, 255]。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 图像处理
    +关注

    关注

    26

    文章

    1225

    浏览量

    55827
  • 计算机视觉
    +关注

    关注

    8

    文章

    1600

    浏览量

    45617
  • HSV
    HSV
    +关注

    关注

    0

    文章

    10

    浏览量

    2567

原文标题:ROS2 HSV值获取

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Micro-ROS:把ROS2放在MCU上

    了机器人的发展。   ROS便是为机器人在研发的过程中的代码复用提供支持的开源框架,大量的机器人开源项目,从感知到控制、从定位到构图、从导航到可视化,几乎都使用ROS作为基础。   Micro-ROS从何而来?   Micro-
    的头像 发表于 04-07 07:13 6611次阅读

    系统镜像Ubuntu_ROS2ROS2是什么意思,带有ROS2开发环境吗?

    请问一下,百度文库资料里面,下图所示的系统镜像Ubuntu_ROS2ROS2是什么意思,带有ROS2开发环境吗?与前面4GB版本的镜像有什么区别?
    发表于 03-01 23:06

    ROS2的安装与使用 精选资料推荐

    ros2的乌龟仿真turtlesim,介绍topic,service,action等元素及其使用,介绍ros的基本操作
    发表于 08-30 08:24

    如何在ROS2中运行小乌龟呢

    ROS2中运行小乌龟,其实主要就是安装两个工具,turtlesim和rqt。A: 安装turtlesim。输入【sudo apt update】输入【sudo apt install
    发表于 11-05 06:08

    RT-Thread实时操作系统与ROS2是怎样进行通信的

    的 API,主要区别就在于 rosserial 是针对 ROS1,而 micro_ros 是针对 ROS2 。第一代的 ROS 发展很多年后,当然也暴露出很多设计不合理的地方,比如有
    发表于 04-01 11:38

    基于无线wifi网络的X3派和PC虚拟机通过ROS2实现跨设备通信

    1、X3派和PC虚拟机都连接无线wifi网络的情况下通过ROS2实现跨设备通信多机通信是ROS的基础能力之一,相比于ROS1,ROS2通过非常简单的配置即可实现多机通信。对于两个安装了
    发表于 07-13 15:13

    教你一步步创建自己的ROS2工作空间应用

    ,IP地址替换为自己的实际IP地址。ssh root@192.168.31.1922、在X3派中执行下面的命令脚本进行系统的更新以及ROS2编译环境依赖安装apt -y update &
    发表于 11-24 15:00

    imx8mp安装ros2失败的原因?

    我参考这个教程来创建一个ROS开发环境。我配置编译ROS2 dashing版时,最后编译正常生成完整固件。但是我在编译ROS2-foxy的时候会报错在meta-robot-platform/imx
    发表于 04-03 08:54

    【昉·星光 2 高性能RISC-V单板计算机体验】四:在 VisionFive2 上安装 ROS2 humble

    在 VisionFive2 上安装 ROS2 humble ROS(Robot Operating System)是一种用于编写机器人软件的灵活框架。它是一个工具(tools)、库
    发表于 09-04 03:33

    【昉·星光 2 高性能RISC-V单板计算机体验】五:在 VisionFive2 上体验 ROS2 humble

    在 VisionFive2 上体验 ROS2 humble 一、系统准备 参考 在 VisionFive2 上安装 ROS2 humble 安装并配置
    发表于 09-04 04:59

    【KV260视觉入门套件试用体验】KV260的ROS2加速相关内容

    目前在使用ros2的humble版本,但使用中感受到的编译速度慢,node启动速度慢等体会是比较影响ROS2的普及速度的,KV260因为内部存在FPGA模块,可以实现硬件加速(accelerated
    发表于 10-08 23:42

    X3派和PC虚拟机之间基于ROS2和wifi的通信

    X3派、PC虚拟机连接无线wifi网络下,通过ROS2实现跨设备通信……
    的头像 发表于 07-13 15:03 464次阅读
    X3派和PC虚拟机之间基于<b class='flag-5'>ROS2</b>和wifi的通信

    DDS在ROS2中的应用

    DDS在ROS2中的应用 DDS在ROS2系统中的位置至关重要,所有上层建设都建立在DDS之上。在这个ROS2的架构图中,蓝色和红色部分就是DDS。 刚才我们也提到,DDS是一种通信的标准,就像4G
    的头像 发表于 11-24 17:54 427次阅读
    DDS在<b class='flag-5'>ROS2</b>中的应用

    ROS2中自带例程测试

    如果你是一个ROS2的开发者,可能对刚才我们使用的ROS2命令比较熟悉,这时你可能也会产生一个问题:我们之前也安装了ROS2系统,那ROS2的原生功能还可以正常运行么? 我们再来试一试
    的头像 发表于 11-28 16:29 412次阅读
    <b class='flag-5'>ROS2</b>中自带例程测试

    在TogetherROS中如何安装ROS2功能包

    安装ROS2功能包 接下来,还有一个很重要的配置,那就是安装ROS2功能包,我们说TogetherROS是基于ROS2深度优化的,很多模块还是会复用ROS2中的功能,所有
    的头像 发表于 12-01 16:02 457次阅读
    在TogetherROS中如何安装<b class='flag-5'>ROS2</b>功能包