当前位置: 首页 > news >正文

装甲板识别

  装甲板识别是一个老项目了,很多人的入门项目也是它,接下来我来分享一下我的代码(写代码过程中也参考了很多网络上的博客和很多RM强队的代码),目前我的还只是初创,全供大家入门时观赏。

  第一步,先是进行图像读取,利用videocapture capture来读取视频,然后用循环读取每一帧

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{VideoCapture capture("C:/Users/qq117/Desktop/ood_red.mp4");Mat frame;while (true){capture.read(frame);if (frame.empty()){break;}int c = waitKey(30);if (c == 27)break;}waitKey(0);return 0;}

  第二步,对图像进行预处理,我是采用颜色作为特征,分离通道,将所要颜色部分表露出来,同时由于装甲板灯光的特性,我采用了先高斯滤波模糊,后膨胀、闭运算,使我所要的轮廓更加准确,然后再findcontours

   vector<Mat>channels;split(frame, channels);Mat red = channels.at(2);inRange(red, Scalar(156, 43, 46), Scalar(180, 255, 255), red);Canny(red, red, 0, 30, 3);GaussianBlur(red, red, Size(3, 3), 0);Mat element = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));dilate(red, red, element);morphologyEx(red, red, MORPH_CLOSE, 0);vector<vector<Point>>contours;vector<Vec4i>hierachy;findContours(red, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

  第三部分就是拟合部分,但由于我才疏学浅,暂时还不能详细解释,只好先将代码放这,之后再来改,望见谅。

   vector<LightDescriptor> lightInfos;for (int i = 0; i < contours.size(); i++) {// 求轮廓面积double area = contourArea(contours[i]);// 去除较小轮廓&fitEllipse的限制条件if (area < 5 || contours[i].size() <= 1)continue;// 用椭圆拟合区域得到外接矩形RotatedRect Light_Rec = fitEllipse(contours[i]);// 长宽比和轮廓面积比限制if (Light_Rec.size.width / Light_Rec.size.height > 5)continue;// 扩大灯柱的面积Light_Rec.size.height *= 1.1;Light_Rec.size.width *= 1.1;lightInfos.push_back(LightDescriptor(Light_Rec));}for (size_t i = 0; i < lightInfos.size(); i++) {for (size_t j = i + 1; (j < lightInfos.size()); j++) {LightDescriptor& leftLight = lightInfos[i];LightDescriptor& rightLight = lightInfos[j];//角差float angleDiff_ = abs(leftLight.angle - rightLight.angle);//长度差比率float LenDiff_ratio = abs(leftLight.length - rightLight.length) / max(leftLight.length, rightLight.length);//筛选if (angleDiff_ > 10 || LenDiff_ratio > 0.8) {continue;}//左右灯条相距距离float dis = pow(pow((leftLight.center.x - rightLight.center.x), 2) + pow((leftLight.center.y - rightLight.center.y), 2), 0.5);//左右灯条长度的平均值float meanLen = (leftLight.length + rightLight.length) / 2;//左右灯条长度差比值float lendiff = abs(leftLight.length - rightLight.length) / meanLen;//左右灯条中心点y的差值float yDiff = abs(leftLight.center.y - rightLight.center.y);//y差比率float yDiff_ratio = yDiff / meanLen;//左右灯条中心点x的差值float xDiff = abs(leftLight.center.x - rightLight.center.x);//x差比率float xDiff_ratio = xDiff / meanLen;//相距距离与灯条长度比值float ratio = dis / meanLen;//筛选if (lendiff > 0.5 ||yDiff_ratio > 1.2 ||xDiff_ratio > 2 ||xDiff_ratio < 0.6 ||ratio > 3.5 ||ratio < 0.5) {continue;}Point center = Point((leftLight.center.x + rightLight.center.x) / 2, (leftLight.center.y + rightLight.center.y) / 2);RotatedRect rect = RotatedRect(center, Size(dis, meanLen), (leftLight.angle + rightLight.angle) / 2);Point2f vertices[4];rect.points(vertices);for (int i = 0; i < 4; i++) {line(frame, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0 ,255), 2);}}}

接下来,我就放出我的完整代码(C++)

#include<opencv2/opencv.hpp>
#include<iostream>
using namespace std;
using namespace cv;
class LightDescriptor
{
public:LightDescriptor() {};LightDescriptor(const cv::RotatedRect& light){width = light.size.width;length = light.size.height;center = light.center;angle = light.angle;area = light.size.area();}const LightDescriptor& operator =(const LightDescriptor& ld){this->width = ld.width;this->length = ld.length;this->center = ld.center;this->angle = ld.angle;this->area = ld.area;return *this;}
public:float width;float length;cv::Point2f center;float angle;float area;
};int main(int argc, char** argv)
{VideoCapture capture("C:/Users/qq117/Desktop/ood_red.mp4");Mat frame;while (true){capture.read(frame);if (frame.empty()){break;}vector<Mat>channels;split(frame, channels);Mat red = channels.at(2);inRange(red, Scalar(156, 43, 46), Scalar(180, 255, 255), red);Canny(red, red, 0, 30, 3);GaussianBlur(red, red, Size(3, 3), 0);Mat element = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));dilate(red, red, element);morphologyEx(red, red, MORPH_CLOSE, 0);vector<vector<Point>>contours;vector<Vec4i>hierachy;findContours(red, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);vector<LightDescriptor> lightInfos;for (int i = 0; i < contours.size(); i++) {// 求轮廓面积double area = contourArea(contours[i]);// 去除较小轮廓&fitEllipse的限制条件if (area < 5 || contours[i].size() <= 1)continue;// 用椭圆拟合区域得到外接矩形RotatedRect Light_Rec = fitEllipse(contours[i]);// 长宽比和轮廓面积比限制if (Light_Rec.size.width / Light_Rec.size.height > 5)continue;// 扩大灯柱的面积Light_Rec.size.height *= 1.1;Light_Rec.size.width *= 1.1;lightInfos.push_back(LightDescriptor(Light_Rec));}for (size_t i = 0; i < lightInfos.size(); i++) {for (size_t j = i + 1; (j < lightInfos.size()); j++) {LightDescriptor& leftLight = lightInfos[i];LightDescriptor& rightLight = lightInfos[j];//角差float angleDiff_ = abs(leftLight.angle - rightLight.angle);//长度差比率float LenDiff_ratio = abs(leftLight.length - rightLight.length) / max(leftLight.length, rightLight.length);//筛选if (angleDiff_ > 10 || LenDiff_ratio > 0.8) {continue;}//左右灯条相距距离float dis = pow(pow((leftLight.center.x - rightLight.center.x), 2) + pow((leftLight.center.y - rightLight.center.y), 2), 0.5);//左右灯条长度的平均值float meanLen = (leftLight.length + rightLight.length) / 2;//左右灯条长度差比值float lendiff = abs(leftLight.length - rightLight.length) / meanLen;//左右灯条中心点y的差值float yDiff = abs(leftLight.center.y - rightLight.center.y);//y差比率float yDiff_ratio = yDiff / meanLen;//左右灯条中心点x的差值float xDiff = abs(leftLight.center.x - rightLight.center.x);//x差比率float xDiff_ratio = xDiff / meanLen;//相距距离与灯条长度比值float ratio = dis / meanLen;//筛选if (lendiff > 0.5 ||yDiff_ratio > 1.2 ||xDiff_ratio > 2 ||xDiff_ratio < 0.6 ||ratio > 3.5 ||ratio < 0.5) {continue;}Point center = Point((leftLight.center.x + rightLight.center.x) / 2, (leftLight.center.y + rightLight.center.y) / 2);RotatedRect rect = RotatedRect(center, Size(dis, meanLen), (leftLight.angle + rightLight.angle) / 2);Point2f vertices[4];rect.points(vertices);for (int i = 0; i < 4; i++) {line(frame, vertices[i], vertices[(i + 1) % 4], Scalar(0, 0 ,255), 2);}}}imshow("装甲板识别1", red);imshow("装甲板识别", frame);int c = waitKey(30);if (c == 27)break;}waitKey(0);return 0;}

 

 


http://www.taodudu.cc/news/show-6105784.html

相关文章:

  • 【图片新闻】低空穿越的美军MC-130J突击队II特种作战运输机
  • 智能物流仓储机器人|海格里斯HEGERLS货物夹抱式防倾倒装置四向穿梭车
  • 机器人学回炉重造(1-2):各种典型机械臂的正运动学建模(标准D-H法)
  • 装甲逆袭-NPC对话处理
  • 装甲逆袭-地图加载
  • 机械战警原型开发 - 仓田机器人
  • 装甲逆袭-获取坦克界面
  • 对于装甲板的规范
  • 装甲逆袭-NPC移动处理
  • 装甲逆袭-玩家碰撞处理
  • 他一个人干掉了5个装甲军
  • 装甲逆袭-加载NPC
  • robomaster(1)装甲板识别
  • 装甲逆袭-资源加载
  • 视觉组考核——装甲板识别
  • 装甲逆袭-玩家移动处理
  • 开机后我的计算机打不开,电脑开机后图标打不开怎么办
  • 电脑开不了机的原因和解决办法
  • Proe转Solidworks
  • proe5.0插件在windows7 64系统预览模型
  • proe常用c语言语句,proe关系式(大全).doc
  • proe5.0启动失败,光标转了几圈后没有任何反应
  • proe常用c语言语句,Proe如何使用if条件语句?
  • proe常用c语言语句,带你轻松搞懂Proe条件语句
  • 【MFC】基于OpenCV的魔镜
  • 魔镜魔镜告诉我谁是世界上最美的人 语音唤醒,百度语音识别。从装系统开始
  • 制作魔镜页
  • 魔镜连接本地mysql_打造属于你的树莓派“魔镜”—硬件篇
  • 旧电脑利用:windows网页版魔镜【不需树莓派】
  • 笔记1 第11课 贪心初步 ——柠檬水找零,分发饼干,跳跃游戏,完成所有任务所需最小能量——极客时间算法