Opencv之Otsu阈值处理(Python)

学习资料参考:

张平.《OpenCV算法精解:基于Python与C++》.[Z].北京.电子工业出版社.2017.

前言

在对图像进行阈值分割之时,所选取的分割阈值应使前景区域的平均灰度、背景区域的平均灰度与整幅图像的平均灰度之间的差异最大,这种差异用区域的方差来表示。

原理详解

假设输入图像为Opencv之Otsu阈值处理(Python),高为Opencv之Otsu阈值处理(Python)、宽为Opencv之Otsu阈值处理(Python),Opencv之Otsu阈值处理(Python)代表归一化的图像的灰度直方图,Opencv之Otsu阈值处理(Python)代表灰度值等于Opencv之Otsu阈值处理(Python)的像素点个数在图像中所占的比率,其中k在0到255的范围。

实现步骤

  1. 计算灰度直方图的累加直方图

  2. 计算灰度直方图的一阶累积距

  3. 计算图像Opencv之Otsu阈值处理(Python)总体的灰度平均值mean

  4. 将每一个灰度级作为阈值时,前景区域的平均灰度、背景区域的平均灰度与整幅图像的平均灰度的方差。

  5. 找到最大的方差,其中该方差对应的k就是Otsu选取的阈值。

Python实现

import numpy as np
import cv2
import math

image = cv2.imread(r"C:\Users\1\Pictures\test.jpg", 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)


运行结果
原图

处理后的图像

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2022年5月10日
下一篇 2022年5月10日

相关推荐