opencv_python学习笔记十二
15 图像阈值
当像素高于阈值时,给这个像素一个新值(可以是白色),否则给它另一种颜色
不同的阈值方法:
cv2.THRESH_BINARY #黑白二值(二值阈值化)
cv2.THRESH_BINARY_INV #黑白二值反转(反转二值阈值化)
cv2.THRESH_TRUNC #得到的图像为多像素值(截断阈值化)
cv2.THRESH_TOZERO #阈值化到0
cv2.THRESH_TOZERO_INV #反转阈值化到0
cv2.threshold()
函数原型
def threshold(src, #原图像
thresh, #阈值
maxval, #使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值
type, #阈值类型
dst=None)#输出图像
cv2.adaptiveThreshold()
def adaptiveThreshold(src, #输入图像
maxValue, #使用 CV_THRESH_BINARY 和 CV_THRESH_BINARY_INV 的最大值
adaptiveMethod,#CV_ADAPTIVE_THRESH_MEAN_C 或CV_ADAPTIVE_THRESH_GAUSSIAN_C 自适应阈值算法
thresholdType,
#阈值类型CV_THRESH_BINARY,
CV_THRESH_BINARY_INV
blockSize, #计算阈值的象素邻域大小
C, #常数,阈值就等于平均值或加权值-常数
dst=None)#输出图像
1 简单阈值
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/11/15 16:43
# @Author : Retacn
# @Site :
简单阈值
# @File : imageThreshold.py
# @Software: PyCharm
import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
img=cv2.imread('test1.jpg',0)
ret,thresh1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
ret,thresh2=cv2.threshold(img,127,255,cv2.THRESH_BINARY_INV)
ret,thresh3=cv2.threshold(img,127,255,cv2.THRESH_TRUNC)
ret,thresh4=cv2.threshold(img,127,255,cv2.THRESH_TOZERO)
ret,thresh5=cv2.threshold(img,127,255,cv2.THRESH_TOZERO_INV)
titles=['Original Image','BINARY','BINARY_INV','TRUNC','TOZERO','TOZERO_INV']
images=[img,thresh1,thresh2,thresh3,thresh4,thresh5]
for
i
in
range(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
2自适应阈值
如果图像不同部分具有不同亮度,就会用到自适应阈值
指定阈值的方法 adaptive method
示例代码如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/11/17 8:51
# @Author : Retacn
# @Site :
自适应阈值
# @File : imageAdaptiveThreshold.py
# @Software: PyCharm
import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
img=cv2.imread("test.jpg",0)
#中值滤波
img=cv2.medianBlur(img,5)
ret,th1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#
th2=cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,11,2)
th3 = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
cv2.THRESH_BINARY,11,2)
titles=['Original Image',
'Global Thresholding (v = 127)',
'Adaptive Mean Thresholding',
'Adaptive Gaussian Thresholding']
images=[img,th1,th2,th3]
for
i
in
range(4):
plt.subplot(2,
2, i +
1), plt.imshow(images[i],
'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
3 otsu’s 二值化
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/11/17 9:49
# @Author : Retacn
# @Site :
二值化
# @File : imageOtsus.py
# @Software: PyCharm
import
cv2
import
numpy
as
np
from
matplotlib
import
pyplot
as
plt
img=cv2.imread('test.jpg',0)
#全局阈值
ret1,th1=cv2.threshold(img,127,255,cv2.THRESH_BINARY)
#二值化阈值
ret2,th2=cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#(5,5)为高斯核的大小,0为标准差
blur=cv2.GaussianBlur(img,(5,5),0)
#阈值一定要设为0
ret2,th3=cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#
images=[img,0,th1,
img,0,th2,
blur,0,th3]
titles=['Original Noisy Image','Histogram','Global
Thresholding (v=127)',
'Original Noisy Image','Histogram',"Otsu's
Thresholding",
'Gaussian filtered Image','Histogram',"Otsu's
Thresholding"]
for
i
in
range(3):
#将多个图画到一个平面上
#参数:m,n,p
#m行,n列,p为图所在位置
plt.subplot(3,3,i*3+1),\
plt.imshow(images[i*3],
'gray')
#titie标题
#xtick是x轴刻度
#xticklabel是x轴刻度值
plt.title(titles[i*3]),
\
plt.xticks([]),\
plt.yticks([])
#将多个图像画到平面上
plt.subplot(3,3,i*3+2),plt.hist(images[i*3].ravel(),256)
plt.title(titles[i*3+1]),
plt.xticks([]), plt.yticks([])
#将多个图像画到平面上
plt.subplot(3,3,i*3+3),plt.imshow(images[i*3+2],'gray')
plt.title(titles[i*3+2]),
plt.xticks([]), plt.yticks([])
plt.show()
4 otsu’s二值化的工作原理
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/11/17 10:27
# @Author : Retacn
# @Site :
二值化是如何工作的
# @File : imageOtsus2.py
# @Software: PyCharm
import
cv2
import
numpy
as
np
img = cv2.imread("test.jpg",
0)
blur = cv2.GaussianBlur(img, (5,
5),
0)
#
计算归一化直方图
hist = cv2.calcHist([blur], [0],
None, [256],
[0,
256])
hist_norm = hist.ravel() / hist.max()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1
for
i
in
range(1,
256):
p1, p2 = np.hsplit(hist_norm, [i])
q1, q2 = Q[i], Q[255]
- Q[i]
b1, b2 = np.hsplit(bins, [i])
#print(q1,q2)
m1, m2 = np.sum(p1 * b1) / q1, np.sum(p2 * b2) / q2
v1, v2 = np.sum(((b1 - m1) **
2) * p1) / q1, np.sum(((b2 - m2) **
2) * p2) / q2
fn = v1 * q1 + v2 * q2
if
fn < fn_min:
fn_min = fn
thresh = i
ret, otsu = cv2.threshold(blur,
0,
255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(thresh, ret)