D435+opencv识别色块

时间:2024-04-27 07:03:38

在当前的机器视觉和机器人技术领域,实时图像处理是一项至关重要的技术。本文介绍了如何利用Python、OpenCV库以及Intel的Realsense摄像头来进行实时的颜色识别。这种技术可以广泛应用于自动化检测、机器人导航以及交互式媒体等领域。

一、 开发环境配置

首先,我们需要配置Python开发环境,确保安装了`pyrealsense2`和`numpy`、`opencv-python`(通常简称cv2)这些库。这些库允许我们操作Realsense摄像头并进行图像处理。

```bash

pip install pyrealsense2 numpy opencv-python

```

整体代码:
 

#!/usr/bin/env python3.8
# _*_ coding: utf-8 _*_
# 导入依赖
import pyrealsense2 as rs
import numpy as np
import cv2

# 设置颜色字典
ball_color = 'red'
color_dist = {
    'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},
    'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},
    'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},
}

# 初始化realsense相机
pipeline = rs.pipeline()
config = rs.config()
config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)
config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)
pipeline.start(config)

# 创建opencv窗口
cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)

try:
    while True:
        # 等待一帧数据
        frames = pipeline.wait_for_frames()
        color_frame = frames.get_color_frame()
        if not color_frame:
            continue

        # 将图像转为numpy数组以便OpenCV处理
        color_image = np.asanyarray(color_frame.get_data())

        # 颜色识别流程
        gs_frame = cv2.GaussianBlur(color_image, (5, 5), 0)  # 高斯模糊
        hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)      # 转换到HSV
        erode_hsv = cv2.erode(hsv, None, iterations=2)      # 腐蚀处理
        inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])
        cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        
        if len(cnts) > 0:
            c = max(cnts, key=cv2.contourArea)
            rect = cv2.minAreaRect(c)
            box = cv2.boxPoints(rect)
            cv2.drawContours(color_image, [np.int0(box)], -1, (0, 255, 255), 2)

        cv2.imshow('RealSense', color_image)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
finally:
    # 停止流
    pipeline.stop()
    cv2.destroyAllWindows()

二、 设定颜色字典

在开始编写代码之前,首先设定一个颜色字典,用于定义我们想要识别的颜色范围。这里,我们定义了红色、蓝色和绿色三种颜色的HSV范围。HSV(色相、饱和度、亮度)是一种比RGB颜色空间更适合颜色识别的模型。

```python

color_dist = {

    'red': {'Lower': np.array([0, 60, 60]), 'Upper': np.array([6, 255, 255])},

    'blue': {'Lower': np.array([100, 80, 46]), 'Upper': np.array([124, 255, 255])},

    'green': {'Lower': np.array([35, 43, 35]), 'Upper': np.array([90, 255, 255])},

}

```

三、 初始化和配置Realsense摄像头

通过`pyrealsense2`库,我们可以轻松初始化Intel Realsense摄像头,并设置其流输出格式。本示例中,我们启用了640x480分辨率的深度流和颜色流。

```python

pipeline = rs.pipeline()

config = rs.config()

config.enable_stream(rs.stream.depth, 640, 480, rs.format.z16, 30)

config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

pipeline.start(config)

```

四、 实时颜色识别

在获取到摄像头的实时视频流后,我们对每一帧图像进行如下处理:

1. 应用高斯模糊,以减少图像噪声。

2. 将图像从BGR转换到HSV颜色空间。

3. 对HSV图像进行腐蚀处理,以过滤小的颜色斑点。

4. 使用`cv2.inRange`函数根据颜色字典中的阈值检测特定颜色。

通过以上步骤,我们可以将图像中的特定颜色区域提取出来。如果找到相应颜色的轮廓,我们计算其最小覆盖矩形,并在原图上绘制该矩形,从而实现实时的颜色跟踪。

```python

color_image = np.asanyarray(color_frame.get_data())

gs_frame = cv2.GaussianBlur(color_image, (5, 5), 0)

hsv = cv2.cvtColor(gs_frame, cv2.COLOR_BGR2HSV)

erode_hsv = cv2.erode(hsv, None, iterations=2)

inRange_hsv = cv2.inRange(erode_hsv, color_dist[ball_color]['Lower'], color_dist[ball_color]['Upper'])

```

在我们的实时颜色识别程序中,一段关键的代码负责识别和高亮显示特定颜色的对象。这部分代码如下:

