Skip to content

Commit cfcdbf8

Browse files
author
wasalen
committed
opencv_study
1 parent a9c9edd commit cfcdbf8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1409
-46
lines changed

.gitignore

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,14 @@
11
/挑战任务3:车道检测/test_pictures/
2-
/挑战任务3:车道检测/test_videos/
2+
/挑战任务3:车道检测/test_videos/
3+
*.xml
4+
*.iml
5+
*.caffemodel
6+
*.prototxt
7+
*.avi
8+
*.mp4
9+
/venv
10+
*.jpg
11+
*.gif
12+
*.png
13+
14+

03. 打开摄像头/cv2_capture_live_video_from_camera.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import cv2
55

66
# 1.打开摄像头
7-
capture = cv2.VideoCapture(2)
7+
capture = cv2.VideoCapture(0)
88

99
# 2.获取捕获的分辨率
1010
width, height = capture.get(3), capture.get(4)
@@ -18,8 +18,9 @@
1818
# 获取一帧
1919
ret, frame = capture.read()
2020
# 将这帧转换为灰度图
21-
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
21+
if ret:
22+
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
2223

23-
cv2.imshow('frame', gray)
24+
cv2.imshow('frame', frame)
2425
if cv2.waitKey(1) == ord('q'):
2526
break

03. 打开摄像头/cv2_exercise1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def track_back(x):
2020
# 创建滑动条
2121
cv2.createTrackbar('process', 'window', 1, int(frames), track_back)
2222

23-
while(capture.isOpened()):
23+
while capture.isOpened():
2424
ret, frame = capture.read()
2525

2626
cv2.imshow('window', frame)

03. 打开摄像头/cv2_play_video_from_file.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import cv2
55

66
# 播放本地视频
7-
capture = cv2.VideoCapture('demo_video.mp4')
7+
capture = cv2.VideoCapture('output.avi')
88

9-
while(capture.isOpened()):
9+
while capture.isOpened():
1010
ret, frame = capture.read()
1111
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
1212

03. 打开摄像头/cv2_save_video_to_file.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
1010
outfile = cv2.VideoWriter('output.avi', fourcc, 25., (640, 480))
1111

12-
while(capture.isOpened()):
12+
while capture.isOpened():
1313
ret, frame = capture.read()
1414

