@@ -344,6 +344,7 @@ cv2.waitKey(1000)
344344# 关闭所有窗口
345345cv2.destroyAllWindows()
346346```
347+
347348### 绘制箭头
348349
349350函数签名:` cv2.arrowedLine(img, start_point, end_point, color, thickness, tipLength) -> img `
@@ -411,6 +412,38 @@ img.show()
411412
412413## 图像运算
413414
415+ ### 图像截取
416+
417+ 图像的本质是数组,所以图像的截取就是数组的截取。
418+
419+ ``` python showLineNumbers
420+ img = cv2.imread(" demo.jpg" )
421+
422+ # 1. 知道左上角 + 宽高(最常用)
423+ x, y, w, h = 100 , 200 , 300 , 400
424+ cropped = img[y:y+ h, x:x+ w]
425+
426+ # 2. 知道左上角和右下角坐标
427+ x1, y1 = 100 , 200
428+ x2, y2 = 400 , 600
429+ cropped = img[y1:y2, x1:x2]
430+
431+ # 3. 知道中心点 + 宽高(比如 YOLO 检测框)
432+ center_x, center_y = 320 , 240
433+ w, h = 200 , 300
434+ x = int (center_x - w/ 2 )
435+ y = int (center_y - h/ 2 )
436+ cropped = img[y:y+ h, x:x+ w]
437+
438+ # 4. 防止越界(生产必加,防止 crash)
439+ h_img, w_img = img.shape[:2 ]
440+ x = max (0 , x)
441+ y = max (0 , y)
442+ w = min (w, w_img - x)
443+ h = min (h, h_img - y)
444+ cropped = img[y:y+ h, x:x+ w]
445+ ```
446+
414447加减法的前提是两张图片的尺寸相同。
415448
416449### 图像加法、图像减法
@@ -1316,6 +1349,109 @@ cv2.destroyAllWindows()
13161349
13171350想获得认证可以参与[ OpenCV Bootcamp] ( https://courses.opencv.org/courses/course-v1:OpenCV+Bootcamp+CV0/course/ )
13181351
1352+ ### 模板匹配
1353+
1354+ 模板匹配(Template Matching)是一种在图像中寻找指定模板位置的技术。它通过在目标图像中滑动模板图像,计算相似度来找到最佳匹配位置。
1355+
1356+ ** 应用场景** :
1357+ - 目标检测:在图像或视频中查找特定对象
1358+ - 图像识别:识别图像中的图标、按钮等
1359+ - 自动化测试:UI自动化中的元素定位
1360+ - 文档处理:在扫描文档中查找特定区域
1361+
1362+ ** 函数签名** :` cv2.matchTemplate(image, templ, method[, result[, mask]]) -> result `
1363+
1364+ ** 参数说明** :
1365+ - ` image ` :目标图像(待搜索的图像),必须是单通道或三通道图像
1366+ - ` templ ` :模板图像(要查找的小图像),尺寸必须小于等于目标图像
1367+ - ` method ` :匹配方法,使用归一化的方法效果通常更好,常用的有:
1368+ - ` cv2.TM_CCOEFF_NORMED ` :归一化相关系数匹配,返回0-1之间的值,值越大越匹配
1369+ - ` cv2.TM_CCORR_NORMED ` :归一化相关匹配
1370+ - ` cv2.TM_SQDIFF_NORMED ` :归一化平方差匹配,值越小越匹配
1371+ - ` result ` :可选,输出结果图像
1372+ - ` mask ` :可选,掩码图像
1373+
1374+ ** 返回值** :
1375+ - ` result ` :匹配结果图像,尺寸为 ` (W-w+1, H-h+1) ` ,其中 ` (W, H) ` 是目标图像尺寸,` (w, h) ` 是模板图像尺寸
1376+
1377+ ** 获取最佳匹配位置** :使用 ` cv2.minMaxLoc() ` 函数获取匹配结果中的最值及其位置
1378+
1379+ ** 函数签名** :` cv2.minMaxLoc(src[, mask]) -> minVal, maxVal, minLoc, maxLoc `
1380+
1381+ ** 返回值** :
1382+ - ` minVal ` :最小值
1383+ - ` maxVal ` :最大值
1384+ - ` minLoc ` :最小值位置 ` (x, y) `
1385+ - ` maxLoc ` :最大值位置 ` (x, y) `
1386+
1387+ ** 注意** :
1388+ - 对于 ` TM_SQDIFF ` 和 ` TM_SQDIFF_NORMED ` 方法,最小值位置是最佳匹配
1389+ - 对于其他方法,最大值位置是最佳匹配
1390+
1391+ ``` python showLineNumbers
1392+ import cv2
1393+ import numpy as np
1394+ import matplotlib.pyplot as plt
1395+
1396+ # 读取目标图像和模板图像
1397+ image = cv2.imread(' target.jpg' ) # 目标图像(大图)
1398+ template = cv2.imread(' template.jpg' ) # 模板图像(小图)
1399+
1400+ # 将图像转换为灰度图(模板匹配通常在灰度图上进行)
1401+ image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY )
1402+ template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY )
1403+
1404+ # 执行模板匹配
1405+ # 使用归一化相关系数匹配方法
1406+ result = cv2.matchTemplate(image_gray, template_gray, cv2.TM_CCOEFF_NORMED )
1407+
1408+ # 获取最佳匹配位置
1409+ min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
1410+
1411+ # 由于使用 TM_CCOEFF_NORMED,最大值位置是最佳匹配
1412+ top_left = max_loc
1413+ h, w = template_gray.shape
1414+ bottom_right = (top_left[0 ] + w, top_left[1 ] + h)
1415+
1416+ # 在原图上绘制匹配区域
1417+ image_copy = image.copy()
1418+ cv2.rectangle(image_copy, top_left, bottom_right, (0 , 255 , 0 ), 2 )
1419+ cv2.putText(image_copy, f ' Match: { max_val:.3f } ' ,
1420+ (top_left[0 ], top_left[1 ] - 10 ),
1421+ cv2.FONT_HERSHEY_SIMPLEX , 0.9 , (0 , 255 , 0 ), 2 )
1422+
1423+ # 显示结果
1424+ plt.figure(figsize = (15 , 5 ))
1425+
1426+ plt.subplot(1 , 3 , 1 )
1427+ plt.imshow(cv2.cvtColor(template, cv2.COLOR_BGR2RGB ))
1428+ plt.title(' Template' )
1429+ plt.axis(' off' )
1430+
1431+ plt.subplot(1 , 3 , 2 )
1432+ plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB ))
1433+ plt.title(' Target Image' )
1434+ plt.axis(' off' )
1435+
1436+ plt.subplot(1 , 3 , 3 )
1437+ plt.imshow(cv2.cvtColor(image_copy, cv2.COLOR_BGR2RGB ))
1438+ plt.title(f ' Match Result (Score: { max_val:.3f } ) ' )
1439+ plt.axis(' off' )
1440+
1441+ plt.tight_layout()
1442+ plt.show()
1443+
1444+ # 如果需要找到所有匹配位置(设置阈值)
1445+ threshold = 0.8 # 匹配阈值
1446+ locations = np.where(result >= threshold)
1447+ locations = list (zip (* locations[::- 1 ])) # 转换为 (x, y) 格式
1448+
1449+ print (f ' Found { len (locations)} matches above threshold { threshold} ' )
1450+ for loc in locations:
1451+ cv2.rectangle(image_copy, loc, (loc[0 ] + w, loc[1 ] + h), (255 , 0 , 0 ), 2 )
1452+ ```
1453+
1454+
13191455### 特征点校准
13201456
13211457特征点校准主要用于图像校准、图像拼接、图像匹配等场景。
0 commit comments