使用OpenCV库实现的模板轮廓匹配定位功能块

c++
#include <opencv2/opencv.hpp>

using namespace cv;

/**
 * 模板轮廓匹配定位
 * @param src 原图像
 * @param tpl 模板图像
 * @param angle_range 角度范围
 * @param scale_range 比例范围
 * @return 匹配结果,包括匹配位置和匹配度
 */
std::vector<std::pair<Point2f, double>> matchTemplateContours(const Mat& src, const Mat& tpl, const std::pair<double, double>& angle_range, const std::pair<double, double>& scale_range) {
    std::vector<std::pair<Point2f, double>> results;

    // 提取原图像和模板图像的轮廓特征
    std::vector<std::vector<Point>> src_contours, tpl_contours;
    findContours(src, src_contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    findContours(tpl, tpl_contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

    // 对模板图像的轮廓特征进行缩放和旋转,生成多个模板
    std::vector<Mat> tpl_mats;
    for (double scale = scale_range.first; scale <= scale_range.second; scale += 0.1) {
        for (double angle = angle_range.first; angle <= angle_range.second; angle += 5) {
            Mat M = getRotationMatrix2D(Point2f(tpl.cols / 2.0f, tpl.rows / 2.0f), angle, scale);
            Mat tpl_mat;
            warpAffine(tpl, tpl_mat, M, tpl.size());
            tpl_mats.push_back(tpl_mat);
        }
    }

    // 对原图像的轮廓特征进行匹配
    for (const auto& src_contour : src_contours) {
        for (const auto& tpl_mat : tpl_mats) {
            std::vector<Point> tpl_contour;
            findContours(tpl_mat, tpl_contour, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

            // 如果模板轮廓特征的点数小于3,则无法计算形状相似度,跳过该模板
            if (tpl_contour.size() < 3) {
                continue;
            }

            // 计算原图像轮廓特征和模板轮廓特征的形状相似度
            double match_score = matchShapes(src_contour, tpl_contour, CONTOURS_MATCH_I1, 0);

            // 如果形状相似度小于0.1,则认为匹配成功,保存匹配结果
            if (match_score < 0.1) {
                Moments m = moments(src_contour);
                Point2f center(m.m10 / m.m00, m.m01 / m.m00);
                results.emplace_back(center, match_score);
            }
        }
    }

    return results;
}
```

该功能块的输入参数包括原图像、模板图像、角度范围和比例范围。其中,角度范围和比例范围用std::pair类型表示,分别包括最小值和最大值。例如,角度范围为(-10, 10),比例范围为(0.8, 1.2)。

该功能块的输出结果为匹配结果,包括匹配位置和匹配度。匹配位置用Point2f类型表示,匹配度用double类型表示。匹配位置表示匹配成功的轮廓特征的中心点坐标。

该功能块的实现过程如下:

1. 提取原图像和模板图像的轮廓特征。
2. 对模板图像的轮廓特征进行缩放和旋转,生成多个模板。
3. 对原图像的轮廓特征进行匹配,计算形状相似度。
4. 如果形状相似度小于0.1,则认为匹配成功,保存匹配结果。

在实现过程中,使用了OpenCV库提供的函数findContours、getRotationMatrix2D、warpAffine和matchShapes。其中,findContours函数用于提取轮廓特征;getRotationMatrix2D和warpAffine函数用于对模板图像进行缩放和旋转;matchShapes函数用于计算形状相似度。

需要注意的是,该功能块只能匹配形状相似的目标,对于颜色、纹理等特征不敏感。因此,在实际应用中,需要根据具体情况选择合适的特征进行匹配。另外,该功能块的计算量较大,对于大尺寸图像和复杂模板可能会耗费较长时间。因此,在实际应用中需要考虑计算效率和精度之间的平衡。

以下是一个使用示例,假设我们有一张原图像和一个模板图像,我们想要在原图像中匹配出和模板图像形状相似的目标:

```c++
int main() {
    // 读取原图像和模板图像
    Mat src = imread("src.jpg", IMREAD_GRAYSCALE);
    Mat tpl = imread("tpl.jpg", IMREAD_GRAYSCALE);

    // 设置角度范围和比例范围
    std::pair<double, double> angle_range(-10, 10);
    std::pair<double, double> scale_range(0.8, 1.2);

    // 进行模板轮廓匹配定位
    std::vector<std::pair<Point2f, double>> results = matchTemplateContours(src, tpl, angle_range, scale_range);

    // 在原图像中绘制匹配结果
    Mat src_color;
    cvtColor(src, src_color, COLOR_GRAY2BGR);
    for (const auto& result : results) {
        circle(src_color, result.first, 5, Scalar(0, 0, 255), -1);
        putText(src_color, std::to_string(result.second), result.first + Point2f(10, -10), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 255), 1);
    }

    // 显示匹配结果
    imshow("Match Result", src_color);
    waitKey(0);

    return 0;
}
```

在该示例中,我们首先读取了原图像和模板图像,并设置了角度范围和比例范围。然后,调用matchTemplateContours函数进行模板轮廓匹配定位,并得到匹配结果。最后,将匹配结果绘制在原图像上,并显示出来。

需要注意的是,在实际应用中,可能需要对匹配结果进行进一步处理,例如筛选出匹配度最高的目标、去除重复的目标等。

另外,如果需要匹配多个模板,可以将模板图像存储在一个vector中,然后对每个模板分别调用matchTemplateContours函数进行匹配。在实际应用中,可能需要对不同的模板设置不同的角度范围和比例范围,以获得更好的匹配效果。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值