机器人视觉行人跟随中的extract+match feature

2024-03-05 21:38

本文主要是介绍机器人视觉行人跟随中的extract+match feature,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

机器人行人跟随ros包中加入图像特征提取和特征匹配,提取surf特征,匹配方法是快速最近邻近似搜索flann。

直接上代码:(有问题可以交流~)

/******************************************************************************
*
* The MIT License (MIT)
*
* Copyright (c) 2018 Bluewhale Robot
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Author: Randoms
*******************************************************************************/#include "tracking_node.h"using namespace cv;
using namespace std;
using namespace XiaoqiangTrack;sensor_msgs::Image last_frame;
XiaoqiangTrack::Tracker *tracker = NULL;
Rect2d body_rect;
ros::Publisher image_pub;
ros::Publisher target_pub;
std::mutex update_track_mutex;
int track_ok_flag = 0;
cv::Rect2d previous_body_rect;
cv::Rect2d body_track_rect;sensor_msgs::Image get_one_frame() { return last_frame; }void update_frame(const sensor_msgs::ImageConstPtr &new_frame) //更新帧
{last_frame = *new_frame;cv_bridge::CvImagePtr cv_ptr =cv_bridge::toCvCopy(new_frame, "bgr8"); //图像格式转换cv::Mat cv_image = cv_ptr->image;if (tracker == NULL)return;unique_lock<mutex> lock(update_track_mutex);previous_body_rect = body_rect;//将检测到的当前rect保存为previous_body_recttrack_ok_flag = tracker->updateFrame(cv_image, body_rect);cv::rectangle(cv_image, body_rect, cv::Scalar(0, 255, 0));image_pub.publish(cv_ptr->toImageMsg());xiaoqiang_track::TrackTarget target;target.x = body_rect.x + body_rect.width / 2;target.y = body_rect.y + body_rect.height / 2;target.width = body_track_rect.width;target.height = body_track_rect.height;if (track_ok_flag == 0) {// send stoptarget.x = 0;target.y = 0;}target_pub.publish(target);//target.x,target.y是跟踪的点的坐标,kalman...
}int main(int argc, char **argv) {ros::init(argc, argv, "xiaoqiang_track_node"); // ros节点初始化//在一个节点中开辟多个线程,构造时可以指定线程数如(4),AsyncSpinner有start()和stop()函数ros::AsyncSpinner spinner(4);spinner.start();ros::NodeHandle private_nh("~");ros::Publisher talk_pub = private_nh.advertise<std_msgs::String>("text", 10);image_pub = private_nh.advertise<sensor_msgs::Image>("processed_image", 10);target_pub = private_nh.advertise<xiaoqiang_track::TrackTarget>("target", 10);int watch_dog;private_nh.param("watch_dog", watch_dog, 2);ros::Subscriber image_sub = private_nh.subscribe("image", 10, update_frame);PoseTracker *client;std::string pose_tracker_type;ros::param::param<std::string>("~pose_tracker", pose_tracker_type, "");if (pose_tracker_type == "baidu") //判断跟踪类型:baidu track or body track{client = (PoseTracker *)new BaiduTrack(private_nh);} else if (pose_tracker_type == "body_pose") {client = (PoseTracker *)new BodyTrack(private_nh);} else {ROS_FATAL_STREAM("unknown pose tracker type " << pose_tracker_type);ROS_FATAL_STREAM("supported pose trakers are body_pose and baidu");exit(1);}std::string tracker_main_type;  //定义主跟踪类型std::string tracker_aided_type; //辅跟踪ros::param::param<std::string>("~tracker_main", tracker_main_type, "");ros::param::param<std::string>("~tracker_aided", tracker_aided_type, "");tracker = new XiaoqiangTrack::Tracker(tracker_main_type,tracker_aided_type); //设置跟踪器// 告诉用户站在前面std_msgs::String words;words.data = "请站在我前面";talk_pub.publish(words);// 提醒用户调整好距离sensor_msgs::Image frame = get_one_frame(); //得到一帧图像body_rect.x = -1;body_rect.y = -1;while (!ros::isShuttingDown()) {if (frame.data.size() != 0) {cv::Rect2d rect = client->getBodyRect(frame); //通过frame得到人体图像区域if (rect.x <= 1 || rect.y <= 1) {words.data = "我没有看到人,请站到我前面";talk_pub.publish(words);} else if (rect.x + rect.width / 2 > 440 ||rect.x + rect.width / 2 < 200) {body_rect = rect;words.data = "请站到镜头中间来";talk_pub.publish(words);} else {body_rect = rect;words.data = "我看到人了,开始追踪";talk_pub.publish(words);break;}}sleep(1);frame = get_one_frame();}/*¥经过分析代码,初步的想法是在这个位置加上特征提取方法和Opencv的特征匹配,思路是:-特征提取是从一帧图像中提取特征,想要提取的特征可以是ORB,FAST,SIFT,SURF等,上面的- frame = get_one_frame()是获取最新的一帧图像,return last_frame-那么对于这一帧图像抽取想要的特征信息,得到特征点,保存检测到的目标特征,之后用来与再次检测时的图像来做匹配-当然这里是做特征提取,匹配是在跟踪丢失后,再次启动检测识别时,识别到多个目标,进行匹配*//*fuck!sorry,i don't wanna say that,but i just lost everything i did the whole day because of clicking the close table without save it! so let me start at the begining...*///begining extract featureint minHessian = 2000;SurfFeatureDetector detector(minHessian);vector<KeyPoint>keypoint1, keypoint2;//image1 = resize(frame, rect.x:(rect.x+rect.width), rect.y:(rect.y+rect.higth))IplImage *img1;CvRect rectInImage1;rectInImage1 = cvRect(rect.x, rect.y,rect.width, rect.height);CvSize size1;size1.width = rectInImage.width;size1.height = rectInImage.height;img1 = CvCreatImage(size1, frame->depth, frame->nChannels);CvSetImageROI(frame, rectInImage1);cvCopy(img1, frame);//img1是从frame上提取的目标框区域//检测特征点detector.detect(img1, keypoint1)//ending // 告诉用户可以开始走了sensor_msgs::Image tracking_frame = get_one_frame();cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(tracking_frame, "bgr8");cv::Mat cv_image = cv_ptr->image;tracker->initTracker(cv_image, body_rect); // initint repeat_count = 0;int watch_dog_count = 0;while (ros::ok()) {usleep(1000 * 100); // 100ms// 如果位置不变,则认为可能丢失if (previous_body_rect == body_rect) {repeat_count += 100;if (repeat_count == 5 * 1000) //rect检测到的数据不变,且超过一定时间,判Lost{ROS_WARN_STREAM("Target not move, may lost");repeat_count = 0;track_ok_flag = 0; // heihei,flag=0 -> reset}} //这里判断跟丢else {repeat_count = 0;}if (body_rect.width < 300 && body_rect.height < 300 && track_ok_flag == 2 &&body_rect.height > body_rect.width) //确认检测到的rect符合这些要求{watch_dog_count += 100;if (watch_dog_count <= watch_dog * 1000) // watch_dog=2{continue;}} //这里判断是否正确的给出rectwatch_dog_count = 0; tracking_frame = get_one_frame(); //再次获得newframebody_track_rect = client->getBodyRect(tracking_frame); // track//usr code begining IplImage *img2;CvRect rectInImage2;ectInImage2 = cvRect(body_track_rect.x, body_track_rect.y,ody_track_rect.width, body_track_rect.height);CvSize size2;size2.width = rectInImage2.width;size2.height = rectInImage2.height;img2 = CvCreatImage(size2, tracking_frame->depth, tracking_frame->nChannels);CvSetImageROI(tracking_frame, rectInImage2);cvCopy(img2, tracking_frame);//img2是从tracking_frame上提取的目标框区域//检测特征点detector.detect(img2, keypoint2);//计算特征点描述子SurfDescriptorExtractor extractor;Mat descriptor1, descriptor2;extractor.compute(img1, keypoint1, descriptor1);extractor.compute(img2, keypoint2, descriptor2);//使用flann匹配FlannBasedMatcher matcher;vector<DMatch>matches;matcher.match(descriptor1, descriptor2, matches);//匹配结束double max_dist = 0;double min_dist = 100;for(int i = 0; i < descriptor1.rows; i++){double dist = matches[i].distance;if(dist < min_dist)min_dist = dist;if(dist > max_dist)max_dist = dist;}//得到匹配结果中的最小距离和最大距离//处理匹配结果:判断当前匹配的对象是否为目标,仅根据最大最小匹配距离,能否进行判断?if(min_dist < 1.0)// get it~{tracking_frame = tracking_frame;body_track_rect = body_track_rect;}elseif(max_dist > 5.0)//abandon{continue;//继续下一帧匹配额}elseif((max_dist - min_dist) <  2.0){tracking_frame = tracking_frame;body_track_rect = body_track_rect;}else {continue;}//usr code endingif (body_track_rect.x <= 1 || body_track_rect.y <= 1) //识别到的rect.x / .y小于1后跟踪停止{tracker->stop();}else{{unique_lock<mutex> lock(update_track_mutex);body_rect = body_track_rect;cv_bridge::CvImagePtr cv_ptr =cv_bridge::toCvCopy(tracking_frame, "bgr8");cv::Mat cv_image = cv_ptr->image;if (track_ok_flag == 0) //跟踪标志为0时跟踪复位{tracker->reset(cv_image, body_rect, true); // watch out the  reset praram}elsetracker->reset(cv_image, body_rect); /// reset}}}
}

 

