Robomaster2023 能量机关识别demo

这篇具有很好参考价值的文章主要介绍了Robomaster2023 能量机关识别demo。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Robomaster2023 能量机关识别demo

Robomaster2023 能量机关识别demo

效果视频
https://www.bilibili.com/video/BV1zT411C7PY/?vd_source=15a7e7c79fb0c7348fc5147c131dd6af

/*
 * @Descripttion: 
 * @version: 
 * @Author: tjk
 * @Date: 2023-01-31 17:01:02
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2023-02-01 17:04:12
 */
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>

using namespace std;

typedef struct armor_point{
    cv::Point point;
    double dis;
}armor_point;

void drawRotatedRect(cv::Mat &img, const cv::RotatedRect &rect, const cv::Scalar &color, int thickness)
{
    cv::Point2f Vertex[4];
    rect.points(Vertex);
    for(int i = 0 ; i < 4 ; i++)
    {
        cv::line(img , Vertex[i] , Vertex[(i + 1) % 4] , color , thickness);
    }
}
double distance(cv::Point a,cv::Point b)
{
    return sqrt((a.x -b.x)*(a.x -b.x) + (a.y -b.y)*(a.y -b.y));
}

int main()
{
    string video_path = "/home/idriver/tjk/project/rm/buff_demo/blue.mp4"; 
    cv::VideoCapture cap;
    cap.open(video_path);


    // cv::VideoWriter writer;
    // int coder = cv::VideoWriter::fourcc('M','J','P','G');//选择编码格式
    // double fps=25.0;//设置视频帧率
    // string filename="live.avi";//保存的视频文件名称
    // writer.open(filename,coder,fps,cv::Size(1350,1080),true);//创建保存视频文件的视频流
    // if(!writer.isOpened()){
    //     cout<<"打开视频文件失败,请确认是否为合法输入"<<endl;
    //     return -1;
    // }

    while(true){
        cv::Mat src_frame;
        cap >> src_frame;
        cv::resize(src_frame,src_frame,cv::Size(640,480));

        vector<cv::Mat> bgr_images;
        cv::split(src_frame,bgr_images);
        cv::Mat b_src_img = bgr_images[0];
        cv::blur(b_src_img,b_src_img,cv::Size(3,3));
        
        cv::Mat threshold_img;
        cv::threshold(b_src_img,threshold_img,130,255,cv::THRESH_BINARY);
        
        vector<vector<cv::Point>> contours;
        cv::findContours(threshold_img,contours,cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
        // cv::drawContours(src_frame,contours,-1,cv::Scalar(0,0,255));
        
        cv::Point r_center; // R 的中心点
        vector<cv::RotatedRect> contours_min_rects;//所有轮廓的最小外接矩形
        vector<cv::RotatedRect> armor_min_rects;
        vector<cv::RotatedRect> target_min_rects;
        vector<cv::RotatedRect> r_min_rects; //R

        int r_index = -1;
        // int cnt = 0;
        for (unsigned int contour_index = 0; contour_index < contours.size(); contour_index++) {
        //     //寻找最小旋转矩形,放进容器,顺便将面积过大的剔除,长宽比悬殊的剔除
            cv::RotatedRect minrect = minAreaRect(contours[contour_index]);
            cv::Rect rect = boundingRect(contours[contour_index]);

            if (minrect.size.area() <= 6000.0 && minrect.size.area()>150) {
                float width;
                float height;
                //判断长宽比
                if (minrect.size.width > minrect.size.height){
                    width = minrect.size.width;
                    height = minrect.size.height;
                } else {
                    width = minrect.size.height;
                    height = minrect.size.width;
                }
                if (width / height < 5) {
                    contours_min_rects.push_back(minrect);
                    if(minrect.size.area() > 200 && minrect.size.area() < 350 && minrect.center.y > 100) { // find R
                        if(height / width > 0.85){
                            // R_minRects.push_back(minrect);
                            r_center = minrect.center;
                            cv::circle(src_frame,minrect.center,15,cv::Scalar(5,255,100));
                            r_index = contour_index;
                            // std::cout<<cnt++<<std::endl;    
                        }
                    } else {
                        if(minrect.size.area() > 300 && minrect.size.area() < 4350 && (height / width) < 0.7) {
                            armor_min_rects.push_back(minrect);
                        }     
                    }
                }   
            }
        }
        bool find_ok = false;
        for (int i = 0;i<armor_min_rects.size()-1;i++){
            for (int j = i+1;j<armor_min_rects.size();j++){
                double dis = distance(armor_min_rects[i].center,armor_min_rects[j].center);
                if(dis<100){
                    target_min_rects.push_back(armor_min_rects[i]);
                    target_min_rects.push_back(armor_min_rects[j]);
                    find_ok = true;
                    break;
                }
                // std::cout<<dis<<std::endl;
            }   
            if (find_ok){
                break;
            }    
        }
        if(target_min_rects.size() != 2){
            continue;
        } else {
            cv::RotatedRect rrect_in; //= target_minRects[0];
            cv::RotatedRect rrect_out;// = target_minRects[1];
            double dis1 = distance(r_center,target_min_rects[0].center);
            double dis2 = distance(r_center,target_min_rects[1].center);
            if (dis1 > dis2){
                rrect_in = target_min_rects[1];
                rrect_out = target_min_rects[0];
            } else {
                rrect_in = target_min_rects[0];
                rrect_out = target_min_rects[1];
            }
            drawRotatedRect(src_frame,rrect_in,cv::Scalar(0,250,0),1);
            drawRotatedRect(src_frame,rrect_out,cv::Scalar(0,0,255),1);

            cv::Point target_center = cv::Point((int)((rrect_in.center.x + rrect_out.center.x)/2),(int)((rrect_in.center.y + rrect_out.center.y)/2));
            cv::circle(src_frame,target_center,5,cv::Scalar(0,0,255),-1);
            cv::Point2f in_vet_points[4];
            cv::Point2f out_vet_points[4];
            rrect_in.points(in_vet_points);
            rrect_out.points(out_vet_points);
            vector<armor_point> armor_points; 
            for(int i = 0;i<4;i++){
                armor_point point;
                point.point = in_vet_points[i];
                point.dis = distance(target_center,in_vet_points[i]);
                armor_points.push_back(point);
            }
            for(int i = 0;i<4;i++){
                armor_point point;
                point.point = out_vet_points[i];
                point.dis = distance(target_center,out_vet_points[i]);
                armor_points.push_back(point);
            }
            sort(armor_points.begin(),armor_points.end(),[](armor_point a,armor_point b){return a.dis < b.dis;});
            for(int i = 0;i<4;i++)
            {
                cv::circle(src_frame,armor_points[i].point,3,cv::Scalar(255,0,255),-1);
            }
            int buff_run_radius = (int)distance(r_center,target_center);
            cv::circle(src_frame,r_center,buff_run_radius,cv::Scalar(55,110,255),1);
        }
        // cv::resize(src_frame,src_frame,cv::Size(1350,1080));
        // writer.write(src_frame);//把图像写入视频流
        cv::imshow("src_img",src_frame);
        // cv::imshow("threshold_img",threshold_img);
        if (cv::waitKey(0) == 'q'){
            break;
        }
        
    }
    // writer.release();
    cap.release();
    return 0;
}

注:文章来源地址https://www.toymoban.com/news/detail-512487.html

  • 只是一个demo!!!
  • 使用的仿真视频做检测,没有环境干扰,实际使用时需要很多的处理。
  • 检测思路和之前的风车检测差不多,现在使用的分离式灯带感觉更容易检测了。

到了这里,关于Robomaster2023 能量机关识别demo的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Robomaster上位机视觉摘要——比赛规则篇

    本文是笔者多日来总结的2023赛季中针对上位机组的比赛规则摘要,力求一文让你看懂上位机在赛场中的飒爽身影。 目录 电力元件 电池 遥控器  激光 涂装 机器人 飞镖 雷达 空中机器人 工程机器人 哨兵机器人 英雄与步兵机器人 视觉应用 识别装甲板 算法步骤 反制与反反制

    2024年02月04日
    浏览(34)
  • 【RoboMaster】从零开始控制RM电机(4)-单环PID控制

    硬件以及软件环境: STM32Cube_FW_F4_V1.26.2 MDK-ARM 5.29.0.0 大疆RoboMaster开发板A型开发板(STM32F427IIHx)/C型开发板(STM32F407IGTx) 源码: RM_ctrl 本系列文章目录: 【RoboMaster】从零开始控制RM电机(2)-CAN通信原理及电调通信协议 【RoboMaster】从零开始控制RM电机(3)- 建立与电调的通

    2024年02月01日
    浏览(30)
  • [已解决] KVM 显卡直通 (GPU-passthrough) 直通虚拟机关机后 显示屏黑屏

    按照LED 显卡直通做完所有工作后,win10直通虚拟机成功运行且安装上了驱动。 但是当虚拟机关机后,显卡似乎并没有归还,导致显示屏一直处于黑屏,但是ssh可以连接。 经过hooks日志查看发现,当钩子执行到 时脚本会被kill. google后,在reddit帖子下找到解决办法: adding video=e

    2024年02月04日
    浏览(41)
  • 【超详细】基于大疆RoboMaster开发板C型的BMI088数据读取

    这里以博世传感器公司产出的BMI088型号的IMU为例,其里面有3轴高精度加速度计和3轴高精度陀螺仪,其他的特性不再介绍 同时这里的IMU是安装在大疆公司出产的RoboMaster开发板C型,单片机芯片是STM32F407IGH6,其外围电路已经设计好,只需要读取IMU数据即可。 本篇不会介绍SPI、

    2023年04月08日
    浏览(62)
  • 【能量算子】评估 EEG 中的瞬时能量:非负、频率加权能量算子(Python&Matlab代码实现)

    💥💥💞💞 欢迎来到本博客 ❤️❤️💥💥 🏆博主优势: 🌞🌞🌞 博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️ 座右铭: 行百里者,半于九十。 📋📋📋 本文目录如下: 🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Python、Matlab代码实现

    2024年02月08日
    浏览(42)
  • RoboMaster EP 实用功能开发(三): 基于树莓派的ROS2机器人系统搭建

    功能: 在树莓派4b上安装ros2系统,引入robomaster sdk,搭建一个基于ROS2的机器人系统,用于ROS系统的学习、开发和实践。 硬件: RobotMaster EP、树莓派4b 系统平台: Ubuntu 20.04、ROS2(Foxy) 开发语言及主要库函数版本:p ython == 3.8,robomaster == 0.1.1.62 一、树莓派4b安装ubuntu20.04  

    2024年02月09日
    浏览(45)
  • CVPR 2023 | OpenGait: 步态识别开源框架介绍

    Title : OpenGait: Revisiting Gait Recognition Toward Better Practicality Paper : https://arxiv.org/pdf/2211.06597.pdf Code : https://github.com/ShiqiYu/OpenGait 今天为大家介绍的 OpenGait 便是一套基于 Pytorch 构建的步态识别( Gait Recognition )框架,其涵盖了一系列最先进的步态识别算法,同时提供了一个结构简单但

    2024年02月04日
    浏览(69)
  • Robomaster电控组小白的学习经验分享(一)——用大疆C型开发板控制GM6020电机转动到既定角度

    88ab4432dec2153611cbbc8f98d96f0f 1、大疆C型开发板         我们可以从Robomaster官网上下载C板的用户使用手册,在编写代码的时候用户开发手册往往非常重要。引脚配置、IO说明等信息都可以从用户手册上获得。 2、GM6020电机         GM6020的说明手册也可以从Robomaster的官网上下载,

    2024年02月16日
    浏览(37)
  • 2023身份识别技术大会 | 安全证件 | 数字认证 | 生物识别 | 公共安全安防身份技术展览会

    展会名称:  2023身份识别技术大会 | 安全证件 | 数字认证 | 生物识别 | 公共安全安防身份技术展览会 举办时间: 2023年5月17-18日 举办地点:  北京 国家会议中心 指导单位:  公安部科技信息化局 主办单位:  多维身份识别与可信认证技术国家工程研究中心 中国国际科技促

    2024年02月07日
    浏览(54)
  • 流体力学控制方程——能量方程

    这里仍然采用随流体运动的无穷小流体微团为研究对象推导能量方程。根据热力学第一定律,对于随流体运动的微团模型而言,其满足能量守恒定律,即: 流体微团内能量的变化率=流入微团内的净热流量+体积力和表面力对微团做功的功率 首先来看体积力以及表面力对微团做

    2024年02月08日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包