Skip to content

Commit 17afd7e

Browse files
📝 更新OpenCV文档,新增图像截取与模板匹配示例
- 在文档中新增了图像截取的详细说明与示例,展示了如何根据不同方式截取图像。 - 增加了模板匹配的介绍,包括应用场景、函数签名及示例代码,阐述了如何在图像中寻找指定模板位置。 - 优化了文档结构,提升了内容的实用性与参考价值。
1 parent ce4b070 commit 17afd7e

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed

docs/docs/深度学习/opencv.mdx

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ cv2.waitKey(1000)
344344
# 关闭所有窗口
345345
cv2.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

Comments
 (0)