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 051b551

Browse files
committed
update ch15
1 parent 96b079f commit 051b551

File tree

6 files changed

+140
-37
lines changed

6 files changed

+140
-37
lines changed
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日 下午1:27
3+
# @Author : play4fun
4+
# @File : 15-How-OTSU-work.py
5+
# @Software: PyCharm
6+
7+
"""
8+
15-How-OTSU-work.py:
9+
"""
10+
11+
import cv2
12+
import numpy as np
13+
14+
img = cv2.imread('noisy2.png', 0)
15+
blur = cv2.GaussianBlur(img, (5, 5), 0)
16+
# find normalized_histogram, and its cumulative distribution function
17+
# 算归一化直方图
18+
# CalcHist(image, accumulate=0, mask=NULL)
19+
20+
hist = cv2.calcHist([blur], [0], None, [256], [0, 256])
21+
hist_norm = hist.ravel() / hist.max()
22+
Q = hist_norm.cumsum()
23+
24+
bins = np.arange(256)
25+
fn_min = np.inf
26+
thresh = -1
27+
28+
for i in range(1, 256):
29+
p1, p2 = np.hsplit(hist_norm, [i]) # probabilities
30+
q1, q2 = Q[i], Q[255] - Q[i] # cum sum of classes
31+
b1, b2 = np.hsplit(bins, [i]) # weights
32+
33+
# finding means and variances
34+
m1, m2 = np.sum(p1 * b1) / q1, np.sum(p2 * b2) / q2
35+
v1, v2 = np.sum(((b1 - m1) ** 2) * p1) / q1, np.sum(((b2 - m2) ** 2) * p2) / q2
36+
37+
# calculates the minimization function
38+
fn = v1 * q1 + v2 * q2
39+
if fn < fn_min:
40+
fn_min = fn
41+
thresh = i
42+
43+
# find otsu's threshold value with OpenCV function
44+
ret, otsu = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
45+
46+
print(thresh, ret)

‎ch15-图像阈值/15.THRESH_OTSU.py‎

Lines changed: 49 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,61 @@
11
# -*- coding: utf-8 -*-
2+
'''
3+
Otsu's 二值化
4+
5+
在第一 分中我们提到 retVal 当我们使用 Otsu 二值化时会用到它。 么它到底是什么呢
6+
在使用全局 值时 我们就是 便给了一个数来做 值 我们怎么知 我们 取的 个数的好坏呢?
7+
答案就是不停的尝 。
8+
如果是一副双峰图像 ,简 单来 双峰图像是指图像直方图中存在两个峰 呢 ?
9+
我们岂不是应 在两个峰 之 的峰 一个值作为阈值 。
10+
就是 Otsu 二值化 做的。
11+
简单来说,就是对一副双峰图像自动根据其直方图计算出一个阈值。
12+
对于非双峰图像 这 种方法 得到的结果可能会不理想 。
13+
14+
这里 用到的函数 是 cv2.threshold() 但是 需要多传入一个参数 flag cv2.THRESH_OTSU。
15+
这时 把 值 为 0。然后算法会找到最 优阈值 ,这 个最优 值就是 回值 retVal。
16+
如果不使用 Otsu 二值化 返回的retVal 值与 设定的 阈值相等。
17+
18+
下 的例子中 输入图像是一副带有噪声的图像。
19+
第一种方法 我们 设127 为全局 阈值。
20+
第二种方法 我们直接使用 Otsu 二值化。
21+
第三种方法 我 们 先使用一个 5x5 的 高斯核 去噪 然后再使用 Otsu 二值化。
22+
看看噪音 去除对结果的影响有多大吧。
23+
'''
24+
225
import cv2
326
import numpy as np
427
from matplotlib import pyplot as plt
528

