Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 29ec6fc

Browse files
committed
update ch21
1 parent 051f311 commit 29ec6fc

15 files changed

+385
-3
lines changed

‎ch18-图像梯度/box.png‎

-255 Bytes
Binary file not shown.

‎ch18-图像梯度/一个重要的事.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
import numpy as np
2323
from matplotlib import pyplot as plt
2424

25-
img = cv2.imread('box.png', 0)
25+
img = cv2.imread('../data/box.png', 0)
2626

2727
# Output dtype = cv2.CV_8U
2828
sobelx8u = cv2.Sobel(img, cv2.CV_8U, 1, 0, ksize=5)

‎ch21-OpenCV中的轮廓Contours/21-findContour.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
ret, thresh = cv2.threshold(src=imgray, thresh=127, maxval=255, type=cv2.THRESH_BINARY)#src, thresh, maxval, type
1919

2020
cv2.imshow("thresh", thresh)
21-
21+
#轮廓提取模式 Contour_Retrieval_Mode
2222
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
2323
print("contours size: ", len(contours))
2424

‎ch21-OpenCV中的轮廓Contours/21-moments.py‎

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
__author__ = 'play4fun'
33
"""
44
create time:15-10-23 下午12:56
5+
图像的矩可以帮助我们计算图像的质心, 面积等。
56
"""
67

78
import cv2
@@ -10,15 +11,50 @@
1011
from pprint import pprint
1112

1213
img = cv2.imread('../data/star.png', 0)
14+
# img = cv2.imread('../data/box.png', 0)
15+
1316
ret, thresh = cv2.threshold(img, 127, 255, 0)
1417
# ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
1518
# contours,hierarchy = cv2.findContours(thresh, 1, 2)
1619
image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
1720
# contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
1821

22+
print('contours len:', len(contours))
1923

20-
cnt = contours[0]
24+
cnt = contours[0]# 第一个
2125
M = cv2.moments(cnt)
2226