```python

cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]

if len(cnts) > 0:

    c = max(cnts, key=cv2.contourArea)

    rect = cv2.minAreaRect(c)

    box = cv2.boxPoints(rect)

    cv2.drawContours(color_image, [np.int0(box)], -1, (0, 255, 255), 2)

```

五、 识别显示

1. 轮廓查找:

   - `cv2.findContours()` 函数用于在二值图像中查找轮廓,这里的图像是已经通过颜色阈值处理后的 `inRange_hsv`。

   - `cv2.RETR_EXTERNAL` 参数表示仅检索最外层轮廓,适合我们的需求,因为我们关心的是物体的外围轮廓。

   - `cv2.CHAIN_APPROX_SIMPLE` 是一个轮廓近似方法,它压缩水平、垂直和对角线段,只留下它们的端点。这种方法有效减少存储空间,并去除不必要的信息。

2. 选择最大轮廓:

   - 从所有检测到的轮廓中,我们选择面积最大的一个,认为这是我们要追踪的主要对象。`max(cnts, key=cv2.contourArea)` 实现了这一点。

3. 计算最小矩形并绘制:

   - `cv2.minAreaRect()` 函数计算轮廓的最小外接矩形,无论对象的角度如何。

   - `cv2.boxPoints()` 函数根据 `minAreaRect` 的输出,生成矩形的四个角点。

   - 使用 `cv2.drawContours()` 在原始彩色图像上绘制这个矩形,用以高亮显示检测到的对象。

4. 显示图像与退出:

   - `cv2.imshow()` 用于在窗口中显示实时视频流中的帧。

   - `cv2.waitKey(1)` 检测按键操作。如果检测到按键 `q`,则退出循环,这是程序结束录像和关闭窗口的信号。

通过这一系列步骤,我们能够在视频流中实时检测并标记特定颜色的对象,为进一步的图像处理或机器人视觉任务提供基础。

六、 识别优化:

为了优化实时颜色识别的精确度和效率,我们可以在原有代码的基础上调整图像预处理和轮廓筛选的参数。这将有助于提高算法的性能和适应不同的应用场景。下面将详细说明如何实现这些调整:

 1. 图像预处理调整

图像预处理主要包括应用高斯模糊以及腐蚀操作,来减少噪点和改善图像质量。在代码中,这可以通过调整 `cv2.GaussianBlur` 和 `cv2.erode` 的参数实现。

2. 高斯模糊

高斯模糊有助于减少图像噪声和细节,使颜色块更加连贯。可以通过调整核的大小和标准差来控制模糊程度。

```python

# 调整高斯模糊的核大小和标准差

kernel_size = (5, 5)  # 可增大核尺寸例如(9, 9)

sigma = 0             # 标准差,0表示由函数自动计算

gs_frame = cv2.GaussianBlur(color_image, kernel_size, sigma)

```

3. 腐蚀操作

腐蚀可以帮助移除小的颜色斑点,增强图像中主要颜色区域的连续性。可以通过调整腐蚀的核大小和迭代次数来改变其效果。

```python

# 调整腐蚀的核大小和迭代次数

erode_size = (3, 3)  # 核的大小

iterations = 2       # 迭代次数,可以增加以增强效果

erode_kernel = np.ones(erode_size, np.uint8)

erode_hsv = cv2.erode(hsv, erode_kernel, iterations=iterations)

```

4.轮廓筛选标准

轮廓筛选是颜色识别后处理的重要部分,通过选择适当的轮廓可以排除不必要的小区域和误识别,提高识别的准确性。

5. 轮廓面积过滤

在检测到的轮廓中,我们通常只关心较大的对象。设置一个面积阈值,只考虑面积超过此阈值的轮廓。

```python

min_area = 100  # 设置最小面积阈值

cnts = cv2.findContours(inRange_hsv.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]

filtered_cnts = [c for c in cnts if cv2.contourArea(c) > min_area]  # 过滤小面积轮廓

if len(filtered_cnts) > 0:

    c = max(filtered_cnts, key=cv2.contourArea)  # 选择最大的轮廓

    # ...之后的代码处理选中的轮廓

```

这些调整可以显著提高颜色识别的精度和鲁棒性,特别是在复杂环境中。通过试验不同的参数设置,可以找到最适合具体应用场景的配置。在实际部署前,建议在不同的光照和背景条件下进行充分测试,以确保系统的可靠性和效果。