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 otsus 二值化

#!/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标题
    #xtickx轴刻度
    #xticklabelx轴刻度值
    
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 otsus二值化的工作原理

#!/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)

posted @ 2016-11-21 16:31  retacn_yue  阅读(184)  评论(0编辑  收藏  举报