Skip to content

Commit ce4b070

Browse files
📝 更新OpenCV文档,新增箭头绘制与图像拼接示例
- 在文档中新增了`cv2.arrowedLine`函数的使用示例,展示如何在图像上绘制箭头。 - 增加了图像横向与纵向拼接的详细说明与示例,阐述了如何确保拼接方向上的尺寸一致。 - 更新了图像处理相关内容,提升了文档的实用性与参考价值。
1 parent e05f848 commit ce4b070

File tree

1 file changed

+164
-24
lines changed

1 file changed

+164
-24
lines changed

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

Lines changed: 164 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,37 @@ cv2.waitKey(1000)
344344
# 关闭所有窗口
345345
cv2.destroyAllWindows()
346346
```
347+
### 绘制箭头
348+
349+
函数签名:`cv2.arrowedLine(img, start_point, end_point, color, thickness, tipLength) -> img`
350+
351+
参数说明:
352+
353+
- `img`:图像对象
354+
- `start_point`:起点坐标
355+
- `end_point`:终点坐标
356+
- `color`:颜色
357+
- `thickness`:线宽
358+
- `tipLength`:箭头占比
359+
360+
```python showLineNumbers
361+
import cv2
362+
img = cv2.imread("top.png")
363+
364+
# 假设 Agent 决定点击 (800, 450)
365+
start_point = (0, 0) # 从下往上画一支箭,更像人伸手
366+
end_point = (100, 250) # 指向目标按钮
367+
368+
img_with_arrow = cv2.arrowedLine(
369+
img, start_point, end_point,
370+
color=(0, 255, 255), # 黄箭头
371+
thickness=8, # 粗箭头,摄像头里都看得清
372+
tipLength=0.3 # 箭头占比,越大越明显
373+
)
374+
375+
cv2.imwrite("agent_intent.jpg", img_with_arrow)
376+
```
377+
347378

348379
### PIL库绘制中文
349380

@@ -444,6 +475,74 @@ cv2.waitKey(0)
444475
```
445476
:::
446477

478+
### 图像横向与纵向拼接
479+
480+
图像拼接的前提是两张图片在拼接方向上的尺寸相同(横向拼接要求高度相同,纵向拼接要求宽度相同)。
481+
482+
横向拼接函数签名:`cv2.hconcat(src, dst) -> dst``np.hstack((img1, img2, ...)) -> dst`
483+
484+
纵向拼接函数签名:`cv2.vconcat(src, dst) -> dst``np.vstack((img1, img2, ...)) -> dst`
485+
486+
参数说明:
487+
488+
- `src`:图像列表或元组
489+
- `dst`:输出图像
490+
491+
```python showLineNumbers
492+
import cv2
493+
import numpy as np
494+
495+
# 读取两张图片
496+
img1 = cv2.imread("img1.jpg")
497+
img2 = cv2.imread("img2.jpg")
498+
499+
# 确保两张图片高度相同(横向拼接)
500+
h1, w1 = img1.shape[:2]
501+
h2, w2 = img2.shape[:2]
502+
if h1 != h2:
503+
# 将高度较小的图片调整到与高度较大的图片相同
504+
if h1 < h2:
505+
img1 = cv2.resize(img1, (w1, h2))
506+
else:
507+
img2 = cv2.resize(img2, (w2, h1))
508+
509+
# 方法1:使用 cv2.hconcat 横向拼接
510+
img_horizontal = cv2.hconcat([img1, img2])
511+
512+
# 方法2:使用 np.hstack 横向拼接(效果相同)
513+
# img_horizontal = np.hstack((img1, img2))
514+
515+
# 确保两张图片宽度相同(纵向拼接)
516+
h1, w1 = img1.shape[:2]
517+
h2, w2 = img2.shape[:2]
518+
if w1 != w2:
519+
# 将宽度较小的图片调整到与宽度较大的图片相同
520+
if w1 < w2:
521+
img1 = cv2.resize(img1, (w2, h1))
522+
else:
523+
img2 = cv2.resize(img2, (w1, h2))
524+
525+
# 方法1:使用 cv2.vconcat 纵向拼接
526+
img_vertical = cv2.vconcat([img1, img2])
527+
528+
# 方法2:使用 np.vstack 纵向拼接(效果相同)
529+
# img_vertical = np.vstack((img1, img2))
530+
531+
# 显示结果
532+
cv2.imshow("Horizontal", img_horizontal)
533+
cv2.imshow("Vertical", img_vertical)
534+
cv2.waitKey(0)
535+
cv2.destroyAllWindows()
536+
537+
# 保存结果
538+
cv2.imwrite("horizontal.jpg", img_horizontal)
539+
cv2.imwrite("vertical.jpg", img_vertical)
540+
```
541+
542+
:::tip
543+
如果图片尺寸不一致,需要先使用 `cv2.resize()` 调整尺寸,确保在拼接方向上尺寸相同。
544+
:::
545+
447546
## 基础图像操作
448547

449548
### 图像缩放
@@ -813,8 +912,8 @@ HSV:相比RGB相比,HSV能更好的表示同个颜色的不同值(饱和
813912

814913
### 灰度图
815914

816-
灰度图
817-
适用于图像处理,如边缘检测及其应用:图像分割、轮廓检测
915+
灰度图适用于图像处理,如边缘检测及其应用:图像分割、轮廓检测
916+
818917
只有1个通道,取值范围是0-255,表示颜色的亮度
819918

820919
```python showLineNumbers
@@ -842,10 +941,7 @@ cv2.destroyAllWindows()
842941

843942
### 二值化图
844943

845-
二值化图
846-
适用于图像压缩
847-
只有1个通道,取值范围是0或1
848-
944+
二值化图,适用于图像压缩。只有1个通道,取值范围是0或1
849945

850946
| 方法 | 核心思想 | 如何工作? | 优点 | 缺点 | 适用场景 |
851947
| :--- | :--- | :--- | :--- | :--- | :--- |
@@ -873,6 +969,28 @@ cv2.destroyAllWindows()
873969
归一化的目的是消除数据量纲和尺度的影响,使得不同尺度或单位的数据可以在同一水平上进行比较或处理。
874970
:::
875971

972+
函数签名:`cv2.threshold(img, thresh, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) -> retval, dst`
973+
974+
参数说明:
975+
976+
- `img`:输入灰度图像
977+
- `thresh`:阈值(Otsu方法中通常设为0,会自动计算最佳阈值)
978+
- `255`:当像素值超过阈值时赋予的新值(maxValue)
979+
- `cv2.THRESH_BINARY + cv2.THRESH_OTSU`:二值化类型,OTSU会自动计算最佳阈值
980+
981+
主要用于缺陷检测
982+
983+
函数签名:`cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) -> dst`
984+
985+
参数说明:
986+
987+
- `img`:输入灰度图像
988+
- `255`:当像素值超过阈值时赋予的新值(maxValue)
989+
- `cv2.ADAPTIVE_THRESH_GAUSSIAN_C`:自适应方法,使用高斯加权
990+
- `11`:用于计算阈值的邻域大小(blockSize,必须为奇数)
991+
- `2`:从平均值或加权和中减去的常数(C)
992+
993+
主要用于光照不均匀的场景
876994

877995
```python showLineNumbers
878996
import cv2
@@ -935,11 +1053,11 @@ def get_binary_image(img, method, *args, **kwargs):
9351053
# 全局平均值法
9361054
_, binary = cv2.threshold(img, img.mean(), 255, cv2.THRESH_BINARY)
9371055
elif method == 'adaptive_mean':
938-
# 自适应均值阈值法
1056+
# 自适应均值阈值法(光照不均匀时效果更好)
9391057
binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,
9401058
cv2.THRESH_BINARY, 11, 2)
9411059
elif method == 'adaptive_gaussian':
942-
# 自适应高斯阈值法
1060+
# 自适应高斯阈值法(光照不均匀时效果更好)
9431061
binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
9441062
cv2.THRESH_BINARY, 11, 2)
9451063
elif method == 'otsu':
@@ -1028,6 +1146,41 @@ cv2.destroyAllWindows()
10281146
- 黑帽: 闭运算 - 原图,用于填充图像中的小孔洞
10291147
:::
10301148

