【Python】图像分割 传统方法

临时学的,记录一下代码,基于python numpy 实现

  • 直方图双峰法:

Prewitt 等人于六十年代中期提出的直方图双峰法(也称 mode 法) 是典型的全局单阈值分割方法。该方法的基本思想是:假设图像中有明显的目标和背景,则其灰度直方图呈双峰分布,当灰度级直方图具有双峰特性时,选取两峰之间的谷对应的灰度级作为阈值。如果背景的灰度值在整个图像中可以合理地看作为恒定,而且所有物体与背景都具有几乎相同的对比度,那么,选择一个正确的、固定的全局阈值会有较好的效果.算法实现:找到第一个峰值和第二个峰值,再找到第一和第二个峰值之间的谷值,谷值就是那个阀值了。

import numpy as np

# 用于平滑灰度直方图
def smooth1d(line, k_size=11, n=1):
    for i in range(n):
        line = np.convolve(line, np.ones((k_size,))/k_size, mode='same')
    return line

# 寻找峰值,ignore用于忽略部分像素,多峰情况
def findPeak(line, ignore=100):
    peak = []
    trough = []
    for i in range(ignore, len(line) - 1):
        if line[i] == 0:
            continue
        if line[i] > 0 and line[i+1] < 0:
            peak.append(i)
        elif line[i] < 0 and line[i+1] > 0:
            trough.append(i)

    return np.array(peak), np.array(trough)

def twoMode(img_gray):
    hist, bins = np.histogram(img_gray.ravel(), bins=256, range=(0, 256))
    hist = smooth1d(hist, n=3)
    s = np.sign(np.diff(np.insert(hist, 0, values=0)))
    peak, trough = findPeak(s)
    peak = peak[np.argsort(hist[peak])[-2:]]
    trough = np.clip(trough, a_min=np.min(peak), a_max=np.max(peak))
    trough = trough[np.argmin(hist[trough])]

    print('2-mode:', trough)

    return trough
  • 迭代阈值图像分割:

1.统计图像灰度直方图,求出图象的最大灰度值和最小灰度值,分别记为ZMAX和ZMIN,令初始阈值T0=(ZMAX+ZMIN)/2;
2. 根据阈值TK将图象分割为前景和背景,计算小于TO所有灰度的均值ZO,和大于TO的所有灰度的均值ZB。
3. 求出新阈值TK+1=(ZO+ZB)/2;
4. 若TK==TK+1,则所得即为阈值;否则转2,迭代计算。

import numpy as np

def iterThresh(img_gray):
    zmax = np.max(img_gray)
    zmin = np.min(img_gray)
    ith_old = 0
    ith_new = (zmax + zmin) / 2
    while ith_old != ith_new + 1:
        zo = np.mean(img_gray[np.where(img_gray > ith_new)])
        zb = np.mean(img_gray[np.where(img_gray < ith_new)])
        ith_old = ith_new
        ith_new = (zo + zb) / 2

    print('iter th:', ith_new)

    return ith_new

Reference:

[1] 图像分割 传统方法 整理

猜你喜欢

转载自blog.csdn.net/u013347145/article/details/108127885
今日推荐