Python+OpenCV基本全局阈值处理(数字图像处理-冈萨雷斯-10.3.2)

全局阈值处理方法前提:当物体和背景像素的灰度分布十分明显时,可以用适用于整个图像的单个(全局)阈值。即可使用全局阈值处理。

算法思路:
(1)输入原图,转化为灰度图;
(2)对于灰度图,为全局阈值T0选择一个初始估计值(本人选择为0~255中值127);
(3)迭代(4)(5)(6)(7)步骤,迭代次数可自行选择;
(4)用T0分割灰度图,将其分为两组像素,G1由灰度值大于T0的所有像素组成,G2由所有小于T的所有像素组成;
(5)对G1和G2的像素分别计算平均灰度值m1和m2;
(6)计算一个新的阈值:T1=1/2(m1+m2);
(7)如果T1-T0=0,则为二值图阈值,否则继续迭代。

代码如下:

import cv2 as cv
import numpy as np

# 转灰
def rgb2gray(img):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    for i in range(h):
        for j in range(w):
            img1[i,j]=0.144*img[i,j,0]+0.587*img[i,j,1]+0.299*img[i,j,2]
    return img1

# 计算新阈值
def threshold(img,T):
    h=img.shape[0]
    w=img.shape[1]
    G1=G2=0
    g1=g2=0
    for i in range (h):
        for j in range (w):
            if img[i,j]>T:
                G1+=img[i,j]
                g1+=1
            else:
                G2+=img[i,j]
                g2+=1
    m1=int(G1/g1)
    m2=int(G2/g2)   # m1,m2计算两组像素均值
    T0=int((m1+m2)/2)   # 据公式计算新的阈值
    return T0

def decide(img,T):
    h=img.shape[0]
    w=img.shape[1]
    img1=np.zeros((h,w),np.uint8)
    T0=T
    T1=threshold(img,T0)
    for k in range (100):   # 迭代次数为经验值,可据实际情况选定
        if abs(T1-T0)==0:   # 若新阈值减旧阈值差值为零,则为二值图最佳阈值
            for i in range (h):
                for j in range (w):
                    if img[i,j]>T1:
                        img1[i,j]=255
                    else:
                        img1[i,j]=0
            break
        else:
            T2=threshold(img,T1)
            T0=T1
            T1=T2   # 变量转换,保证if条件为新阈值减旧阈值
    return img1

image=cv.imread("D:/Testdata/grow.tif")
grayimage=rgb2gray(image)
thresholdimage=decide(grayimage,127)
cv.imshow("image",image)
cv.imshow("grayimage",grayimage)
cv.imshow("thresholdimage",thresholdimage)
cv.waitKey(0)
cv.destroyAllWindows()

实验结果:
Python+OpenCV基本全局阈值处理(数字图像处理-冈萨雷斯-10.3.2)_第1张图片左图为原图,右图为灰度图

Python+OpenCV基本全局阈值处理(数字图像处理-冈萨雷斯-10.3.2)_第2张图片
此图为二值图

此方法为最基本二值化图像方法,在实际应用中会从在诸多不足,但确是阈值分割的基础,需要了解掌握。

你可能感兴趣的:(基本全局阈值处理)