数字图像处理——图像分割:点的全局阈值、区域的全局阈值、局部阈值法、多阈值法

基于点的全局阈值选取方法:

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

img = cv2.imread('grey-gradient.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()

基于区域的全局阈值选取方法:

import numpy as np
import cv2
import math

image = cv2.imread(r"./cat/cat1.png", 0)
rows, cols = image.shape[:2]
gray_hist = np.zeros([256], np.uint64)
for i in range(rows):
    for j in range(cols):
        gray_hist[image[i][j]] += 1
uniformGrayHist = gray_hist / float(rows * cols)
# 计算零阶累积距和一阶累积距
zeroCumuMomnet = np.zeros(256, np.float32)
oneCumuMomnet = np.zeros(256, np.float32)
for k in range(256):
    if k == 0:
        zeroCumuMomnet[k] = uniformGrayHist[0]
        oneCumuMomnet[k] = (k) * uniformGrayHist[0]
    else:
        zeroCumuMomnet[k] = zeroCumuMomnet[k - 1] + uniformGrayHist[k]
        oneCumuMomnet[k] = oneCumuMomnet[k - 1] + k * uniformGrayHist[k]
# 计算类间方差
variance = np.zeros(256, np.float32)
for k in range(255):
    if zeroCumuMomnet[k] == 0 or zeroCumuMomnet[k] == 1:
        variance[k] = 0
    else:
        variance[k] = math.pow(oneCumuMomnet[255] * zeroCumuMomnet[k] - oneCumuMomnet[k], 2) / (
                    zeroCumuMomnet[k] * (1.0 - zeroCumuMomnet[k]))
# 找到阈值
threshLoc = np.where(variance[0:255] == np.max(variance[0:255]))
thresh = threshLoc[0][0]
# 阈值处理
threshold = np.copy(image)
threshold[threshold > thresh] = 255
threshold[threshold <= thresh] = 0
cv2.imshow("test", threshold)
cv2.waitKey(0)

局部阈值:

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

# img = cv2.imread('dave.jpg', 0)
img = cv2.imread('../data/sudoku.jpg', 0)
# 中值滤波
img = cv2.medianBlur(img, 5)
ret, th1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)

# 11 为 Block size 邻域大小 用来计算阈值的区域大小 ,
# 2 为 C值,常数, 阈值就等于的平均值或者加权平均值减去这个常数。
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()

多阈值法:

import cv2
import numpy as np
# 多阈值处理
def double_threshold_processing(x):   # x 为传入的图像
    hist = cv2.calcHist([x], [0], None, [256], [0, 256]) # 图像的灰度直方图  shape = (256,1)
    grayScale = np.arange(256).reshape(1, -1)     # 灰度级 [0,255]  shape =(1,256)
    sum_pixels = x.shape[0] * x.shape[1]            # 图像总共像素点的个数
    mG = x.mean()                                # 整幅图像的平均灰度
    T1,T2,varMax = 0,0,0.0        # 双阈值T1、T2,类间方差varMax
    for k1 in range(1,254):     # k1范围在1 - 253之间 1 ~ L-3
        gray_G1 = grayScale[:, :k1 + 1]               # 灰度值 0~k1 的子区域G1
        hist_G1 = hist[:k1 + 1, :]                    # 子区域G1的直方图 0~k1 ,对应每个灰度值的像素点
        sum_gray_G1 = np.dot(gray_G1, hist_G1)        # G1 区域所有像素点灰度值总和 = 灰度值 * 对应像素点的个数
        sum_pixels_G1 = sum(hist_G1)                  # G1 像素数量
        P1 = sum_pixels_G1 / sum_pixels               # G1 像素占比
        m1 = (sum_gray_G1 / sum_pixels_G1) if sum_pixels_G1 > 0 else 0    
  # G1 像素的平均灰度
        for k2 in range(k1+1,255):     # k2范围在 k1+1 ~ 254 之间 k1+1 ~ L-2
            gray_G3 = grayScale[:,k2:]             # 灰度值 k2~L-1 的子区域G3
            hist_G3 = hist[k2:,:]        # 子区域G3的直方图 k2~L-1 ,对应每个灰度值的像素点
            sum_gray_G3 = np.dot(gray_G3,hist_G3)     # G3 区域所有像素点灰度值总和 = 灰度值 * 对应像素点的个数
            sum_pixels_G3 = sum(hist_G3)              # G3 像素数量
            P3 = sum_pixels_G3 / sum_pixels           # G3 像素占比
            m3 = (sum_gray_G3 / sum_pixels_G3) if sum_pixels_G3 > 0 else 0        # G3 平均灰度
            P2 = 1.0 - P1 - P3              # G2 区域的像素占比
            m2 = ((mG - P1 * m1 - P3 * m3) / P2) if P2 > 0 else 0   # G2 平均灰度
 
            varB = P1 * (m1 - mG) ** 2 + P2 * (m2 - mG) ** 2 + P3 * (m3 - mG) ** 2  # 类间方差
            if varB > varMax:        # 保存最大的类间方差
                T1,T2,varMax = k1,k2,varB
    x[x <= T1] = 0
    x[(x>T1)&(x<T2)] = 123  # 中间的灰度,可以更改
    x[x >= T2] = 255
    return T1,T2,x
img = cv2.imread("img.tif",0)
ret1,ret2,dst = double_threshold_processing(img.copy())         # 多阈值处理
print(ret1,ret2) 
cv2.imshow('img',np.hstack((img,dst)))
cv2.waitKey()
cv2.destroyAllWindows()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值