1
1
# -*- 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
+
2
25
import cv2
3
26
import numpy as np
4
27
from matplotlib import pyplot as plt
5
28
6
- img = cv2 .imread ('noisy2.png' ,0 )
29
+ img = cv2 .imread ('noisy2.png' ,0 )
7
30
# global thresholding
8
- ret1 ,th1 = cv2 .threshold (img ,127 ,255 ,cv2 .THRESH_BINARY )
31
+ ret1 ,th1 = cv2 .threshold (img ,127 ,255 ,cv2 .THRESH_BINARY )
9
32
# 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
+
11
35
# Otsu's thresholding after Gaussian filtering
12
36
# 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
+
16
41
# plot all the images and their histograms
17
42
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
+ #注意的是它的参数是一维数组
25
50
# 所以使用了 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 ()
0 commit comments