zoukankan      html  css  js  c++  java
  • 29、【opencv入门】轮廓查找与绘制(7)——位置关系及轮廓匹配

    一、计算点与轮廓的距离及位置关系---pointPolygonTest()

    CV_EXPORTS_W double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist);

      contour: 所需检测的轮廓对象

      pt: Point2f 类型的pt, 待判定位置的点

      measureDist: 是否计算距离的标志, 当其为true时, 计算点到轮廓的最短距离, 当其为false时, 只判定轮廓与点的位置关系, 具体关系如下:    

        ①返回值为-1, 表示点在轮廓外部    

        ②返回值为0, 表示点在轮廓上    

        ③返回值为1, 表示点在轮廓内部

    示例:

    1 double a0 = pointPolygonTest(contours[0], Point(3,3), true);
    2 double b0 = pointPolygonTest(contours[0], Point(3,3), false);

    注意:如果你不需要知道具体的距离,建议你将第三个参数设为false,这样速度会提高2到3倍。

     1 //计算点到轮廓的距离
     2 #include "opencv2/opencv.hpp"
     3 #include <iostream>
     4 
     5 using namespace std;
     6 using namespace cv;
     7 
     8 int main()
     9 {
    10     //计算点到轮廓的距离与位置关系
    11     Mat srcImg = imread("1.png");
    12     imshow("src", srcImg);
    13 
    14     Mat dstImg = srcImg.clone();
    15     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    16     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
    17     imshow("threshold", srcImg);
    18 
    19     //查找轮廓
    20     vector<vector<Point>> contours;
    21     vector<Vec4i> hierarcy;
    22     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);//TREE:提取所有轮廓    NONE:画出轮廓所有点
    23     cout << "contours.size()=" << contours.size() << endl;
    24     for (int i = 0; i < contours.size(); i++)//遍历每个轮廓
    25     {
    26         for (int j = 0; j < contours[i].size(); j++)//遍历轮廓每个点
    27         {
    28             cout << "(" << contours[i][j].x << "," << contours[i][j].y << ")" << endl;
    29         }
    30     }
    31 
    32     double a0 = pointPolygonTest(contours[0], Point(3, 3), true);//点到轮廓的最短距离
    33     double b0 = pointPolygonTest(contours[0], Point(212, 184), false);//点与轮廓的位置关系:-1表示外部;0表示在轮廓上;1表示轮廓内部
    34     cout << "a0=" << a0 << endl;
    35     cout << "b0=" << b0 << endl;
    36     waitKey(0);
    37     return 0;
    38 }

    二、轮廓的矩的计算---moments()

    1 CV_EXPORTS_W Moments moments(InputArray array, bool binaryImage=false);

      array: 输入参数, 可以是光栅图像或二维数组

      binaryImage:默认值false, 非零像素取其本身值, 若为true, 则非零像素取1 返回值: Moments类的对象, 返回对应的轮廓的空间矩/中心矩和归一化中心矩(最高3阶), 如下:

    更多关于轮廓的矩的计算,参见:

    1 http://blog.csdn.net/cp32212116/article/details/38374015 
    2 http://blog.csdn.net/huixingshao/article/details/42060231
     1 //轮廓矩的计算
     2 #include "opencv2/opencv.hpp"
     3 #include <iostream>
     4 
     5 using namespace std;
     6 using namespace cv;
     7 
     8 int main()
     9 {
    10     Mat srcImg = imread("1.png");
    11     imshow("src", srcImg);
    12 
    13     Mat dstImg = srcImg.clone();
    14     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    15     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
    16     //imshow("threshold", srcImg);
    17 
    18     vector<vector<Point>> contours;
    19     vector<Vec4i> hierarcy;
    20     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
    21     cout << "contours.size()=" << contours.size() << endl;
    22     Moments moment0 = moments(contours[0], false);
    23     cout << moment0.m00<< endl;
    24     waitKey(0);
    25     return 0;
    26 }

    三、形状匹配---matchShapes()

    1 CV_EXPORTS_W double matchShapes(InputArray contour1, InputAaary contour2, int method, double parameter);

      contour1: 所需比较的轮廓1

      contour2: 所需比较的轮廓2

      method: 轮廓比较的方法

      parameter: 比较方法的特殊参数(目前不支持)

    注意:  matchShapes()函数比较轮廓相似度是基于Hu矩来计算的, 结果越小相似度越高。

    Hu矩是归一化中心矩的线性组合, 是为了获取图像某个特征的矩函数(对应变化如平移、缩放、旋转、镜像)  

     1 //形状匹配
     2 #include "opencv2/opencv.hpp"
     3 #include <iostream>
     4 #include <iomanip>
     5 
     6 using namespace std;
     7 using namespace cv;
     8 
     9 int main()
    10 {
    11     Mat srcImg = imread("1.jpg");  //模板图像
    12     imshow("src", srcImg);
    13     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
    14     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
    15     vector<vector<Point>> contours;
    16     vector<Vec4i> hierarcy;
    17     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    18 
    19     Mat srcImg2 = imread("2.jpg");  //待测试图片
    20     imshow("src2", srcImg2);
    21     Mat dstImg = srcImg2.clone();
    22     cvtColor(srcImg2, srcImg2, CV_BGR2GRAY);
    23     threshold(srcImg2, srcImg2, 100, 255, CV_THRESH_BINARY);
    24     vector<vector<Point>> contours2;
    25     vector<Vec4i> hierarcy2;
    26     findContours(srcImg2, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
    27     while (1)
    28     {
    29         for (int i = 0; i<contours2.size(); i++)
    30         {
    31             double matchRate = matchShapes(contours[0], contours2[i], CV_CONTOURS_MATCH_I1, 0.0);//形状匹配:值越小越相似
    32             cout << "index=" << i << "---" << setiosflags(ios::fixed) << matchRate << endl;//setiosflags(ios::fixed)是用定点方式表示实数,保留相同位数,相同格式输出
    33             if (matchRate <= 0.1)
    34                 drawContours(dstImg, contours2, i, Scalar(0, 255, 0), 2, 8);
    35             imshow("dst", dstImg);
    36             /*char key = waitKey();
    37             if (key == 27)
    38                 break;*/
    39         }
    40         break;
    41     }
    42     waitKey(0);
    43     return 0;
    44 }
  • 相关阅读:
    mybatis3这个问题我晕为什么对于配置信息的节点放的位置也会报错
    QTP的那些事增删改查中的增加操作的测试用例及其脚本设计思路
    QTP的那些事importsheet注意的一些事情
    mybatis3中的结果集
    QTP的那些事终极项目脚本设计思路及其测试查询功能的一些实际项目体会
    mybatis+spring整合的几个好的例子
    QTP的那些事操作excel数据需要注意的事
    hibernate4的使用第一步环境搭建
    项目中关于IFRAME引发的问题【出现率很高】
    oracle直接sql语句后台递归查询返回一个树
  • 原文地址:https://www.cnblogs.com/Long-w/p/9668862.html
Copyright © 2011-2022 走看看