二值化操作
对图像需要一些处理,每次都要查看才能写出来,所以将看到的东西做了一下总结。二值化篇
固定阈值二值化:
ret, dst = cv2.threshold(src, thresh, maxval, type)
src:输入的图片(灰度图)
thresh:阈值
maxval:图像中的像素和阈值相比较之后,所赋予的值
type:二值化操作的类型,主要有五类: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
原理如下:
def threshold_demo(image):
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret , binary = cv.threshold(gray,127,255,cv.THRESH_BINARY)
print('threshold_value is:',ret)
cv.imshow('threshold_demo',binary)
效果:
自适应阈值:
固定阈值是选择上述五类中的类别的一个,自适应阈值就是将多个阈值结合起来,自适应计算合适的阈值。
比如:
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
结合cv.THRESH_OTSU,写成cv.THRESH_BINARY | cv.THRESH_OTSU。第二个参数可以设置为任何值,不影响效果,都是自适应阈值。
效果:
局部阈值
局部阈值二值化函数根据图片一小块区域的值来计算对应区域的阈值,从而得到也许更为合适的图片。
dst = cv2.adaptiveThreshold(src, maxval, adaptiveMethod, type, Block Size, C)
src:输入图片
thresh:阈值
maxval:图像中的像素和阈值相比较之后,所赋予的值
type:二值化操作的类型,主要有五类: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
adaptiveMethod: 阈值的计算方法,包含以下2种类型:平均(ADAPTIVE_THRESH_MEAN_C)和高斯 (ADAPTIVE_THRESH_GAUSSIAN_C.)
Block Size: 图片中分块的大小(必须是奇数且大于1,比如3,5,7… )
C :阈值计算方法中的常数项(表示从平均值或加权平均值中减去的数。 通常情况下,这是正值,但也可能为零或负值)
补:在使用平均和高斯两种算法情况下,通过计算每个像素周围blockSize x blockSize大小像素块的加权均值并减去常量C即可得到自适应阈值。如果使用平均的方法,则所有像素周围的权值相同;
如果使用高斯的方法,则每个像素周围像素的权值则根据其到中心点的距离通过高斯方程得到。
平均效果:
c=cv2.cvtColor(c,cv2.COLOR_RGB2GRAY)
c = cv2.resize(c, (600, 600))
dst = cv2.adaptiveThreshold(c,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
cv2.imshow("original",c)
cv2.imshow("guding yuzhi",dst)
高斯效果:
c=cv2.cvtColor(c,cv2.COLOR_RGB2GRAY)
c = cv2.resize(c, (600, 600))
dst = cv2.adaptiveThreshold(c,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,10)
cv2.imshow("original",c)
cv2.imshow("guding yuzhi",dst)
基于直方图的二值化:
Otsu’s Binarization是一种基于直方图的二值化方法,它需要和threshold函数配合使用。
Otsu过程:
- 计算图像直方图;
- 设定一阈值,把直方图强度大于阈值的像素分成一组,把小于阈值的像素分成另外一组;
- 分别计算两组内的偏移数,并把偏移数相加;
- 把0~255依照顺序多为阈值,重复1-3的步骤,直到得到最小偏移数,其所对应的值即为结果阈值。
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('noisy2.png',0)
# global thresholding
ret1,th1 = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
# Otsu's thresholding
ret2,th2 = cv2.threshold(img,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# plot all the images and their histograms
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 xrange(3):
plt.subplot(3,3,i*3+1),plt.imshow(images[i*3],'gray')
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()
效果:
自定义阈值
自定义阈值其实是固定阈值的一种,通过计算得到一个阈值,来进行二值化。
= cv2.cvtColor(c, cv2.COLOR_RGB2GRAY)
c = cv2.resize(c, (600, 600))
h, w = c.shape[:2]
m = np.reshape(c, [1, w * h])#将gray的图像(h*w)转化为[1行,w*h列]的数组
mean = m.sum() / (w * h)
ret, binary = cv2.threshold(c, mean, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("original", c)
cv2.imshow("guding yuzhi", binary)