这篇关于机器人视觉行人跟随中的extract+match feature的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/777894

相关文章

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

计算机视觉工程师所需的基本技能

一、编程技能 熟练掌握编程语言 Python:在计算机视觉领域广泛应用,有丰富的库如 OpenCV、TensorFlow、PyTorch 等,方便进行算法实现和模型开发。 C++:运行效率高,适用于对性能要求严格的计算机视觉应用。 数据结构与算法 掌握常见的数据结构(如数组、链表、栈、队列、树、图等)和算法(如排序、搜索、动态规划等),能够优化代码性能,提高算法效率。 二、数学基础

基于树梅派的视频监控机器人Verybot

最近这段时间做了一个基于树梅派 ( raspberry pi ) 的视频监控机器人平台 Verybot ,现在打算把这个机器人的一些图片、视频、设计思路进行公开,并且希望跟大家一起研究相关的各种问题,下面是两张机器人的照片:         图片1:                   图片2                    这个平台的基本组成是:

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

《计算机视觉工程师养成计划》 ·数字图像处理·数字图像处理特征·概述~

1 定义         从哲学角度看:特征是从事物当中抽象出来用于区别其他类别事物的属性集合,图像特征则是从图像中抽取出来用于区别其他类别图像的属性集合。         从获取方式看:图像特征是通过对图像进行测量或借助算法计算得到的一组表达特性集合的向量。 2 认识         有些特征是视觉直观感受到的自然特征,例如亮度、边缘轮廓、纹理、色彩等。         有些特征需要通

