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

来源:互联网 发布:软件系统关键技术指标 编辑:程序博客网 时间:2024/05/02 02:32

试了试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



原创粉丝点击