2327
# print(M)
2428
pprint(M) # 好看一点
29+
30+
# 根据 这些矩的值 我们可以 计算出对象的重心
31+
cx = int(M['m10'] / M['m00'])
32+
cy = int(M['m01'] / M['m00'])
33+
print('重心:', cx, cy)
34+
35+
#
36+
area = cv2.contourArea(cnt)
37+
print('面积:', area)
38+
39+
# 第二参数可以用来指定对象的形状是闭合的 True 是打开的FALSE 一条曲线 。
40+
perimeter = cv2.arcLength(cnt, True)
41+
print('周长:', perimeter)
42+
43+
'''
44+
将轮廓形状近似到另外一种由更少点组成的 廓形状 新 廓的点的数目 由我们 定的准确度来决定。
45+
使用的Douglas-Peucker算法
46+
为了帮助理解,假设我们 在一幅图像中查找一个矩形
47+
但是由于图像的 种种原因,我们不能得到一个完美的矩形 而是一个 坏形状 如下图所示 。
48+
49+
现在你就可以使用这个函数来近似 个形状 了。
50+
这个函数的第二个参数叫 epsilon 它是从原始 廓到近似轮廓的最大距离。它是一个准确度参数。
51+
选择一个好的 epsilon 对于得到满意结果非常重要
52+
'''
53+
epsilon = 0.1*cv2.arcLength(cnt,True)
54+
print('epsilon:',epsilon)
55+
approx = cv2.approxPolyDP(cnt,epsilon,True)
56+
cv2.drawContours(image,[approx],0,(255,0,0),3)
57+
cv2.imshow('approxPolyDP',image)
58+
59+
cv2.waitKey(0)
60+
cv2.destroyAllWindows()
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2017年7月12日 下午7:49
3+
# @Author : play4fun
4+
# @File : 21.1.2 怎样绘制轮轮廓.py
5+
# @Software: PyCharm
6+
7+
"""
8+
21.1.2 怎样绘制轮轮廓.py:
9+
函数 cv2.drawContours() 可以 用来绘制 轮廓。它可以根据你提供 的 界点绘制任何形状。
10+
第一个参数是原始图像
11+
第二个参数是 轮廓 一 个 Python 列表。
12+
第三个参数是 轮廓的索引
13+
在绘制独立 轮廓是很有用 当 设置为 -1 时绘制所有轮廓 。
14+
接下来的参数是 轮廓的颜色和厚度等。
15+
"""
16+
17+
import numpy as np
18+
import cv2
19+
20+
im = cv2.imread('test.jpg')
21+
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
22+
23+
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
24+
25+
img, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
26+
27+
# 绘制独立 轮廓 如第四个 轮廓
28+
cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
29+
# To gdraw an individual contour, say 4th contour:
30+
31+
cv2.drawContours(image=img, contours=contours, contourIdx=3, color=(0, 255, 0), thickness=3)
32+
# drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None)
33+
34+
# But most of the time, below method will be useful:
35+
# 但是大多数时候 下 的方法更有用
36+
cnt = contours[4]
37+
cv2.drawContours(img, [cnt], 0, (0, 255, 0), 3)
38+
39+
'''
40+
这个参数如果 设置为 cv2.CHAIN_APPROX_NONE
41+
所有的边界点 都 会被存储。但是我们真的需要那么多点吗 ?
42+
例如 当我们找的边界是一条直线时。你需要直线上所有的点来表示直线吗 ?
43+
不是的 我们只需要1 条直线 的两个端点而已。
44+
就是 cv2.CHAIN_APPROX_SIMPLE 做的。它会
45+
将 轮廓上的冗余点 去掉, 压缩 轮廓 ,从而节省内存开支。
46+
'''
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2017年7月12日 下午8:47
3+
# @Author : play4fun
4+
# @File : 21.4 轮廓-更多函数.py
5+
# @Software: PyCharm
6+
7+
"""
8+
21.4 轮廓-更多函数.py:
9+
"""
10+
11+
import cv2
12+
import numpy as np
13+
14+
'''
15+
Point Polygon Test
16+
求 图像中的一个点到一个对 廓的最短 离。如果点在 廓的外 回值为 。如果在 廓上 回值为 0。如果在 廓内 回值为正。
17+
下 我们以点 50 50 为例
18+
19+
dist = cv2.pointPolygonTest(cnt,(50,50),True)
20+
21+
此函数的第三个参数是 measureDist。如果 置为 True 就会 算最 短 离。如果是 False 只会判断 个点与 廓之 的位置关系 回值为 +1 -1 0
22+
23+
注意 如果你不 知 具体 离 建 你将第三个参数 为 False 这样速度会提 2 到 3 倍。
24+
'''
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2017年7月12日 下午9:30
3+
# @Author : play4fun
4+
# @File : 21.4.3-形状匹配.py
5+
# @Software: PyCharm
6+
7+
"""
8+
21.4.3-形状匹配.py:
9+
函数 cv2.matchShape() 可以帮我们比 两个形状或 廓的相似度。
10+
如果返回值越小, 匹配越好。它是根据 Hu 矩来计算的。文档中对不同的方法有解释。
11+
12+
"""
13+
14+
import cv2
15+
import numpy as np
16+
17+
img1 = cv2.imread('star.jpg', 0)
18+
img2 = cv2.imread('star2.jpg', 0)
19+
20+
ret, thresh = cv2.threshold(img1, 127, 255, 0)
21+
ret, thresh2 = cv2.threshold(img2, 127, 255, 0)
22+
23+
contours, hierarchy = cv2.findContours(thresh, 2, 1)
24+
cnt1 = contours[0]
25+
contours, hierarchy = cv2.findContours(thresh2, 2, 1)
26+
cnt2 = contours[0]
27+
28+
ret = cv2.matchShapes(cnt1, cnt2, 1, 0.0)
29+
print(ret)
30+
31+
#Hu 矩是归一化中心矩的线性组合
32+
# 之所以 样做是为了能够获取 代表图像的某个特征的矩函数
33+
# 这些矩函数对某些变化如缩放 旋转, 镜像映射 ( 除了 h1) 具有不变形。
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
什么是轮廓
2+
3+
轮廓可以简单 为成将连续的点 着 界 在一 的曲线 具有相同
4+
的 色或者灰度。 轮廓在形状分析和物体的检测和 别中很有用。
5+
• 为了更加准确 使用二值化图像。在寻找 轮廓之前 ,要进行阈值化处理
6+
或者 Canny 边界检测。
7+
• 查找 轮廓的函数会修改原始图像。如果你在找到 轮廓之后 想使用原始图
8+
像的 你应 将原始图像存储到其他变 中。
9+
• 在 OpenCV 中 查找 轮廓就像在黑色背景中超白色物体。你应该记住 找的物体应 是白色而背景应该是黑色。
10+
11+
我们看看如何在一个二值图像中查找 轮廓
12+
函数 cv2.findContours() 有三个参数
13+
第一个是 入图像
14+
第二个是轮廓检索模式
15+
第三个是 轮廓近似方法。
16+
17+
返回值有三个
18+
第一个是图像
19+
第二个 是 轮廓
20+
第三个是 轮廓的 层析结构。
21+
22+
轮廓 第二个 回值 是一个 Python 列表
23+
其中存储 图像中的所有 轮廓。
24+
每一个 轮廓 是一个 Numpy 数组 包含对 边界点 x y 的坐标。
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2017年7月12日 下午8:28
3+
# @Author : play4fun
4+
# @File : 凸包-凸性检测-边界矩形-最小外接圆-拟合.py
5+
# @Software: PyCharm
6+
7+
"""
8+
凸包-凸性检测-边界矩形-最小外接圆-拟合.py:
9+
"""
10+
import cv2
11+
12+
'''
13+
函数 cv2.convexHull() 可以用来检测一个曲线是否具有凸性缺 并能纠 正缺 。一般来 凸性曲线总是凸出来的 至少是平的。如果有地方凹 去 了就 叫做凸性缺
14+
例如下图中的手。红色曲线显示了手的凸包 凸性缺 双箭头标出来了。
15+
'''
16+
# convexHull(points, hull=None, clockwise=None, returnPoints=None)
17+
hull = cv2.convexHull(points, hull, clockwise, returnPoints)
18+
19+
'''
20+
points 我们 传入的 廓
21+
• hull 输出 通常不需要
22+
• clockwise 方向标志。如果 置为 True 出的凸包是顺时针 方向的。 否则为逆时针 方向。
23+
• returnPoints 值为 True。它会 回凸包上点的坐标。如果 置 为 False 就会 回与凸包点对应的 廓上的点。
24+
'''
25+
hull = cv2.convexHull(cnt)
26+
27+
# 凸性检测
28+
# 函数 cv2.isContourConvex() 可以可以用来检测一个曲线是不是凸的。它只能 回 True 或 False。没什么大不了的。
29+
k = cv2.isContourConvex(cnt)
30+
31+
# 边界矩形
32+
'''
33+
直边界矩形 一个直矩形 就是没有旋 的矩形 。它不会考虑对象是否旋转。 所以边界矩形的 积不是最小的。可以使用函数 cv2.boundingRect() 查 找得到。
34+
x y 为矩形左上角的坐标 w h 是矩形的宽和 。
35+
'''
36+
x, y, w, h = cv2.boundingRect(cnt)
37+
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
38+
39+
'''
40+
旋 的 界矩形 个 界矩形是 积最小的 因为它考 了对 的旋 。用 到的函数为 cv2.minAreaRect()。 回的是一个 Box2D 结构 其中包含 矩形左上 点的坐标 x y 矩形的宽和 w h 以及旋 度。但是 绘制 个矩形 矩形的 4 个 点 可以 函数 cv2.boxPoints() 获 得。
41+
'''
42+
x, y, w, h = cv2.boundingRect(cnt)
43+
img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
44+
45+
# 最小外接圆
46+
# 函数 cv2.minEnclosingCircle() 可以帮我们找到一个对 的外切圆。它是所有能够包括对 的圆中 积最小的一个。
47+
(x, y), radius = cv2.minEnclosingCircle(cnt)
48+
center = (int(x), int(y))
49+
radius = int(radius)
50+
img = cv2.circle(img, center, radius, (0, 255, 0), 2)
51+
52+
# 椭圆拟合
53+
# 使用的函数为 cv2.ellipse() 回值其实就是旋 界矩形的内切圆
54+
ellipse = cv2.fitEllipse(cnt)
55+
im = cv2.ellipse(im, ellipse, (0, 255, 0), 2)
56+
57+
# 直线拟合
58+
# 我们可以根据一组点拟合出一条直线 同样我们也可以为图像中的白色点 拟合出一条直线。
59+
rows, cols = img.shape[:2]
60+
[vx, vy, x, y] = cv2.fitLine(cnt, cv2.DIST_L2, 0, 0.01, 0.01)
61+
lefty = int((-x * vy / vx) + y)
62+
righty = int(((cols - x) * vy / vx) + y)
63+
cv2.line(img, (cols - 1, righty), (0, lefty), (0, 255, 0), 2)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2017年7月12日 下午9:25
3+
# @Author : play4fun
4+
# @File : 凸缺陷.py
5+
# @Software: PyCharm
6+
7+
"""
8+
凸缺陷.py:
9+
"""
10+
11+
# 凸缺陷
12+
# 前 我们已经学习了 廓的凸包 对 上的任何凹 成为凸缺 。
13+
# OpenCV 中有一个函数 cv.convexityDefect() 可以帮助我们找到凸缺
14+
15+
16+
# hull = cv2.convexHull(cnt, returnPoints=False)
17+
# defects = cv2.convexityDefects(cnt, hull)
18+
19+
20+
# 注意 如果 查找凸缺 在使用函数 cv2.convexHull 找凸包时 参数 returnPoints 一定 是 False
21+
'''
22+
它会 回一个数组 其中每一 包含的值是 [ 点 终点 最 的点 到最 点的 似 离]。我们可以在一张图上显示它。我们将 点和终点用一条绿线 接 在最 点画一个圆圈 住的是 回结果的前三个值是 廓点的索引。 所以我们 到 廓点中去找它们。
23+
'''
24+
import cv2
25+
import numpy as np
26+
27+
img = cv2.imread('star.jpg')
28+
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
29+
30+
ret, thresh = cv2.threshold(img_gray, 127, 255, 0)
31+
contours, hierarchy = cv2.findContours(thresh, 2, 1)
32+
33+
cnt = contours[0]
34+
hull = cv2.convexHull(cnt, returnPoints=False)
35+
defects = cv2.convexityDefects(cnt, hull)
36+
37+
for i in range(defects.shape[0]):
38+
s, e, f, d = defects[i, 0]
39+
start = tuple(cnt[s][0])
40+
end = tuple(cnt[e][0])
41+
far = tuple(cnt[f][0])
42+
cv2.line(img, start, end, [0, 255, 0], 2)
43+
cv2.circle(img, far, 5, [0, 0, 255], -1)
44+
cv2.imshow('img', img)
45+
cv2.waitKey(0)
46+
cv2.destroyAllWindows()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /