华拓科技网
您的当前位置:首页加强版 第七节 图像轮廓的匹配

加强版 第七节 图像轮廓的匹配

来源:华拓科技网

-计算轮廓的矩和Hu矩,通过比较Hu矩的形状匹配来判断轮廓是否相似

1. 理论基础

• 在图像的矩(Moments)理论中,对于一个平面区域(在这种情况下是图像中的轮廓),零阶矩表示轮廓的面积。一阶矩和用于计算轮廓的质心坐标。

• 质心(也称为重心)的坐标计算公式为,坐标计算公式为。

2. 在OpenCV中的实现

• 在OpenCV的Moments结构中,m00、m10和m01分别对应理论中的、和。

• 所以,在OpenCV的这个代码环境下,只要是通过moments函数计算得到的Moments对象,计算轮廓质心坐标的方式就是固定的m10/m00(坐标)和m01/m00(坐标),这是基于数学原理和OpenCV库对矩的定义来确定的。

double cx = mm.m10 / mm.m00;

double cy = mm.m01 / mm.m00;



代码演示

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;
void found_demo(Mat& image, vector<vector<Point>>& sky);

int main(int argc, char** argv) {
    Mat sqw, swe, ser;
    Mat src1 = imread("C:/newword/image/6.png");
    Mat src2 = imread("C:/newword/image/7.png");
    if (src1.empty() || src2.empty()) {
        printf("no");
        return -1;
    }

    //imshow("1", src1);
    //imshow("2", src2);
    vector<vector<Point>>sky1;
    vector<vector<Point>>sky2;
    found_demo(src1, sky1);
    found_demo(src2, sky2);
    Moments mm2 = moments(sky2[0]);
    Mat hu2;
    HuMoments(mm2, hu2);
    for (size_t t = 0; t < sky1.size(); t++) {
        Moments mm1 = moments(sky1[t]);
        double cx = mm1.m10 / mm1.m00;
        double cy = mm1.m01 / mm1.m00;
        circle(src1, Point(cx, cy), 3, Scalar(0, 0, 255), 2, 8, 0);
        Mat hu1;
        HuMoments(mm1, hu1);
        double dist = matchShapes(hu1, hu2, CONTOURS_MATCH_I1, 0);
        if (dist < 1.0) {
            printf("matched distance value : %.2f\n", dist);
            drawContours(src1, sky1, t, Scalar(255, 0, 0), 2, 8, 0);
        }
    }
        imshow("sss", src1);
        waitKey(0);
        return 0;
    
}
void found_demo(Mat& image, vector<vector<Point>>& sky)
{
    Mat dsv, dsk, dsb;
    GaussianBlur(image, dsv, Size(3, 3), 0);
    cvtColor(dsv, dsk, COLOR_BGR2GRAY);
    threshold(dsk, dsb, 0, 255, THRESH_BINARY | THRESH_OTSU);
    vector<Vec4i>sea;
    findContours(dsb, sky, sea, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());

}

因篇幅问题不能全部显示,请点此查看更多更全内容