1515
if ret:
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import cv2 as cv
2+
import numpy as np
3+
4+
dataset = 'MPI'
5+
if dataset == 'COCO':
6+
BODY_PARTS = { "Nose": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
7+
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
8+
"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "REye": 14,
9+
"LEye": 15, "REar": 16, "LEar": 17, "Background": 18 }
10+
11+
POSE_PAIRS = [ ["Neck", "RShoulder"], ["Neck", "LShoulder"], ["RShoulder", "RElbow"],
12+
["RElbow", "RWrist"], ["LShoulder", "LElbow"], ["LElbow", "LWrist"],
13+
["Neck", "RHip"], ["RHip", "RKnee"], ["RKnee", "RAnkle"], ["Neck", "LHip"],
14+
["LHip", "LKnee"], ["LKnee", "LAnkle"], ["Neck", "Nose"], ["Nose", "REye"],
15+
["REye", "REar"], ["Nose", "LEye"], ["LEye", "LEar"] ]
16+
else:
17+
assert(dataset == 'MPI')
18+
BODY_PARTS = { "Head": 0, "Neck": 1, "RShoulder": 2, "RElbow": 3, "RWrist": 4,
19+
"LShoulder": 5, "LElbow": 6, "LWrist": 7, "RHip": 8, "RKnee": 9,
20+
"RAnkle": 10, "LHip": 11, "LKnee": 12, "LAnkle": 13, "Chest": 14,
21+
"Background": 15 }
22+
23+
POSE_PAIRS = [["Head", "Neck"], ["Neck", "RShoulder"], ["RShoulder", "RElbow"],
24+
["RElbow", "RWrist"], ["Neck", "LShoulder"], ["LShoulder", "LElbow"],
25+
["LElbow", "LWrist"], ["Neck", "Chest"], ["Chest", "RHip"], ["RHip", "RKnee"],
26+
["RKnee", "RAnkle"], ["Chest", "LHip"], ["LHip", "LKnee"], ["LKnee", "LAnkle"] ]
27+
28+
inWidth = 368
29+
inHeight = 368
30+
thr = 0.1
31+
protoc = "../openpose/pose_deploy.prototxt"
32+
model = "../openpose/pose_iter_584000.caffemodel"
33+
net = cv.dnn.readNetFromCaffe(protoc, model)
34+
35+
cap = cv.VideoCapture(0)
36+
# 播放本地视频
37+
# cap = cv.VideoCapture('output.avi')
38+
height = cap.get(cv.CAP_PROP_FRAME_HEIGHT)
39+
width = cap.get(cv.CAP_PROP_FRAME_WIDTH)
40+
# video_writer = cv.VideoWriter("demo.mp4", cv.VideoWriter_fourcc('D', 'I', 'V', 'X'), 15, (640, 480), True)
41+
iit = 0
42+
while cv.waitKey(1) < 0:
43+
hasFrame, frame = cap.read()
44+
if not hasFrame:
45+
cv.waitKey()
46+
break
47+
48+
frameWidth = frame.shape[1]
49+
frameHeight = frame.shape[0]
50+
inp = cv.dnn.blobFromImage(frame, 1.0 / 255, (inWidth, inHeight),
51+
(0, 0, 0), swapRB=False, crop=False)
52+
net.setInput(inp)
53+
out = net.forward()
54+
55+
print(len(BODY_PARTS), out.shape[0])
56+
# assert(len(BODY_PARTS) == out.shape[1])
57+
58+
points = []
59+
for i in range(len(BODY_PARTS)):
60+
# Slice heatmap of corresponging body's part.
61+
heatMap = out[0, i, :, :]
62+
63+
# Originally, we try to find all the local maximums. To simplify a sample
64+
# we just find a global one. However only a single pose at the same time
65+
# could be detected this way.
66+
_, conf, _, point = cv.minMaxLoc(heatMap)
67+
x = (frameWidth * point[0]) / out.shape[3]
68+
y = (frameHeight * point[1]) / out.shape[2]
69+
70+
# Add a point if it's confidence is higher than threshold.
71+
points.append((x, y) if conf > thr else None)
72+
73+
for pair in POSE_PAIRS:
74+
partFrom = pair[0]
75+
partTo = pair[1]
76+
assert(partFrom in BODY_PARTS)
77+
assert(partTo in BODY_PARTS)
78+
79+
idFrom = BODY_PARTS[partFrom]
80+
idTo = BODY_PARTS[partTo]
81+
if points[idFrom] and points[idTo]:
82+
x1, y1 = points[idFrom]
83+
x2, y2 = points[idTo]
84+
cv.line(frame, (np.int32(x1), np.int32(y1)), (np.int32(x2), np.int32(y2)), (0, 255, 0), 3)
85+
cv.ellipse(frame, (np.int32(x1), np.int32(y1)), (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
86+
cv.ellipse(frame, (np.int32(x2), np.int32(y2)), (3, 3), 0, 0, 360, (0, 0, 255), cv.FILLED)
87+
88+
t, _ = net.getPerfProfile()
89+
freq = cv.getTickFrequency() / 1000
90+
cv.putText(frame, '%.2fms' % (t / freq), (10, 20), cv.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0))
91+
# video_writer.write(frame);
92+
cv.imwrite("bbb/pose{}.png".format(iit), frame)
93+
cv.imshow('OpenPose using OpenCV', frame)
94+
iit += 1

04. 图像基本操作/cv2_basic_operations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import cv2
55

66
img = cv2.imread('lena.jpg')
7-
7+
print(type(img))
88
# 1.获取像素的值
99
px = img[100, 90]
1010
print(px) # [103 98 197]

05. 颜色空间转换/cv2_changing_color_space.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,33 @@
77

88
# 1.转成灰度图
99
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
10-
11-
cv2.imshow('img', img)
10+
# cv2.namedWindow('gray', cv2.WINDOW_NORMAL)
11+
# cv2.imshow('img', img)
1212
cv2.imshow('gray', img_gray)
1313
cv2.waitKey(0)
1414

15-
1615
# 2.获取所有的转换模式
1716
flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
1817
print(flags)
1918

2019
# 蓝色的HSV值
2120
import numpy as np
2221

22+
"""
23+
OpenCV中色调H范围为[0,179],饱和度S是[0,255],明度V是[0,255]。虽然H的理论数值是0°~360°,但8位图像像素点的最大值是255,所以OpenCV中除以了2,某些软件可能使用不同的尺度表示,所以同其他软件混用时,记得归一化。
24+
"""
2325
blue = np.uint8([[[255, 0, 0]]])
2426
hsv_blue = cv2.cvtColor(blue, cv2.COLOR_BGR2HSV)
2527
print(hsv_blue) # [[[120 255 255]]]
2628

27-
2829
# 3.追踪蓝色物体
2930
capture = cv2.VideoCapture(0)
3031

3132
# 蓝色的范围,不同光照条件下不一样,可灵活调整
3233
lower_blue = np.array([100, 110, 110])
3334
upper_blue = np.array([130, 255, 255])
3435

35-
while(True):
36+
while True:
3637
# 1.捕获视频中的一帧
3738
ret, frame = capture.read()
3839

05. 颜色空间转换/cv2_exercises1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# Green:[[[ 60 255 255]]]
1010
# Red:[[[ 0 255 255]]]
1111

12-
capture = cv2.VideoCapture(1)
12+
capture = cv2.VideoCapture(0)
1313

1414
# 蓝色的范围
1515
lower_blue = np.array([100, 110, 110])

06. 阈值分割/cv2_thresholding.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
img = cv2.imread('gradient.jpg', 0)
99
# 阈值分割,ret:return value缩写,代表当前的阈值,暂时不用理会
1010
ret, th = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
11+
cv2.imshow('img', img)
1112
cv2.imshow('thresh', th)
1213
cv2.waitKey(0)
1314

09. 图像混合/图像混合.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
[![img](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg)](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg)
2+
3+
# Python+OpenCV教程9:图像混合
4+
5+
Posted on [December 10, 2017](http://ex2tron.wang/opencv-python-image-blending/)
6+
7+
学习图片间的数学运算,图像混合。图片等可到[源码处](http://ex2tron.wang/opencv-python-image-blending/#%E5%BC%95%E7%94%A8)下载。
8+
9+
------
10+
11+
## 目标
12+
13+
- 图片间的数学运算,如相加、按位运算等
14+
- OpenCV函数:`cv2.add()`, `cv2.addWeighted()`, `cv2.bitwise_and()`
15+
16+
## 教程
17+
18+
> 首先恭喜你已经完成了入门篇的学习噢,接下来我们学习一些OpenCV的基础内容,加油(ง •_•)ง
19+
20+
### 图片相加
21+
22+
要叠加两张图片,可以用`cv2.add()`函数,相加两幅图片的形状(高度/宽度/通道数)必须相同。numpy中可以直接用res = img + img1相加,但这两者的结果并不相同:
23+
24+
```
25+
x = np.uint8([250])
26+
y = np.uint8([10])
27+
print(cv2.add(x, y)) # 250+10 = 260 => 255
28+
print(x + y) # 250+10 = 260 % 256 = 4
29+
```
30+
31+
如果是二值化图片(只有0和255两种值),两者结果是一样的(用numpy的方式更简便一些)。
32+
33+
### 图像混合
34+
35+
图像混合`cv2.addWeighted()`也是一种图片相加的操作,只不过两幅图片的权重不一样,γ相当于一个修正值:
36+
37+
38+
39+
dst=α×img1+β×img2+γdst=α×img1+β×img2+γ
40+
41+
42+
43+
```
44+
img1 = cv2.imread('lena_small.jpg')
45+
img2 = cv2.imread('opencv-logo-white.png')
46+
res = cv2.addWeighted(img1, 0.6, img2, 0.4, 0)
47+
```
48+
49+
[![图像混合](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg)](http://pic.ex2tron.top/cv2_image_blending_6_4.jpg)图像混合
50+
51+
> 经验之谈:α和β都等于1时,就相当于图片相加。
52+
53+
### 按位操作
54+
55+
按位操作包括按位与/或/非/异或操作,有什么用途呢?比如说我们要实现下图的效果:
56+
57+
[![img](http://pic.ex2tron.top/cv2_bitwise_operations_demo.jpg)](http://pic.ex2tron.top/cv2_bitwise_operations_demo.jpg)
58+
59+
如果将两幅图片直接相加会改变图片的颜色,如果用图像混合,则会改变图片的透明度,所以我们需要用按位操作。首先来了解一下[掩膜](https://baike.baidu.com/item/%E6%8E%A9%E8%86%9C/8544392?fr=aladdin)(mask)的概念:掩膜是用一副二值化图片对另外一幅图片进行局部的遮挡,看下图就一目了然了:
60+
61+
[![掩膜概念](http://pic.ex2tron.top/cv2_understand_mask.jpg)](http://pic.ex2tron.top/cv2_understand_mask.jpg)掩膜概念
62+
63+
所以我们的思路就是把原图中要放logo的区域抠出来,再把logo放进去就行了:
64+
65+
```
66+
img1 = cv2.imread('lena.jpg')
67+
img2 = cv2.imread('opencv-logo-white.png')
68+
69+
# 把logo放在左上角,所以我们只关心这一块区域
70+
rows, cols = img2.shape[:2]
71+
roi = img1[:rows, :cols]
72+
73+
# 创建掩膜
74+
img2gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
75+
ret, mask = cv2.threshold(img2gray, 10, 255, cv2.THRESH_BINARY)
76+
mask_inv = cv2.bitwise_not(mask)
77+
78+
# 保留除logo外的背景
79+
img1_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
80+
dst = cv2.add(img1_bg, img2) # 进行融合
81+
img1[:rows, :cols] = dst # 融合后放在原图上
82+
```
83+
84+
> 经验之谈:掩膜的概念在图像混合/叠加的场景下使用较多,可以多多练习噢!
85+
86+
## 小结
87+
88+
- `cv2.add()`用来叠加两幅图片,`cv2.addWeighted()`也是叠加两幅图片,但两幅图片的权重不一样。
89+
- `cv2.bitwise_and()`, `cv2.bitwise_not()`, `cv2.bitwise_or()`, `cv2.bitwise_xor()`分别执行按位与/或/非/异或运算。掩膜就是用来对图片进行全局或局部的遮挡。
90+
91+
## 引用
92+
93+
- [本节源码](https://github.com/ex2tron/OpenCV-Python-Tutorial/tree/master/09.%20%E5%9B%BE%E5%83%8F%E6%B7%B7%E5%90%88)
94+
- [掩膜](https://baike.baidu.com/item/%E6%8E%A9%E8%86%9C/8544392?fr=aladdin)
95+
- [Arithmetic Operations on Images](http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_core/py_image_arithmetics/py_image_arithmetics.html)

11. 边缘检测/666.jpg

77 KB
Loading

11. 边缘检测/6666.jpg

15.1 KB
Loading

11. 边缘检测/cv2_canny_edge_detection.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,23 @@
33

44
import cv2
55
import numpy as np
6+
import matplotlib.pyplot as plt
67

78
# 1.Canny边缘检测
8-
img = cv2.imread('handwriting.jpg', 0)
9+
img = cv2.imread('666.jpg', 0)
910
edges = cv2.Canny(img, 30, 70)
1011

11-
cv2.imshow('canny', np.hstack((img, edges)))
12-
cv2.waitKey(0)
12+
# cv2.imshow('canny', np.hstack((img, edges)))
13+
ret, th1 = cv2.threshold(edges, 127, 255, cv2.THRESH_BINARY_INV)
14+
# cv2.imshow('canny', th1)
15+
# cv2.waitKey(0)
16+
# cv2.imwrite("a.jpg", edges)
1317

1418

1519
# 2.先阈值,后边缘检测
1620
# 阈值分割(使用到了番外篇讲到的Otsu自动阈值)
1721
_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
1822
edges = cv2.Canny(thresh, 30, 70)
19-
23+
# cv2.imshow('canny', thresh)
2024
cv2.imshow('canny', np.hstack((img, thresh, edges)))
2125
cv2.waitKey(0)

11. 边缘检测/cv2_exercise1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def track_back(x):
99
pass
1010

1111

12-
img = cv2.imread('sudoku.jpg', 0)
12+
img = cv2.imread('123.jpg', 0)
1313
cv2.namedWindow('window')
1414

1515
# 创建滑动条

13. 轮廓/666.jpg

77 KB
Loading

13. 轮廓/cv2_find_contours.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
1111

1212
# 寻找轮廓
13-
image, contours, hierarchy = cv2.findContours(
14-
thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
15-
16-
cnt = contours[1]
17-
cv2.drawContours(img, [cnt], 0, (0, 0, 255), 2)
13+
# print(len(cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)))
14+
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
15+
print(hierarchy)
16+
# cnt = contours[0]
17+
for cnt in contours:
18+
print(cv2.arcLength(cnt, True), cv2.contourArea(cnt))
19+
img = cv2.drawContours(img, [cnt], 0, (0, 0, 255), 2)
1820

1921
cv2.imshow('contours', img)
2022
cv2.waitKey(0)

0 commit comments

Comments
 (0)