多角度多尺度模板匹配(进阶篇)

        上一篇中我们实现了带有旋转和缩放的模板匹配(halcon中的find_scaled_shape_model),并对带有不同尺度图案的图像进行了测试,这一篇我们将推广至更一般的情况,采用没有缩放,只有原始比例并带有一些遮挡的图片进行测试,来验证算法的稳健性。测试图片来自halcon形状匹配例程中使用的图像,程序使用的模板以及提取的特征点如下:

        设置模板创建的参数:

        设置模板匹配的参数:

        上面是在halcon中进行模板创建及匹配设置的参数,在我的程序中除了最低分数其他与halcon保持一致,具体参数如下:金字塔级别为5,角度范围【-180,180】,尺度范围【0.5,1.5】,角度步长和尺度步长自动计算,使用极性,最小分数0.4(halcon为0.5),最大匹配个数为0,贪婪度0.75,最大重叠0.5,亚像素我还没有加进去。下面的图显示了和halcon的对比结果ÿ

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
OpenCV提供了多种图像匹配算法,其中包括多尺度模板匹配(Multi-Scale Template Matching)算法。下面介绍如何使用Java实现多角度多尺度模板匹配。 1. 导入OpenCV库 首先需要导入OpenCV库,可以在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.openpnp</groupId> <artifactId>opencv</artifactId> <version>3.4.1-1</version> </dependency> ``` 2. 加载图像 使用OpenCV的Java API,可以通过以下代码加载待匹配的图像和模板图像: ```java // 加载待匹配的图像和模板图像 Mat img = Imgcodecs.imread("image.jpg"); Mat template = Imgcodecs.imread("template.jpg"); ``` 其中,`Imgcodecs`是OpenCV提供的用于读写图像的类。 3. 多角度匹配 为了实现多角度匹配,可以对模板图像进行旋转,然后在旋转后的图像上进行匹配。以下是旋转图像的代码: ```java // 旋转图像 Mat rotate(Mat src, double angle) { Point center = new Point(src.cols() / 2, src.rows() / 2); Mat rotMat = Imgproc.getRotationMatrix2D(center, angle, 1.0); Mat dst = new Mat(); Imgproc.warpAffine(src, dst, rotMat, src.size()); return dst; } ``` 其中,`src`是待旋转的图像,`angle`是旋转角。 接下来,在旋转后的图像上进行匹配,可以得到每个匹配结果的位置和得分。以下是代码: ```java double minScore = 0.8; // 最小匹配得分 double maxScore = 0.0; // 最大匹配得分 Point maxLoc = null; // 最大匹配得分的位置 double angleStep = 10.0; // 旋转角步长 double angleStart = 0.0; // 起始旋转角 double angleEnd = 360.0; // 终止旋转角 double angle = angleStart; // 当前旋转角 while (angle <= angleEnd) { // 旋转模板图像 Mat rotatedTemplate = rotate(template, angle); // 多尺度匹配 Mat result = new Mat(); Imgproc.matchTemplate(img, rotatedTemplate, result, Imgproc.TM_CCOEFF_NORMED); Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1); // 找到最大匹配得分和位置 Core.MinMaxLocResult mmr = Core.minMaxLoc(result); double score = mmr.maxVal; if (score >= minScore && score > maxScore) { maxScore = score; maxLoc = mmr.maxLoc; } // 更新旋转角 angle += angleStep; } ``` 在上述代码中,`minScore`是最小匹配得分,如果匹配得分低于这个值,则认为没有匹配成功。`angleStep`是旋转角步长,`angleStart`和`angleEnd`分别是旋转角的起始值和终止值。在每次旋转后,使用`Imgproc.matchTemplate`函进行多尺度匹配,找到最大匹配得分和位置,然后更新旋转角。最终得到的`maxLoc`就是最大匹配得分的位置。 4. 显示匹配结果 最后,可以在原图像上标记匹配结果。以下是代码: ```java // 在原图像上标记匹配结果 if (maxLoc != null) { Point topLeft = new Point(maxLoc.x, maxLoc.y); Point bottomRight = new Point(topLeft.x + template.cols(), topLeft.y + template.rows()); Imgproc.rectangle(img, topLeft, bottomRight, new Scalar(0, 0, 255), 2); } // 显示匹配结果 HighGui.imshow("Result", img); HighGui.waitKey(); ``` 在上述代码中,如果找到了匹配结果,则使用`Imgproc.rectangle`函在原图像上画出匹配框。最后,使用`HighGui.imshow`函显示匹配结果。 完整代码如下: ```java import org.opencv.core.Core; import org.opencv.core.Core.MinMaxLocResult; import org.opencv.core.Mat; import org.opencv.core.Point; import org.opencv.core.Scalar; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.highgui.HighGui; public class MultiScaleTemplateMatching { // 旋转图像 static Mat rotate(Mat src, double angle) { Point center = new Point(src.cols() / 2, src.rows() / 2); Mat rotMat = Imgproc.getRotationMatrix2D(center, angle, 1.0); Mat dst = new Mat(); Imgproc.warpAffine(src, dst, rotMat, src.size()); return dst; } public static void main(String[] args) { // 加载待匹配的图像和模板图像 Mat img = Imgcodecs.imread("image.jpg"); Mat template = Imgcodecs.imread("template.jpg"); double minScore = 0.8; // 最小匹配得分 double maxScore = 0.0; // 最大匹配得分 Point maxLoc = null; // 最大匹配得分的位置 double angleStep = 10.0; // 旋转角步长 double angleStart = 0.0; // 起始旋转角 double angleEnd = 360.0; // 终止旋转角 double angle = angleStart; // 当前旋转角 while (angle <= angleEnd) { // 旋转模板图像 Mat rotatedTemplate = rotate(template, angle); // 多尺度匹配 Mat result = new Mat(); Imgproc.matchTemplate(img, rotatedTemplate, result, Imgproc.TM_CCOEFF_NORMED); Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1); // 找到最大匹配得分和位置 MinMaxLocResult mmr = Core.minMaxLoc(result); double score = mmr.maxVal; if (score >= minScore && score > maxScore) { maxScore = score; maxLoc = mmr.maxLoc; } // 更新旋转角 angle += angleStep; } // 在原图像上标记匹配结果 if (maxLoc != null) { Point topLeft = new Point(maxLoc.x, maxLoc.y); Point bottomRight = new Point(topLeft.x + template.cols(), topLeft.y + template.rows()); Imgproc.rectangle(img, topLeft, bottomRight, new Scalar(0, 0, 255), 2); } // 显示匹配结果 HighGui.imshow("Result", img); HighGui.waitKey(); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值