opencv学习之路(28)、轮廓查找与绘制(七)——位置关系及轮廓匹配

本文详细介绍使用OpenCV进行轮廓查找、绘制、计算点与轮廓距离、轮廓矩以及形状匹配的方法。通过实例演示如何处理图像,提取轮廓并分析其属性,实现形状的精确匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

opencv轮廓查找与绘制——位置关系及轮廓匹配

一、点与轮廓的距离及位置关系

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

a0之所以是负数,是因为点在轮廓外部

二、轮廓的矩

轮廓矩的介绍:

http://blog.youkuaiyun.com/cp32212116/article/details/38374015
http://blog.youkuaiyun.com/huixingshao/article/details/42060231

复制代码
 1 #include "opencv2/opencv.hpp"
 2 #include <iostream>
 3 using namespace std;
 4 using namespace cv;
 5 
 6 void main()
 7 {
 8     Mat srcImg = imread("E://00.png");
 9     imshow("src", srcImg);
10 
11     Mat dstImg = srcImg.clone();
12     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
13     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
14     //imshow("threshold", srcImg);
15 
16     vector<vector<Point>> contours;
17     vector<Vec4i> hierarcy;
18     findContours(srcImg, contours, hierarcy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE);
19     cout << "contours.size()=" << contours.size() << endl;
20     Moments moment0 = moments(contours[0], false);
21     cout << moment0.m00<< endl;
22     waitKey(0);
23 }
复制代码

三、形状匹配--matchShapes()

注意与模板匹配matchTemplate()相区分。形状匹配对于旋转、尺度、位移都能适应。

复制代码
 1 #include "opencv2/opencv.hpp"
 2 #include <iostream>
 3 #include <iomanip>
 4 using namespace std;
 5 using namespace cv;
 6 
 7 void main()
 8 {
 9     Mat srcImg = imread("1.jpg");  //模板图像
10     imshow("src", srcImg);
11     cvtColor(srcImg, srcImg, CV_BGR2GRAY);
12     threshold(srcImg, srcImg, 100, 255, CV_THRESH_BINARY);
13     vector<vector<Point>> contours;
14     vector<Vec4i> hierarcy;
15     findContours(srcImg, contours, hierarcy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
16 
17     Mat srcImg2 = imread("2.jpg");  //待测试图片
18     imshow("src2", srcImg2);
19     Mat dstImg = srcImg2.clone();
20     cvtColor(srcImg2, srcImg2, CV_BGR2GRAY);
21     threshold(srcImg2, srcImg2, 100, 255, CV_THRESH_BINARY);
22     vector<vector<Point>> contours2;
23     vector<Vec4i> hierarcy2;
24     findContours(srcImg2, contours2, hierarcy2, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
25     while (1)
26     {
27         for (int i = 0; i<contours2.size(); i++)
28         {
29             double matchRate = matchShapes(contours[0], contours2[i], CV_CONTOURS_MATCH_I1, 0.0);//形状匹配:值越小越相似
30             cout << "index=" << i << "---" << setiosflags(ios::fixed) << matchRate << endl;//setiosflags(ios::fixed)是用定点方式表示实数,保留相同位数,相同格式输出
31             if (matchRate <= 0.1)
32                 drawContours(dstImg, contours2, i, Scalar(0, 255, 0), 2, 8);
33             imshow("dst", dstImg);
34             /*char key = waitKey();
35             if (key == 27)
36                 break;*/
37         }
38         break;
39     }
40     waitKey(0);
41 }
复制代码

 

分类: opencv
0
0
« 上一篇: [c/c++] programming之路(20)、字符串(一)
» 下一篇: [C++ Primer Plus] 第4章、复合类型(一)程序清单——指针new和delete
	</div>
	<div class="postDesc">posted @ <span id="post-date">2017-09-04 20:34</span> <a href="https://www.cnblogs.com/little-monkey/">进击的小猴子</a> 阅读(<span id="post_view_count">3462</span>) 评论(<span id="post_comment_count">0</span>)  <a href="https://i.cnblogs.com/EditPosts.aspx?postid=7475481" rel="nofollow">编辑</a> <a href="#" onclick="AddToWz(7475481);return false;">收藏</a></div>
</div>
<script type="text/javascript">var allowComments=true,cb_blogId=367074,cb_entryId=7475481,cb_blogApp=currentBlogApp,cb_blogUserGuid='699572fa-bd2f-496b-1dc9-08d49c352df3',cb_entryCreatedDate='2017/9/4 20:34:00';loadViewCount(cb_entryId);var cb_postType=1;var isMarkdown=false;</script>
### OpenCV轮廓模板匹配的使用方法 #### 函数介绍 `cv2.matchTemplate()` 是 OpenCV 库中用于执行模板匹配操作的核心函数。该函数可以在较大的源图像 `image` 中搜索给定的小模板图像 `template` 最相似的部分[^2]。 #### 参数说明 - **image**: 源图像,即要从中查找模板的大图像。 - **template**: 小尺寸的模板图像,在大图像中寻找其相像的地方。 - **method**: 匹配算法的选择标志位,决定了如何评估两个图像之间的相似程度。常见的选项有: - 平方差匹配 (`cv2.TM_SQDIFF`) - 归一化的平方差匹配 (`cv2.TM_SQDIFF_NORMED`) - 相关系匹配 (`cv2.TM_CCORR`) - 归一化相关系匹配 (`cv2.TM_CCOEFF`) 和其他变体. - **mask** (可选): 掩模图像,其大小应等于模板图像。此参数允许指定哪些部分应当参比较过程;当掩膜上的某一点为零时,则对应的模板点不会参到计算之中[^4]. #### 实现流程 为了提高准确性,通常会先通过 Canny 边缘检测器提取目标对象的边界信息,再利用这些特征来进行更精确的位置定位。具体来说: 1. 对输入图片应用高斯模糊减少噪声干扰; 2. 使用 Canny 运算符获取物体轮廓; 3. 执行形态学变换(如膨胀/腐蚀)优化边缘质量; 4. 调用 `cv2.findContours()` 获取所有闭合曲线; 5. 计算每条路径的最小外接矩形或其他几何属性作为筛选条件; 6. 结合上述步骤的结果调用 `cv2.matchTemplate()` 完成最终识别任务。 下面是一个简单的 Python 示例代码展示如何结合轮廓检测和模板匹配技术来完成特定形状的目标检索工作: ```python import numpy as np import cv2 def preprocess_image(img): gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (7, 7), 0) edged = cv2.Canny(blurred, 50, 150) dilated = cv2.dilate(edged, None, iterations=1) eroded = cv2.erode(dilated, None, iterations=1) return eroded source_img = cv2.imread('path_to_large_image') template_img = cv2.imread('path_to_small_template') processed_source = preprocess_image(source_img) processed_template = preprocess_image(template_img) result = cv2.matchTemplate(processed_source, processed_template, cv2.TM_CCOEFF_NORMED) min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result) top_left = max_loc bottom_right = (top_left[0] + w, top_left[1] + h) cv2.rectangle(source_img,top_left,bottom_right,(0,255,0),2) cv2.imshow("Detected", source_img) cv2.waitKey(0) ``` 这段程序首先定义了一个预处理函数用来增强原始图像的质量以便后续分析更加可靠。接着读取两张图片——一个是待查询的大图,另一个是要找寻的小模板。之后分别对两者做相同的前处理操作以确保一致性。最后一步则是实际调用了 `matchTemplate` 方法,并根据返回的最佳匹配位置绘制出矩形框标注出来。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值