一、二值图像

其实就是把图像转换为只有黑白的两种颜色图像,即像素值非零即一

三角阈值二值化

对一个图像进行操作,获取图像的直方图,找到波峰和波谷进行连线设为线段A,每个点做有关线段A的垂线垂足在线段A上,最后将所有的垂足的横坐标累加再加上一个偏量位移得到的值也就是图像的阈值,通过这个阈值对整个图像进行二值化操作。

二、图像二值化的方法

1、全局阈值

OTSU:内方差最小,外方差最大(常用)
import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_OpenCV


java 图像二值化阀值计算 图像二值化处理方法_OpenCV_02

Triangle
import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_03

java 图像二值化阀值计算 图像二值化处理方法_OpenCV_04

自动与手动设置阈值

THRESH_BINARY手动设置阈值为127,像素值小于127为0黑色,大于127为255白色

import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_05


java 图像二值化阀值计算 图像二值化处理方法_二值化_06


THRESH_BINARY_INV手动设置阈值为127,取反效果,像素值小于127为255白色,大于127为0黑色

import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_二值化_07


java 图像二值化阀值计算 图像二值化处理方法_jupyter_08


THRESH_TRUNC手动设置阈值为127,截断,像素值大于127为127,小于127为0黑色

import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_python_09


java 图像二值化阀值计算 图像二值化处理方法_OpenCV_10


THRESH_TOZERO手动设置阈值为127,截断,像素值小于127为0黑色,大于127像素值不变

import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_二值化_11

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_12

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 plt


def 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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_13

②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 plt


def 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()**

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_python_14

Ⅱ自己计算均值然后对图像进行分割从而达到图像二值化效果
import cv2
import numpy as np
from matplotlib import pyplot as plt


def 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*w
    print("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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_15


java 图像二值化阀值计算 图像二值化处理方法_jupyter_16

三、超大图像二值化

Ⅰ自动全局方法操作

思想:对超大图像进行分块二值化操作

import cv2
import numpy as np
from matplotlib import pyplot as plt


def big_image_binary(image):
    print(image.shape)
    cw = 256
    ch = 256
    h,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] = dst
            print(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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_17


java 图像二值化阀值计算 图像二值化处理方法_OpenCV_18


java 图像二值化阀值计算 图像二值化处理方法_java 图像二值化阀值计算_19

对图像噪声进行过滤之后进行全局二值化操作

import cv2
import numpy as np
from matplotlib import pyplot as plt


def big_image_binary(image):
    print(image.shape)
    cw = 256
    ch = 256
    h,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] = 255
            else :
                ret,dst = cv2.threshold(roi,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)
                gray[row:row+ch,col:col+cw] = dst
               
    cv2.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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_二值化_20


java 图像二值化阀值计算 图像二值化处理方法_二值化_21


java 图像二值化阀值计算 图像二值化处理方法_python_22

Ⅱ自适应局部方法操作

import cv2
import numpy as np
from matplotlib import pyplot as plt


def big_image_binary(image):
    print(image.shape)
    cw = 256
    ch = 256
    h,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] = dst
            print(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()

效果图如下:

java 图像二值化阀值计算 图像二值化处理方法_二值化_23


java 图像二值化阀值计算 图像二值化处理方法_OpenCV_24


java 图像二值化阀值计算 图像二值化处理方法_OpenCV_25