OTSU算法的原理介绍及C++和Python实现

3 篇文章 0 订阅

前言:

最近由于在做图像处理方面的工作,需要自己编写提取图像中对象边缘的算法,我目前所采用的事最简单的阈值分割算法,在此算法中最重要的一个参数就是用于分割前景和背景的阈值。刚开始做的时候阈值都是通过手动调整然后观察效果来设定的,之后再网上查阅了许多前辈的博客之后,了解了OTSU算法,可以用于自动计算最佳的分割阈值。

原理:

大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。

按图像的灰度特性,将图像分成背景和前景两部分。因方差是灰度分布均匀性的一种度量,背景和前景之间的类间方差越大,说明构成图像的两部分的差别越大,当部分前景错分为背景或部分背景错分为前景都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。

 

对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于前景的像素点数占整幅图像的比例记为ω0,其平均灰度μ0;背景像素点数占整幅图像的比例为ω1,其平均灰度为μ1。图像的总平均灰度记为μ,类间方差记为g。

假设图像的背景较暗,并且图像的大小为M×N,图像中像素的灰度值小于阈值T的像素个数记作N0,像素灰度大于阈值T的像素个数记作N1,则有:

      ω0=N0/ M×N (1)

      ω1=N1/ M×N (2)

      N0+N1=M×N (3)

      ω0+ω1=1    (4)

      μ=ω0*μ0+ω1*μ1 (5)

      g=ω0(μ0-μ)^2+ω1(μ1-μ)^2 (6)

将式(5)代入式(6),得到等价公式:

      g=ω0ω1(μ0-μ1)^2    (7) 这就是类间方差

采用遍历的方法得到使类间方差g最大的阈值T,即为所求。

C++实现:

在我制作的MFC程序中加入了OTSU算法的实现,具体代码见github

Python实现:

import numpy as np

def OTSU(img_array):            #传入的参数为ndarray形式
	height = img_array.shape[0]
	width = img_array.shape[1]
	count_pixel = np.zeros(256)

	for i in range(height):
		for j in range(width):
			count_pixel[int(img_array[i][j])] += 1 

	# fig = plt.figure()        #通过绘制直方图可以观察像素的分布情况
	# ax = fig.add_subplot(111)
	# ax.bar(np.linspace(0, 255, 256), count_pixel)
	# ax.set_xlabel("pixels")
	# ax.set_ylabel("num")
	# plt.show()

	max_variance = 0.0
	best_thresold = 0
	for thresold in range(256):
		n0 = count_pixel[:thresold].sum()
		n1 = count_pixel[thresold:].sum()
		w0 = n0 / (height * width)
		w1 = n1 / (height * width)
		u0 = 0.0
		u1 = 0.0
		
		for i in range(thresold):
			u0 += i * count_pixel[i]
		for j in range(thresold, 256):
			u1 += j * count_pixel[j]
		
		u = u0 * w0 + u1 * w1 
		tmp_var = w0 * np.power((u - u0), 2) + w1 * np.power((u - u1), 2)

		if tmp_var > max_variance:
			best_thresold = thresold
			max_variance = tmp_var

	return best_thresold

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值