一、二值图像
其实就是把图像转换为只有黑白的两种颜色图像,即像素值非零即一
三角阈值二值化
对一个图像进行操作,获取图像的直方图,找到波峰和波谷进行连线设为线段A,每个点做有关线段A的垂线垂足在线段A上,最后将所有的垂足的横坐标累加再加上一个偏量位移得到的值也就是图像的阈值,通过这个阈值对整个图像进行二值化操作。
二、图像二值化的方法
1、全局阈值
OTSU:内方差最小,外方差最大(常用)
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)print("threshold value is:%s"%ret)cv2.imshow("OTSU",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
Triangle
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,0,255,cv2.THRESH_BINARY|cv2.THRESH_TRIANGLE)print("threshold value is:%s"%ret)cv2.imshow("TRIANGLE",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
自动与手动设置阈值
①THRESH_BINARY
手动设置阈值为127,像素值小于127为0黑色,大于127为255白色
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)print("threshold value is:%s"%ret)cv2.imshow("binary",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
②THRESH_BINARY_INV
手动设置阈值为127,取反效果,像素值小于127为255白色,大于127为0黑色
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)print("threshold value is:%s"%ret)cv2.imshow("binary",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
③THRESH_TRUNC
手动设置阈值为127,截断,像素值大于127为127,小于127为0黑色
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC)print("threshold value is:%s"%ret)cv2.imshow("TRUNC",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
④THRESH_TOZERO
手动设置阈值为127,截断,像素值小于127为0黑色,大于127像素值不变
import cv2
import numpy as np
from matplotlib import pyplot as pltdef threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)ret,binary = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO)print("threshold value is:%s"%ret)cv2.imshow("TOZERO",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
2、局部阈值
Ⅰ局部自适应阈值方法
①THRESH_MEAN_C
MEAN_C:将图片分为若干个小方格,求出每一个方格中像素的均值,判断均值是否大于自定义的阈值,大于阈值为白色,小于阈值为黑色
adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)
gray必须为灰度图
255为maxValue
25为blockSize,必须是奇数
10为C,是一个常量,每个像素块的均值与计算出来的均值差不能大于10,否则视为无效,其目的为了防止噪声的影响
import cv2
import numpy as np
from matplotlib import pyplot as pltdef local_threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)binary = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY,25,10)cv2.imshow("MEAN_C",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)local_threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
②THRESH_GAUSSIAN_C
GAUSSIAN_C:将图片分为若干个小方格,求出每一个方格中像素的均值并乘以相应的高斯权重(中间的权重更大),判断均值是否大于自定义的阈值,大于阈值为白色,小于阈值为黑色
adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,10)
gray必须为灰度图
255为maxValue
25为blockSize,必须是奇数
10为C,是一个常量,每个像素块的均值与计算出来的均值差不能大于10,否则视为无效,其目的为了防止噪声的影响
import cv2
import numpy as np
from matplotlib import pyplot as pltdef local_threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)binary = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,25,10)cv2.imshow("binary",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)
local_threshold(src)
cv2.waitKey(0)
cv2.destroyAllWindows()**
效果图如下:
Ⅱ自己计算均值然后对图像进行分割从而达到图像二值化效果
import cv2
import numpy as np
from matplotlib import pyplot as pltdef custom_threshold(image):gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)h,w = gray.shape[:2]m = np.reshape(gray,[1,h*w])mean = m.sum()/h*wprint("mean:",mean)ret ,binary = cv2.threshold(gray,mean,255,cv2.THRESH_BINARY)cv2.imshow("binary",binary)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\a1.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)custom_threshold(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
三、超大图像二值化
Ⅰ自动全局方法操作
思想:对超大图像进行分块二值化操作
import cv2
import numpy as np
from matplotlib import pyplot as pltdef big_image_binary(image):print(image.shape)cw = 256ch = 256h,w = image.shape[:2]gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)for row in range(0,h,ch):for col in range(0,w,cw):roi = gray[row:row+ch,col:col+cw]ret,dst = cv2.threshold(roi,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)gray[row:row+ch,col:col+cw] = dstprint(np.std(dst),np.mean(dst))cv2.imwrite(r"G:\Juptyer_workspace\study\opencv\opencv3\big1.jpg",gray)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\big.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)
big_image_binary(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
对图像噪声进行过滤之后进行全局二值化操作
import cv2
import numpy as np
from matplotlib import pyplot as pltdef big_image_binary(image):print(image.shape)cw = 256ch = 256h,w = image.shape[:2]gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)for row in range(0,h,ch):for col in range(0,w,cw):roi = gray[row:row+ch,col:col+cw]print(np.std(roi),np.mean(roi))dev = np.std(roi)if dev < 15:gray[row:row+ch,col:col+cw] = 255else :ret,dst = cv2.threshold(roi,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)gray[row:row+ch,col:col+cw] = dstcv2.imwrite(r"G:\Juptyer_workspace\study\opencv\opencv3\big3.jpg",gray)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\big.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)
big_image_binary(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下:
Ⅱ自适应局部方法操作
import cv2
import numpy as np
from matplotlib import pyplot as pltdef big_image_binary(image):print(image.shape)cw = 256ch = 256h,w = image.shape[:2]gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)for row in range(0,h,ch):for col in range(0,w,cw):roi = gray[row:row+ch,col:col+cw]dst = cv2.adaptiveThreshold(roi,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,127,20)gray[row:row+ch,col:col+cw] = dstprint(np.std(dst),np.mean(dst))cv2.imwrite(r"G:\Juptyer_workspace\study\opencv\opencv3\big2.jpg",gray)src = cv2.imread(r"G:\Juptyer_workspace\study\opencv\opencv3\big.jpg")
cv2.imshow("image",src)
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)
big_image_binary(src)cv2.waitKey(0)
cv2.destroyAllWindows()
效果图如下: