Skip to content

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)
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()
21 KB
Loading

ch15-图像阈值/noisy2.png

105 KB
Loading

0 commit comments

Comments
 (0)