【python计算机视觉编程——7.图像搜索】

python计算机视觉编程——7.图像搜索 7.图像搜索7.1 基于内容的图像检索(CBIR)从文本挖掘中获取灵感——矢量空间模型(BOW表示模型)7.2 视觉单词**思想****特征提取**: 创建词汇7.3 图像索引7.3.1 建立数据库7.3.2 添加图像 7.4 在数据库中搜索图像7.4.1 利用索引获取获选图像7.4.2 用一幅图像进行查询7.4.3 确定对比基准并绘制结果 7.

参会邀请 | 第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)

第二届机器视觉、图像处理与影像技术国际会议(MVIPIT 2024)将于2024年9月13日-15日在中国张家口召开。 MVIPIT 2024聚焦机器视觉、图像处理与影像技术,旨在为专家、学者和研究人员提供一个国际平台,分享研究成果,讨论问题和挑战,探索前沿技术。诚邀高校、科研院所、企业等有关方面的专家学者参加会议。 9月13日(周五):签到日 9月14日(周六):会议日 9月15日(周日

【python计算机视觉编程——8.图像内容分类】

python计算机视觉编程——8.图像内容分类 8.图像内容分类8.1 K邻近分类法(KNN)8.1.1 一个简单的二维示例8.1.2 用稠密SIFT作为图像特征8.1.3 图像分类:手势识别 8.2贝叶斯分类器用PCA降维 8.3 支持向量机8.3.2 再论手势识别 8.4 光学字符识别8.4.2 选取特征8.4.3 多类支持向量机8.4.4 提取单元格并识别字符8.4.5 图像校正

Python计算机视觉编程 第十章

目录 一、OpenCv基础知识 1.读取和写入图像 2.颜色空间 3.显示图像和结果 二、处理视频 1.输入视频 2.将视频读取到NumPy数组中 三、跟踪 1.光流 2.Lucas-Kanade算法 一、OpenCv基础知识 OpenCV 自带读取、写入图像函数以及矩阵操作和数学库。 1.读取和写入图像 import cv2# 读取图像im = c

【机器人工具箱Robotics Toolbox开发笔记(二十)】机器人工具箱SerialLink I类函数参数说明

机器人工具箱中的SerialLink表示串联机器人型机器人的具体类。该类使用D-H参数描述,每个关节一组。SerialLink I类包含的参数如表1所示。 表1 SerialLink I类参数 参  数 意    义 参  数 意    义 plot 显示机器人的图形表示 jacobn 工具坐标系中的雅可比矩阵 plot3D 显示机器人3D图形模型 Jacob_dot