RM装甲识别程序再分析(一)
最近半个月在RM视觉组实习,有幸接触到一些机器人比赛相关的算法,真不错嘿嘿!今晚仔细研究了一位大佬博主好久之前发的一篇博文(地址见下),感觉自己对博文中装甲识别的代码有一些见解(由于作者学习的是opencv4,鉴于年代隔阂,仅对opencv3.0.0部分代码进行注解),所以想分享一下。由于作者水平有限,如有错漏,欢迎各位大佬批评斧正:
RM装甲识别程序分析(一)_healingwounds的博客-优快云博客)
首先,将大佬博主的源码贴在下面:
//根据以上代码将其在opencv3.0.0中编写
#include "stdafx.h"
#include "opencv2/core.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/imgproc.hpp"
#include "iostream"
#include "omp.h"
using namespace cv;
using namespace std;
#define T_ANGLE_THRE 10
#define T_SIZE_THRE 5
void brightAdjust(Mat src, Mat dst, double dContrast, double dBright); //亮度调节函数
void getDiffImage(Mat src1, Mat src2, Mat dst, int nThre); //二值化
vector<RotatedRect> armorDetect(vector<RotatedRect> vEllipse); //检测装甲
void drawBox(RotatedRect box, Mat img); //标记装甲
int main()
{
VideoCapture cap0("RawImage\\RedCar.avi");
Mat frame0;
Size imgSize;
RotatedRect s; //定义旋转矩形
vector<RotatedRect> vEllipse; //定以旋转矩形的向量,用于存储发现的目标区域
vector<RotatedRect> vRlt;
vector<RotatedRect> vArmor;
bool bFlag = false;
vector<vector<Point> > contour;
cap0 >> frame0;
imgSize = frame0.size();
Mat rawImg = Mat(imgSize, CV_8UC3);
Mat grayImage = Mat(imgSize, CV_8UC1);
Mat rImage = Mat(imgSize, CV_8UC1);
Mat gImage = Mat(imgSize, CV_8UC1);
Mat bImage = Mat(imgSize, CV_8UC1);
Mat binary = Mat(imgSize, CV_8UC1);
Mat rlt = Mat(imgSize, CV_8UC1);
namedWindow("Raw");
while (1)
{
if (cap0.read(frame0))
{
brightAdjust(frame0, rawImg, 1, -120); //每个像素每个通道的值都减去120
Mat bgr[3];
split(rawImg, bgr); //将三个通道的像素值分离
bImage = bgr[0];
gImage = bgr[1];
rImage = bgr[2];
//如果像素R值-G值大于25,则返回的二值图像的值为255,否则为0
getDiffImage(rImage, gImage, binary, 25);
dilate(binary, grayImage, Mat(), Point(-1,-1), 3); //图像膨胀
erode(grayImage, rlt, Mat(), Point(-1,-1), 1); //图像腐蚀,先膨胀在腐蚀属于闭运算
findContours(rlt, contour, RETR_CCOMP , CHAIN_APPROX_SIMPLE); //在二值图像中寻找轮廓
for (int i=0; i<contour.size(); i++)
{
if (contour[i].size()> 10) //判断当前轮廓是否大于10个像素点
{
bFlag = true; //如果大于10个,则检测到目标区域
//拟合目标区域成为椭圆,返回一个旋转矩形(中心、角度、尺寸)
s = fitEllipse(contour[i]);
for (int nI = 0; nI < 5; nI++)
{
for (int nJ = 0; nJ < 5; nJ++) //遍历以旋转矩形中心点为中心的5*5的像素块
{
if (s.center.y - 2 + nJ > 0 && s.center.y - 2 + nJ < 480 && s.center.x - 2 + nI > 0 && s.center.x - 2 + nI < 640) //判断该像素是否在有效的位置
{
Vec3b v3b = frame0.at<Vec3b>((int)(s.center.y - 2 + nJ), (int)(s.center.x - 2 + nI)); //获取遍历点点像素值
//判断中心点是否接近白色
if (v3b[0] < 200 || v3b[1] < 200 || v3b[2] < 200)
bFlag = false; //如果中心不是白色,则不是目标区域
}
}
}
if (bFlag)
{
vEllipse.push_back(s); //将发现的目标保存
}
}
}
//调用子程序,在输入的LED所在旋转矩形的vector中找出装甲的位置,并包装成旋转矩形,存入vector并返回
vRlt = armorD

本文是对RM装甲识别程序的深入分析,重点探讨了fitEllipse()函数的拟合效果以及armorDetect()函数的作用和调用前后变化。通过示例图片解释了dAngle的概念,并对关键if语句进行了思考。
最低0.47元/天 解锁文章
2213

被折叠的 条评论
为什么被折叠?



