确定图像二值化分割阈值
不受图像亮度和对比度的影响
用于图像分割过程中,自动计算出一个最佳全局阈值的算法
通过最大类间平方差的方法来区分图像前景及背景
缺点
-
对图像噪声敏感
-
只能针对单一目标分割
-
当目标和背景大小比例悬殊、类间方差函数可能呈现双峰或者多峰,效果不好
OTSU算法的核心是类间平方差
类间平方差:将图像的阈值划分为两个区域寻找这两个区域阈值间的最大方差
类间方差公式假设存在一个阈值TH将整幅图(灰度值为0~255)分为了两个部分:
- 第一部分是小于假定阈值TH的那部分。这一部分的平均灰度值为m1,这一部分在整幅图中出现的概率为P1
- 第二部分是大于假定阈值TH的那部分。这部分的平均灰度值为m2,出现的概率为P2
- MG则是全局的平均阈值
公式求解:
-
m1可以想象为从0到假定阈值TH处每个灰度值与该灰度值出现的频率的乘积再除以该区域的总频率,就是它的平均阈值
- k——假定阈值TH
- i——灰度值
- pi——每个灰度值出现的频率
- p1——0~k区域每个灰度值出现概率的总和
-
m2:
- L: 图像的像素级,通常都是255
- p2: k+1~L区域每个灰度值出现概率的总和
-
p1、p2
-
全局的平均阈值
-
类间方差表达式
import cv2
import numpy as np
img = cv2.imread("./lena.jpg",0)
h,w = img.shape
hist = [0 for i in range(256)]
for i in range(w):
for j in range(h):
hist[img.item(j,i)]+=1
ave_hist = list(map(lambda i: i/(w*h),hist))
M=0
for i in range(256):
M += i*ave_hist[i]
otsu_value = []
for i in range(256):
m1,m2,p1,p2=0,0,0,0
for v1 in range(0,i+1):
p1+=ave_hist[v1]
m1+=ave_hist[v1]*v1
if p1:
m1 /= p1
else:
m1=-1
for v2 in range(i+1,256):
p2+=ave_hist[v2]
m2+=ave_hist[v2]*v2
if p2:
m2 /= p2
else:
m2=-1
M = p1*m1+p2*m2
thes = p1*(m1-M)**2 + p2*(m2-M)**2
otsu_value.append(thes)
max_v = max(otsu_value)
idx = otsu_value.index(max_v)
print(len(ave_hist))
print("thes:",idx)
参考内容opencv 内部的函数:
ret, binary = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
https://blog.csdn.net/m0_54351828/article/details/120642025
https://blog.csdn.net/weixin_40647819/article/details/90179953
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)