Ask me anything
Ithy Logo
Sign in to save

使用C语言和OpenCV在Visual Studio上检测RM比赛中的装甲板

实现平移和旋转运动中小车装甲板的高效检测

robotic armored plate detection

三个关键要点

  • 环境配置与OpenCV安装:正确配置开发环境是成功实现装甲板检测的基础。
  • 图像处理与目标识别算法:包括颜色分割、形态学处理和轮廓检测等关键步骤。
  • 代码优化与调试技巧:通过参数调整和算法优化提升检测的准确性与稳定性。

环境配置与OpenCV安装

1. 安装OpenCV库

在Visual Studio (VS) 上使用C语言进行图像处理和装甲板检测,首先需要安装OpenCV库。以下是安装步骤:

1.1 从官网下载预编译库

访问OpenCV的官方网站(https://opencv.org),下载适合的预编译版本。解压后,将其放置在一个易于访问的位置,例如 C:\OpenCV。

1.2 使用包管理工具安装

Alternatively, you can use package managers like vcpkg to install OpenCV:

# 使用vcpkg安装OpenCV
vcpkg install opencv
vcpkg integrate install
    

2. 配置Visual Studio项目

在Visual Studio中创建一个新的C项目,并进行以下配置:

2.1 添加包含目录和库目录

在项目属性中,导航到 C/C++ -> 常规,添加OpenCV的头文件路径。例如:

  • C:\OpenCV\build\include

然后,导航到 链接器 -> 常规,添加OpenCV的库文件路径,例如:

  • C:\OpenCV\build\x64\vc15\lib

2.2 配置依赖库

在 链接器 -> 输入 -> 附加依赖项 中,添加OpenCV的库文件名称。例如:

  • opencv_world455.lib

图像处理与目标识别算法

1. 图像预处理

图像预处理是提高检测准确性的关键步骤,主要包括颜色空间转换和噪声去除。

1.1 颜色空间转换

将输入图像从BGR颜色空间转换为HSV颜色空间,以便更容易进行颜色分割:

cvtColor(frame, hsv, COLOR_BGR2HSV);
    

1.2 颜色分割

根据装甲板的颜色(通常为红色或蓝色)定义颜色阈值,创建掩膜:


// 定义红色范围
Scalar lower_red1(0, 100, 100);
Scalar upper_red1(10, 255, 255);
Scalar lower_red2(170, 100, 100);
Scalar upper_red2(180, 255, 255);

// 创建红色掩膜
Mat redMask1, redMask2, redMask;
inRange(hsv, lower_red1, upper_red1, redMask1);
inRange(hsv, lower_red2, upper_red2, redMask2);
redMask = redMask1 | redMask2;

// 定义蓝色范围
Scalar lower_blue(100, 150, 50);
Scalar upper_blue(140, 255, 255);

// 创建蓝色掩膜
Mat blueMask;
inRange(hsv, lower_blue, upper_blue, blueMask);
    

2. 形态学处理

使用形态学操作去除噪声并填补目标区域中的孔洞:


Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(mask, mask, MORPH_OPEN, kernel);
morphologyEx(mask, mask, MORPH_CLOSE, kernel);
    

3. 轮廓检测与筛选

查找图像中的轮廓,并根据面积和形状特征筛选出潜在的装甲板区域:


vector<vector<Point>> contours;
findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

for (const auto& contour : contours) {
    double area = contourArea(contour);
    if (area < 300) continue; // 过滤小轮廓
    
    // 多边形逼近
    vector<Point> approx;
    approxPolyDP(contour, approx, 0.02 * arcLength(contour, true), true);
    
    // 最小外接矩形
    RotatedRect rect = minAreaRect(contour);
    float width = rect.size.width;
    float height = rect.size.height;
    if(width < height) swap(width, height);
    float ratio = width / height;
    if (ratio < 2.0 || ratio > 5.0) continue; // 根据装甲板比例筛选
    
    // 绘制检测结果
    Point2f boxPoints[4];
    rect.points(boxPoints);
    for(int j=0; j<4; j++) {
        line(frame, boxPoints[j], boxPoints[(j+1)%4], Scalar(0, 255, 0), 2);
    }
    circle(frame, rect.center, 3, Scalar(0,0,255), -1);
}
    

4. 装甲板匹配与识别

利用检测到的灯条位置和角度信息,匹配出装甲板并进行识别:


// 代码示例略,可根据具体需求添加模板匹配或机器学习方法
    

代码实现

1. 基本结构

以下是一个完整的C++示例代码,用于在Visual Studio中使用OpenCV检测RM比赛中的装甲板:


// armor_detection.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

// 装甲板检测函数
bool detectArmorPlate(Mat& frame) {
    // 1. 图像预处理
    Mat hsv;
    cvtColor(frame, hsv, COLOR_BGR2HSV);
    
    // 2. 颜色分割
    Scalar lower_red1(0, 100, 100), upper_red1(10, 255, 255);
    Scalar lower_red2(170, 100, 100), upper_red2(180, 255, 255);
    Mat mask1, mask2, redMask;
    inRange(hsv, lower_red1, upper_red1, mask1);
    inRange(hsv, lower_red2, upper_red2, mask2);
    redMask = mask1 | mask2;
    
    // 3. 形态学处理
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(redMask, redMask, MORPH_OPEN, kernel);
    morphologyEx(redMask, redMask, MORPH_CLOSE, kernel);
    
    // 4. 轮廓检测
    vector<vector<Point>> contours;
    findContours(redMask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    
    // 5. 筛选并绘制装甲板
    for (const auto& contour : contours) {
        double area = contourArea(contour);
        if (area < 300) continue;
        
        RotatedRect rect = minAreaRect(contour);
        float width = rect.size.width;
        float height = rect.size.height;
        if(width < height) swap(width, height);
        float ratio = width / height;
        if (ratio < 2.0 || ratio > 5.0) continue;
        
        Point2f boxPoints[4];
        rect.points(boxPoints);
        for(int j=0; j<4; j++) {
            line(frame, boxPoints[j], boxPoints[(j+1)%4], Scalar(0, 255, 0), 2);
        }
        circle(frame, rect.center, 3, Scalar(0,0,255), -1);
    }
    
    return !contours.empty();
}

int main() {
    VideoCapture cap(0); // 打开默认摄像头
    if(!cap.isOpened()) {
        cout << "无法打开摄像头" << endl;
        return -1;
    }
    
    Mat frame;
    while(true) {
        cap >> frame;
        if(frame.empty()) break;
        
        bool detected = detectArmorPlate(frame);
        imshow("Armor Plate Detection", frame);
        
        if(waitKey(30) == 'q') break; // 按'q'键退出
    }
    
    cap.release();
    destroyAllWindows();
    return 0;
}
    

2. 详细代码注解

上述代码的主要功能模块解释如下:

模块 功能描述
图像预处理 将BGR图像转换为HSV颜色空间,并进行颜色分割以提取装甲板颜色区域。
形态学处理 通过开操作和闭操作去除噪声并连接断裂部位,强化目标区域。
轮廓检测 查找图像中的轮廓,并筛选出符合装甲板特征的轮廓区域。
装甲板绘制 在检测到的装甲板区域绘制边界框和中心点,便于视觉确认。

3. 参数调整

不同比赛环境下,光照条件和装甲板颜色可能有所不同,因此需要根据实际情况调整以下参数:

  • 颜色阈值:调整HSV空间中的下界和上界,以适应红色或蓝色装甲板。
  • 面积阈值:根据装甲板在图像中的大小调整过滤掉过小或过大的轮廓。
  • 长宽比:调整装甲板的长宽比范围,确保筛选出的轮廓符合装甲板的实际形状。

优化与调试技巧

1. 参数优化

通过逐步调整颜色阈值、形态学处理核大小以及面积和长宽比阈值,不断优化检测算法的准确性。

1.1 动态调节

使用Trackbar动态调整参数,实时观察检测效果,以确定最优参数组合:


// 创建Trackbar用于动态调整颜色阈值
int lower_h = 0, lower_s = 100, lower_v = 100;
namedWindow("Controls", WINDOW_AUTOSIZE);
createTrackbar("Lower H", "Controls", &lower_h, 180);
createTrackbar("Lower S", "Controls", &lower_s, 255);
createTrackbar("Lower V", "Controls", &lower_v, 255);
// 类似地创建Upper H, Upper S, Upper V Trackbar
    

2. 防抖与跟踪策略

在装甲板进行平移和旋转运动时,可能会出现检测不稳定的问题。以下是一些优化策略:

  • 历史帧信息融合:结合多帧的检测结果,通过平均或加权方式减少单帧误差。
  • 卡尔曼滤波:应用卡尔曼滤波器预测装甲板位置,提高检测的稳定性和预测性。
  • 模板匹配与特征匹配:在检测过程中引入模板匹配或特征匹配,增强对旋转和尺度变化的适应能力。

示例代码

完整代码示例


// full_armor_detection.cpp

#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>

using namespace cv;
using namespace std;

// 装甲板检测函数
bool detectArmorPlate(Mat& frame) {
    // 1. 图像预处理
    Mat hsv;
    cvtColor(frame, hsv, COLOR_BGR2HSV);
    
    // 2. 红色装甲板颜色分割
    Scalar lower_red1(0, 100, 100), upper_red1(10, 255, 255);
    Scalar lower_red2(170, 100, 100), upper_red2(180, 255, 255);
    Mat mask1, mask2, redMask;
    inRange(hsv, lower_red1, upper_red1, mask1);
    inRange(hsv, lower_red2, upper_red2, mask2);
    redMask = mask1 | mask2;
    
    // 3. 形态学处理
    Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(redMask, redMask, MORPH_OPEN, kernel);
    morphologyEx(redMask, redMask, MORPH_CLOSE, kernel);
    
    // 4. 轮廓检测
    vector<vector<Point>> contours;
    findContours(redMask, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    
    // 5. 筛选并绘制装甲板
    for (const auto& contour : contours) {
        double area = contourArea(contour);
        if (area < 300) continue;
        
        RotatedRect rect = minAreaRect(contour);
        float width = rect.size.width;
        float height = rect.size.height;
        if(width < height) swap(width, height);
        float ratio = width / height;
        if (ratio < 2.0 || ratio > 5.0) continue;
        
        Point2f boxPoints[4];
        rect.points(boxPoints);
        for(int j=0; j<4; j++) {
            line(frame, boxPoints[j], boxPoints[(j+1)%4], Scalar(0, 255, 0), 2);
        }
        circle(frame, rect.center, 3, Scalar(0,0,255), -1);
    }
    
    return !contours.empty();
}

int main() {
    VideoCapture cap(0); // 打开默认摄像头
    if(!cap.isOpened()) {
        cout << "无法打开摄像头" << endl;
        return -1;
    }
    
    Mat frame;
    while(true) {
        cap >> frame;
        if(frame.empty()) break;
        
        bool detected = detectArmorPlate(frame);
        imshow("Armor Plate Detection", frame);
        
        if(waitKey(30) == 'q') break; // 按'q'键退出
    }
    
    cap.release();
    destroyAllWindows();
    return 0;
}
    

结论

通过以上步骤和示例代码,您可以在Visual Studio环境下使用C++和OpenCV实现RM比赛中小车装甲板的检测。关键在于正确的环境配置、合理的图像处理算法以及针对实际比赛环境的参数优化。结合防抖与跟踪策略,可以显著提升检测系统的稳定性和准确性,从而在激烈的比赛中占据优势。


参考资料

forums.robomasterna.com
RoboMaster论坛指南
nusrobomaster.github.io
BeebleBum的RoboMaster项目
devpress.csdn.net
CSDN OpenCV教程

Last updated February 16, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask Ithy AI