【opencv】目标识别——轮廓匹配

41 篇文章 1 订阅

试了试opencv里面的轮廓匹配来识别物体

//对轮廓按面积降序排列  
bool biggerSort(vector<Point> v1, vector<Point> v2)  
{  
    return contourArea(v1)>contourArea(v2);  
}  


int lunkuo()
{
    Mat img = imread("923.jpg",1);
    Mat img_template = imread("ljt.jpg",1);

    Mat gray_img,gray_img_template;

    cvtColor(img, gray_img, COLOR_BGR2GRAY);
    cvtColor(img_template, gray_img_template, COLOR_BGR2GRAY);

    Mat temp_img,temp_img_template;

    threshold(gray_img, temp_img, 60, 255, THRESH_BINARY);//对图像进行二值化

    threshold(gray_img_template, temp_img_template, 80, 255, THRESH_BINARY);

    Mat closerect=getStructuringElement(MORPH_RECT,Size(11,11)); //进行结构算子生成

    morphologyEx(temp_img, temp_img, MORPH_OPEN, closerect);

    morphologyEx(temp_img_template, temp_img_template, MORPH_OPEN, closerect);//进行形态学开运算

    imwrite("目标图处理.jpg",temp_img);
    imwrite("模版图处理.jpg",temp_img_template);


    vector<vector<Point>> contours_img,contours_template;//目标图,模版图

    findContours(temp_img, contours_img, CV_RETR_TREE, CHAIN_APPROX_NONE);//提取轮廓元素

    findContours(temp_img_template, contours_template, CV_RETR_TREE, CHAIN_APPROX_NONE);

    std::sort(contours_img.begin(), contours_img.end(), biggerSort);

    std::sort(contours_template.begin(), contours_template.end(), biggerSort);

    Rect rt;

    //for (int kk = 0; kk < contours_template.size(); kk++)
    //{
    //    rt = boundingRect(contours_template[kk]);
    //    rectangle(img_template, rt, Scalar(0,0,255),2);   
    //}
    //imwrite("模版图轮廓.jpg",img_template);

    double pro = 1;//相似度,越接近0越好
    double min_pro = 999;//对应的最优匹配值
    int min_kk = -1;//对应的最优匹配的下标

    for (int kk = 0; kk < contours_img.size(); kk++)
    {
        if (contourArea(contours_img[kk]) < 10000)//面积阈值筛选
        {
            break;
        }
        rt = boundingRect(contours_img[kk]);  
        if (rt.height <= rt.width)//垃圾桶是矩形
        {
            continue;
        }

        pro = matchShapes(contours_img[kk], contours_template[1], CV_CONTOURS_MATCH_I3, 1.0);//进行轮廓匹配

        if (pro < min_pro)
        {
            min_pro = pro;
            min_kk = kk;
        }

        cout << kk <<"=="<<pro<< endl;
    }

    rt = boundingRect(contours_img[min_kk]);
    rectangle(img, rt, Scalar(0,0,255),2);   

    cout << "相似度最高轮廓下标:"<<min_kk <<endl;
    cout << "目标形心坐标:"<<rt.x + rt.width/2<<","<<rt.y + rt.height/2<<endl;

    imwrite("目标寻找结果.jpg",img);

    return 0;
}

                                 图1                                                        图2

                              图3                                                         图4


                            图5

需要说明的是图1并不是从图2里抠出来的,是另外近距离拍摄的,直接用sift,surf效果并不是很好,但是轮廓形状却变化不大。上面的图我为了排版缩放了。图1、3大小2248*2248   图2、4、5大小3671*3627



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值