[opencv]Rect集合象限法分类聚合 函数

/**
 * 矩形拟合
 * @param mats
 * @return
 */
vector<Rect> PublicCardFrameDetection::RectContainFit(vector<Rect> rects,Mat src) {

    //获取图像中心坐标
    int src_w = src.cols;
    int src_h = src.rows;
    Point2i center = (Point2i(src_w/2),Point2i(src_h/2));
    Rect rect_center (int(src_w/3),int(src_h/3),int(src_w/3),int(src_h/3));
//    rectangle(src,rect_center.tl(),rect_center.br(),cv::Scalar(255,255,255),5,8);
    //存放结果Rect区域
    vector<Rect> results;
    vector<Rect> roi_tl; //左上
    vector<Rect> roi_tr; //右上
    vector<Rect> roi_bl; //左下
    vector<Rect> roi_br; //右下
    vector<Rect> roi_center; //中间
    int size = rects.size();
    for (auto rct : rects){
        Point2i tl_pt = rct.tl();
        Point2i tr_pt = Point2i(rct.tl().x + src_w,rct.tl().y);
        Point2i br_pt = rct.br();
        Point2i bl_pt = Point2i(rct.br().x - src_w,rct.br().y);
        Point2i center_pt = (tl_pt+br_pt)/2;
        //rect是否落在中间3*3的九宫格区域
        if ((tl_pt.x < rect_center.tl().x && tl_pt.y < rect_center.tl().y) &&
                (br_pt.x < rect_center.br().x && br_pt.y < rect_center.br().y)){
            if ((tl_pt.x + rct.width < rect_center.tl().x + rect_center.width) &&
                    (tl_pt.y + rct.height < rect_center.tl().y + rect_center.height))
                roi_center.emplace_back(rct);
        }

        //rect在中心点center左上方
        if (center_pt.y < center.y && center_pt.x > center.x){
//            if (br_pt.x < center.x && br_pt.y < center.y &&
//                    bl_pt.x < center.x && bl_pt.y < center.y)
                roi_tr.emplace_back(rct);
        }
        //rect在中心点center右上方
        if (center_pt.y < center.y && center_pt.x > center.x){
//            if (br_pt.x < center.x && br_pt.y < center.y &&
//                bl_pt.x < center.x && bl_pt.y < center.y)
                roi_tl.emplace_back(rct);
        }
        //rect在中心点center左下方
        if (center_pt.y > center.y && center_pt.x > center.x){
//            if (tl_pt.x > center.x && tl_pt.y > center.y &&
//                tr_pt.x < center.x && tr_pt.y < center.y)
                roi_br.emplace_back(rct);
        }
        //rect在中心点左下方
        if (center_pt.y > center.y && center_pt.x < center.x){
//            if (tl_pt.x > center.x && tl_pt.y > center.y &&
//                tr_pt.x < center.x && tr_pt.y < center.y)
                roi_bl.emplace_back(rct);
        }

    }//for_end

    //若rect落在正中间,说明识别单卡片,直接返回results结果
//    if (!roi_center.empty()){
//        rectangle(src,roi_center[0].tl(),roi_center[0].br(),cv::Scalar(0,0,255),5,8);
//        results.emplace_back(roi_center[0]);
//        imshow("rectangle",src);
//        waitKey(0);
//        return results;
//    } else {
        //否则,说明识别多卡片,对卡片进行排序
        //顺序为:逆时针==>左上,左下,右下,左上
        //若四个方向的集合为空,存入原图分割后的四个象限
        if (roi_tl.empty()) {
            Rect tl(0,0,src_w/2,src_h/2);
            roi_tl.emplace_back(tl);
        }
        if (roi_bl.empty()) {
            Rect bl(0,src_h/2,src_w/2,src_h/2);
            roi_bl.emplace_back(bl);
        }
        if (roi_br.empty()) {
            Rect br(src_w/2,src_h/2,src_w/2,src_h/2);
            roi_br.emplace_back(br);
        }
        if (roi_tr.empty()) {
            Rect tr(src_w/2,0,src_w/2,src_h/2);
            roi_tr.emplace_back(tr);
        }
        //Scalr(BGR)
        rectangle(src,roi_tl[0].tl(),roi_tl[0].br(),cv::Scalar(0,0,255),5,8);
        rectangle(src,roi_bl[0].tl(),roi_bl[0].br(),cv::Scalar(255,0,0),5,8);
        rectangle(src,roi_br[0].tl(),roi_br[0].br(),cv::Scalar(0,255,0),5,8);
        rectangle(src,roi_tr[0].tl(),roi_tr[0].br(),cv::Scalar(255,0,255),5,8);
        imshow("rectangle",src);
        waitKey(0);
        results.emplace_back(roi_tl[0]);
        results.emplace_back(roi_bl[0]);
        results.emplace_back(roi_br[0]);
        results.emplace_back(roi_tr[0]);
//    }
    return results;
}

 

posted @ 2019-09-20 16:43  Xu_Lin  阅读(452)  评论(0编辑  收藏  举报