1149+
### 开运算和闭运算
1150+
1151+
开运算和闭运算主要用于去除图像中的小噪声和小孔洞、粘连断裂。
1152+
1153+
开运算函数签名:`cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) -> dst`
1154+
1155+
闭运算函数签名:`cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) -> dst`
1156+
1157+
参数说明:
1158+
1159+
- `img`:输入图像
1160+
- `cv2.MORPH_OPEN`:开运算操作类型(先腐蚀后膨胀)
1161+
- `cv2.MORPH_CLOSE`:闭运算操作类型(先膨胀后腐蚀)
1162+
- `kernel`:形态学操作的核
1163+
1164+
```python showLineNumbers
1165+
import cv2
1166+
import numpy as np
1167+
1168+
img = cv2.imread("dt2.png")
1169+
kernel = np.ones((3, 3), np.uint8)
1170+
1171+
# 开运算:先腐蚀后膨胀,用于去除图像中的小噪声
1172+
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
1173+
1174+
# 闭运算:先膨胀后腐蚀,用于填充图像中的小孔洞
1175+
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
1176+
1177+
cv2.imshow("Original", img)
1178+
cv2.imshow("Opening", opening)
1179+
cv2.imshow("Closing", closing)
1180+
cv2.waitKey(0)
1181+
cv2.destroyAllWindows()
1182+
```
1183+
10311184

10321185
### 模糊
10331186

@@ -1159,7 +1312,7 @@ cv2.destroyAllWindows()
11591312

11601313
## 算法指路
11611314

1162-
下面是Opencv常用的算法,每个算法都比较复杂且可能随时间变化出现新的算法,因此随用随学即可。
1315+
下面是Opencv常用的算法,每个算法都比较复杂且可能随时间变化出现新的算法,因此随用随学即可。另外,大部分算法也有深度学习的版本,效果更好。
11631316

11641317
想获得认证可以参与[OpenCV Bootcamp](https://courses.opencv.org/courses/course-v1:OpenCV+Bootcamp+CV0/course/)
11651318

@@ -1649,9 +1802,7 @@ video_out.release()
16491802

16501803
```
16511804

1652-
### 人体相关
1653-
1654-
#### 人脸检测
1805+
### 人脸检测
16551806

16561807
人脸检测算法广泛应用于身份验证、考勤系统、社交媒体标记、美颜相机和安防监控中。
16571808

@@ -1784,17 +1935,6 @@ if __name__ == "__main__":
17841935
recognizer()
17851936
```
17861937

1787-
#### 其他
1788-
1789-
人体检测算法广泛应用于智能安防、客流统计、健身应用、体感游戏和自动驾驶系统中。
1790-
1791-
人体姿态估计主要用于健身指导、医疗康复、运动分析、动作捕捉和人机交互界面。
1792-
1793-
手势识别技术应用于智能家居控制、手语翻译、VR/AR交互、游戏控制和辅助残障人士交流。
1794-
1795-
动作识别算法用于视频内容理解、体育比赛分析、异常行为检测、健身应用和人机交互。
1796-
1797-
行为识别技术主要应用于安防监控、智慧城市、客户行为分析、老人看护和异常事件预警。
17981938

17991939
## YOLO
18001940

@@ -1811,7 +1951,7 @@ if __name__ == "__main__":
18111951

18121952
经过测试:opencv加载YOLOv11模型,与原生yolo的FPS一致、内存占用一致。Opencv的CPU占用率更高。
18131953

1814-
所以使用OpenCV的唯一原因是可以用`C++`版本的代码,在无python依赖的设备上运行,适合资源受限的边缘设备
1954+
所以使用OpenCV的唯一原因是打包为可执行文件后体积更小
18151955
:::
18161956

18171957
### 导出模型

0 commit comments

Comments
 (0)