• opencv c++ 轮廓匹配


    1、几何矩和Hu矩

    1.1几何矩

    a)几何计算公式:

            

            p、q为阶数,当p+q = 1时,几何矩为一阶矩,p+q = 2,几何矩为二阶矩,依次类推。。

    因此,对于二值图像有:

            所有前景像素的x坐标之和:m_{10}

            所有前景像素的y坐标之和:m_{01}

            所有前景像素的个数:m_{00}

            注:前景像素为像素值为对应类型的满像素值的像素。

    b)几何中心矩计算公式

            

             

    1.2 Hu矩

    Hu矩计算公式:

            

             性质:Hu矩具有放缩不变性旋转不变性

            利用下述7个值来进行轮廓匹配:

            

     2、基于Hu矩的轮廓匹配

            两个轮廓的参数计算公式(这里的h_{i}即为上面的\phi值)。

            

            两个轮廓的相似度计算公式: 

            

             在常规使用时,常预设一个阈值将相似度值与阈值进行比较,设定相似度大于阈值的两个轮廓为同一轮廓。

    3、代码

    步骤:
        1、任选图像2中的一个轮廓,计算其Hu矩
        2、对图像1所有轮廓计算Hu矩,将图像2的Hu矩与图像1的所有Hu进行比较
        3、相似度阈值操作。

    1. void QuickDemo::contourGet(Mat& image, vector>& contours)
    2. {
    3. //高斯模糊
    4. Mat dst;
    5. GaussianBlur(image, dst, Size(3, 3), 0);
    6. Mat gray;
    7. cvtColor(dst, gray, COLOR_BGR2GRAY);
    8. Mat binary;
    9. threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    10. /*namedWindow("THRESH_OTSU", WINDOW_FREERATIO);
    11. imshow("THRESH_OTSU", binary);*/
    12. //查找轮廓
    13. vector hierachy;
    14. findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());
    15. cout << contours.size() << endl;
    16. }
    17. void QuickDemo::contourMatch(Mat& image1, Mat&image2)
    18. {
    19. vector> contours1;
    20. vector> contours2;
    21. contourGet(image1, contours1);
    22. contourGet(image2, contours2);
    23. /*
    24. * 步骤:
    25. * 1、任选图像2中的一个轮廓,计算其Hu矩
    26. * 2、对图像1所有轮廓计算Hu矩,将图像2的Hu矩与图像1的所有Hu进行比较
    27. * 3、相似度阈值操作。
    28. */
    29. //Hu矩计算
    30. Moments mm2 = moments(contours2[0]);//先计算几何矩
    31. Mat hu2;
    32. HuMoments(mm2, hu2);
    33. for (size_t t = 0; t < contours1.size(); ++t) {
    34. Moments mm = moments(contours1[t]);//先计算几何矩
    35. Mat hu;
    36. HuMoments(mm, hu);
    37. double sim_value = matchShapes(hu, hu2, CONTOURS_MATCH_I1, 0);
    38. //在原图绘制相似轮廓
    39. if (sim_value < 1) {
    40. cout << "第" << t << "个轮廓的相似度值为:" << (float)(1 - sim_value) << endl;
    41. drawContours(image1, contours1, t, Scalar(0, 255, 0), 2, 8);
    42. drawContours(image2, contours2, 0, Scalar(0, 255, 0), 2, 8);
    43. }
    44. //获取图像1轮廓的中心位置
    45. double cx = mm.m10 / mm.m00;
    46. double cy = mm.m01 / mm.m00;
    47. circle(image1, Point(cx, cy), 2, Scalar(255, 0, 0), 2, 8);//在中心位置画圆
    48. }
    49. namedWindow("contours1", WINDOW_FREERATIO);
    50. imshow("contours1", image1);
    51. namedWindow("image2", WINDOW_FREERATIO);
    52. imshow("image2", image2);
    53. }

     结果:

  • 相关阅读:
    盘点 Udemy 上最受欢迎的免费编程课程
    【Go】Go语言中的数组基本语法与应用实战
    压测必经之路,Jmeter分布式压测教程
    【Linux】可重入VS线程安全
    1688商品详情接口代码展示
    Python "爬虫"出发前的装备之二数据先行( Requests 模块)
    DeCLIP 论文阅读
    【Windows】局域网内共享文件夹的设置方法
    选择适合的防火墙需要考虑哪些因素?
    二叉树,关于数字计算的高频考点
  • 原文地址:https://blog.csdn.net/lucust/article/details/128160441