RM装甲识别程序再分析(一)

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

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值