图像识别-OSTU阈值分割

2022/3/7 23:18:14

本文主要是介绍图像识别-OSTU阈值分割,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

原理方面,其他网友已经讲得很详细了,这里补充下python代码
https://blog.csdn.net/liyuanbhu/article/details/49387483

点击查看代码
import cv2
import numpy as np
import matplotlib.pyplot as plt

# ICV=PA∗(MA−M)2+PB∗(MB−M)2
# 每一个阈值将整个直方图分割成两部分
# 两部分各自的平均值成为 MA 和 MB
# A 部分里的像素数占总像素数的比例记作 PA,B部分里的像素数占总像素数的比例记作 PB。
# 整体图片的灰度值的均值为 M。
img = cv2.imread('ostu.jpg', 0)
# flatten() 将数组变成一维
hist, bins = np.histogram(img.flatten(), 256, [0, 256])
# 计算累积分布图
cdf = hist.cumsum()

cdf_normalized = cdf * hist.max() / cdf.max()
# 可以看下直方图
# plt.plot(cdf_normalized, color='b')
# plt.hist(img.flatten(), 256, [0, 256], color='r')
# plt.xlim([0, 256])
# plt.legend(('cdf', 'histogram'), loc='upper left')
# plt.show()

M = img.flatten().mean()
print(M)
n = img.flatten()
print(n.shape)

M = n.mean()
print(n.min(), n.max(), M)

# 手工实现OSTU
ICV = 0
Threshold = 0
for t in np.linspace(n.min(), n.max() - 1):
    # print(t)
    filter_arr = n > t
    newarr = n[filter_arr]
    PA = len(newarr) / len(n)
    MA = newarr.mean()
    filter_arr = n <= t
    newarr = n[filter_arr]
    PB = len(newarr) / len(n)
    MB = newarr.mean()
    # print(PA, MA, PB, MB)

    I = PA * (MA - M) ** 2 + PB * (MB - M) ** 2
    if I > ICV:
        ICV = I
        Threshold = t

# cv2的实现
ret, otsu = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print(Threshold, ret)

ret, img2 = cv2.threshold(img, Threshold, 255, cv2.THRESH_BINARY)
plt.subplot(1, 2, 1)
plt.imshow(img, 'gray')
plt.xticks([]), plt.yticks([])

plt.subplot(1, 2, 2)
plt.imshow(img2, 'gray')
plt.xticks([]), plt.yticks([])
plt.show()




这篇关于图像识别-OSTU阈值分割的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程