Robomaster大能量机关轮廓流水灯识别+框选

由于能量机关是蓝色或者红色的
可以使用hsv 把蓝色或者红色分割出来
或用红蓝通道想减

分割方法
inrange()函数实现阈值化

    cvtColor(image,image,COLOR_BGR2HSV);
    inRange(image, Scalar(70, 150, 50), Scalar(120, 255, 255), image);        //阈值要自己调
    接着进行一组膨胀
    dilate(image,image,Mat());

(1)这是预处理的效果图
在这里插入图片描述***(2)下面进行找轮廓并画出轮廓***

Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// 用Canny算子检测边缘
    Canny(image1, canny_output, 100, 100*2, 3 );
    /// 寻找轮廓
    findContours( canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );

    /// 绘出轮廓
    Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
    {
    
    
        Scalar color = Scalar( 0, 0,255 );
        drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
    }

下面是轮廓效果
在这里插入图片描述
(3)寻找流水灯,也就是要击打的一块区域;面积和轮廓比要自己调

 		 ///  面积大小排序轮廓 ///
    std::sort(contours.begin(),contours.end(),ContoursSortFun);
 		cv::RotatedRect min_center_rect;
		vector<Point> points;
        if(contourArea(contours[i])==0)
            continue;
 
        double area_of_contour=contourArea(contours[i]);
        /比较面积
        if ( (area_of_contour >=1200)&& (area_of_contour <=1400&& center_rm_founded_flag == 0 ))
        {
    
    
            min_center_rect = cv::minAreaRect( contours[i] );
            double center_rect_h_w_div = min_center_rect.size.height / min_center_rect.size.width;
            center_rect_h_w_div=center_rect_h_w_div>1?center_rect_h_w_div:1/center_rect_h_w_div;
   

            //划线找出流水灯
            points = contours[i];
            拟合出最小外接矩形
            RotatedRect rrect = fitEllipse(points);
            cv::Point2f* vertices = new cv::Point2f[4];
            ///矩阵的四个顶点赋值给vertices
            rrect.points(vertices);
            /找长宽比
            float aim = center_rect_h_w_div;
            if(aim > 1.95&& aim < 2.5){
    
    
                cout<<"第"<<i<<"个面积为"<<contourArea(contours[i])<<endl;
                cout<<"第"<<i<<"个长宽比"<<center_rect_h_w_div<<endl;
                for (int j = 0; j < 4; j++)
                {
    
    cout<<"Di"<<j<<"个坐标点"<<vertices[i]<<endl;
                    cv::line(binary, vertices[j], vertices[(j + 1) % 4], cv::Scalar(0, 255, 0),4);
                }
                imshow("划线",binary);

猜你喜欢

转载自blog.csdn.net/qq_43570528/article/details/103001661