6-
img = cv2.imread('noisy2.png',0)
29+
img = cv2.imread('noisy2.png',0)
730
# global thresholding
8-
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
31+
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
932
# Otsu's thresholding
10-
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
33+
ret2, th2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
34+
1135
# Otsu's thresholding after Gaussian filtering
1236
# 5,5 为 斯核的大小 0 为标准差
13-
blur = cv2.GaussianBlur(img,(5,5),0)
14-
#阀值一定为 0
15-
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
37+
blur = cv2.GaussianBlur(img, (5, 5), 0)
38+
# 阀值一定为 0
39+
ret3, th3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
40+
1641
# plot all the images and their histograms
1742
images = [img, 0, th1,
18-
img, 0, th2,
19-
blur, 0, th3]
20-
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
21-
'Original Noisy Image','Histogram',"Otsu's Thresholding",
22-
'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
23-
#使用了 pyplot 中画直方图的方法 plt.hist,
24-
#注意的是它的参数是一维数组
43+
img, 0, th2,
44+
blur, 0, th3]
45+
titles = ['Original Noisy Image','Histogram','Global Thresholding (v=127)',
46+
'Original Noisy Image','Histogram',"Otsu's Thresholding",
47+
'Gaussian filtered Image','Histogram',"Otsu's Thresholding"]
48+
#使用了 pyplot 中画直方图的方法 plt.hist,
49+
#注意的是它的参数是一维数组
2550
# 所以使用了 numpy ravel 方法 将多维数组 换成一维 也可以使用 flatten 方法
26-
#ndarray.flat 1-D iterator over an array.
27-
#ndarray.flatten 1-D array copy of the elements of an array in row-major order.
28-
for i in xrange(3):
29-
plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
30-
plt.title(titles[i*3]), plt.xticks([]), plt.yticks([])
31-
plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
32-
plt.title(titles[i*3+1]), plt.xticks([]), plt.yticks([])
33-
plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
34-
plt.title(titles[i*3+2]), plt.xticks([]), plt.yticks([])
35-
plt.show()
51+
# ndarray.flat 1-D iterator over an array.
52+
# ndarray.flatten 1-D array copy of the elements of an array in row-major order.
53+
54+
for i in range(3):
55+
plt.subplot(3, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray')
56+
plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([])
57+
plt.subplot(3, 3, i * 3 + 2), plt.hist(images[i * 3].ravel(), 256)
58+
plt.title(titles[i * 3 + 1]), plt.xticks([]), plt.yticks([])
59+
plt.subplot(3, 3, i * 3 + 3), plt.imshow(images[i * 3 + 2], 'gray')
60+
plt.title(titles[i * 3 + 2]), plt.xticks([]), plt.yticks([])
61+
plt.show()
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,35 @@
11
# -*- coding: utf-8 -*-
22

3+
'''
4+
自适应阈值
5+
6+
Adaptive Method- 指定 算阈值的方法。
7+
– cv2.ADPTIVE_THRESH_MEAN_C 值取自相邻区域的平均值
8+
– cv2.ADPTIVE_THRESH_GAUSSIAN_C 值取值相邻区域 的加权和 ,权重为一个高斯窗口
9+
'''
10+
311
import cv2
412
import numpy as np
513
from matplotlib import pyplot as plt
614

7-
img = cv2.imread('dave.jpg', 0)
15+
# img = cv2.imread('dave.jpg', 0)
16+
img = cv2.imread('../data/sudoku.jpg', 0)
817
# 中值滤波
918
img = cv2.medianBlur(img, 5)
1019
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
11-
# 11 为 Block size, 2 为 C 值
20+
21+
# 11 为 Block size 邻域大小 用来计算阈值的区域大小 ,
22+
# 2 为 C值,常数, 阈值就等于的平均值或者加权平均值减去这个常数。
1223
th2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)
1324
th3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
25+
1426
titles = ['Original Image', 'Global Thresholding (v = 127)',
1527
'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
1628
images = [img, th1, th2, th3]
29+
1730
for i in range(4):
1831
plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
1932
plt.title(titles[i])
2033
plt.xticks([]), plt.yticks([])
21-
plt.show()
34+
35+
plt.show()

‎ch15-图像阈值/15.threshold.py‎

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
11
# -*- coding: utf-8 -*-
2+
'''
3+
简单阈值
4+
像素值高于阈值时 我们给这个像素 赋予一个新值, 可能是白色 ,
5+
否则我们给它赋予另外一种颜色, 或是黑色 。
6+
这个函数就是 cv2.threshhold()。
7+
这个函数的第一个参数就是原图像
8+
原图像应 是灰度图。
9+
第二个参数就是用来对像素值进行分类的阈值。
10+
第三个参数 就是当像素值高于, 有时是小于 阈值时应该被赋予的新的像素值。
11+
OpenCV 提供了多种不同的阈值方法 , 是由第四个参数来决定的。
12+
些方法包括
13+
• cv2.THRESH_BINARY
14+
• cv2.THRESH_BINARY_INV • cv2.THRESH_TRUNC
15+
• cv2.THRESH_TOZERO
16+
• cv2.THRESH_TOZERO_INV
17+
'''
218

319
import cv2
420
import numpy as np
521
from matplotlib import pyplot as plt
622

7-
img=cv2.imread('gradient.png',0)
8-
ret,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
9-
ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
10-
ret,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
11-
ret,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
12-
ret,thresh5=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
23+
img = cv2.imread('grey-gradient.jpg', 0)
1324

14-
titles = ['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
25+
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
26+
ret, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
27+
ret, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
28+
ret, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
29+
ret, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
30+
31+
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
1532
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
1633

17-
for i in xrange(6):
18-
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
34+
for i in range(6):
35+
plt.subplot(2,3, i+1),plt.imshow(images[i],'gray')
1936
plt.title(titles[i])
20-
plt.xticks([]),plt.yticks([])
21-
plt.show()
37+
plt.xticks([]),plt.yticks([])
38+
plt.show()

‎ch15-图像阈值/grey-gradient.jpg‎

21 KB
Loading[フレーム]

‎ch15-图像阈值/noisy2.png‎

105 KB
Loading[フレーム]

0 commit comments

Comments
(0)

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