跟我一块学Otsu算法

  • Ostu
    • 一.定义、原理
    • 二、优缺点
    • 三、程序

Ostu

一.定义、原理

Otsu算法:最大类间方差法(大津算法),是一种确定阈值的算法。

对于图像I(x,y),前景(即目标)和背景的分割阈值记作T,属于前景的像素点数占整幅图像的比例记为ω0,其平均灰度μ0;背景像素点数占整幅图像的比例为ω1,其平均灰度为μ1。图像的总平均灰度记为μ,类间方差记为g。
假设图像的背景较暗,并且图像的大小为M×N,图像中像素的灰度值小于阈值T的像素个数记作N0,像素灰度大于阈值T的像素个数记作N1,则有:
      (1) ω0=N0/ (M×N)
      (2) ω1=N1/ (M×N)
      (3) N0 + N1 = M×N
      (4) ω0 + ω1 = 1
      (5) μ = ω0 * μ0 + ω1 * μ1
      (6) g = ω0 * (μ0 - μ)2 + ω1 * (μ1 - μ)2
将式(5)代入式(6),得到等价公式:
      (7) g = ω0 *ω1 * (μ0 - μ1)2
采用遍历的方法得到使类间方差g最大的阈值T。

二、优缺点

优点:算法简单,当目标与背景的面积相差不大时,能够有效地对图像进行分割。
缺点:当图像中的目标与背景的面积相差很大时,表现为直方图没有明显的双峰,或者两个峰的大小相差很大,分割效果不佳,或者目标与背景的灰度有较大的重叠时也不能准确的将目标与背景分开。
原因:该方法忽略了图像的空间信息,同时将图像的灰度分布作为分割图像的依据,对噪声也相当敏感。

三、程序

opencv可以直接调用这种算法,threshold(gray, dst, 0, 255, CV_THRESH_OTSU);
import numpy as npdef otsu_threshold(im):width, height = im.sizeimg_size = width * heightpixel_counts = np.zeros(256)for x in range(width):for y in range(height):pixel = im.getpixel((x, y))pixel_counts[pixel] = pixel_counts[pixel] + 1# 得到图片的以0-255索引的像素值个数列表s_max = (0, -10)for threshold in range(256):# 遍历所有阈值# 更新n_0 = sum(pixel_counts[:threshold])  # 得到阈值以下像素个数n_1 = sum(pixel_counts[threshold:])   # 得到阈值以上像素个数w_0 = n_0 / img_sizew_1 = n_1 / img_size# 得到阈值下所有像素的平均灰度u_0 = sum([i * pixel_counts[i] for i in range(0, threshold)]) / n_0 if n_0 > 0 else 0# 得到阈值上所有像素的平均灰度u_1 = sum([i * pixel_counts[i] for i in range(threshold, 256)]) / n_1 if n_1 > 0 else 0# 总平均灰度u = w_0 * u_0 + w_1 * u_1# 类间方差g = w_0 * (u_0 - u) * (u_0 - u) + w_1 * (u_1 - u) * (u_1 - u)# 类间方差等价公式# g = w_0 * w_1 * (u_0 * u_1) * (u_0 * u_1)# 取最大的if g > s_max[1]:s_max = (threshold, g)return s_max[0]


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部