图像图像处理作业—全局阈值迭代法和大津阈值法+python代码

前言

最近图形图像处理课留了作业:我抽到了全局阈值迭代与大津法。本来想直接调函数,但为了能拿个高分,决定自己撸了,哎!另外,我没在网上找到现成的迭代法的python代码。

查阅

1. uint8是无符号八位整型,表示范围是[0, 255]的整数

2. i= cv2.imread('test.jpg'# 读入默认是uint8格式的numpy array

3.一般情况直接用uint8即可,若是有需求(如神经网络等),可以转换成浮点数等形式。如果需要转回PIL的图像对象,那就必须是uint8的格式。如果一直用cv2的话,也可以直接保存浮点数形式的(注意是0~255,不是0~1(不自动归一化))

正文

1、全局阈值均值迭代法:

算法很简单,不说啦,说几个代码的小问题:

1)关于Uint8,处理图像用这个类型没错,但涉及到像素运算还是float32稳妥一点。

代码:

图像图像处理作业—全局阈值迭代法和大津阈值法+python代码_第1张图片

结果:29

不难发现明显是值大于255,结果给截断了。

所以改进:

图像图像处理作业—全局阈值迭代法和大津阈值法+python代码_第2张图片

结果就正常了,哈哈。

2)cv2.threshold(),如果不写ret1会报错,提一下。

ret1, th1 = cv2.threshold(img, yvzhi, 255, cv2.THRESH_BINARY)

全局均值迭代法完整代码:

import tensorflow as tf
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm

def diedai(img):
    img_array = np.array(img).astype(np.float32)#转化成数组
    I=img_array
    zmax=np.max(I)
    zmin=np.min(I)
    tk=(zmax+zmin)/2#设置初始阈值
    #根据阈值将图像进行分割为前景和背景,分别求出两者的平均灰度  zo和zb
    b=1
    m,n=I.shape;
    while b==0:
        ifg=0
        ibg=0
        fnum=0
        bnum=0
        for i in range(1,m):
             for j in range(1,n):
                tmp=I(i,j)
                if tmp>=tk:
                    ifg=ifg+1
                    fnum=fnum+int(tmp)  #前景像素的个数以及像素值的总和
                else:
                    ibg=ibg+1
                    bnum=bnum+int(tmp)#背景像素的个数以及像素值的总和
        #计算前景和背景的平均值
        zo=int(fnum/ifg)
        zb=int(bnum/ibg)
        if tk==int((zo+zb)/2):
            b=0
        else:
            tk=int((zo+zb)/2)
    return tk

img = cv2.imread("dog.jpg")
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
img = cv2.resize(gray,(200,200))#大小
yvzhi=diedai(img)
ret1, th1 = cv2.threshold(img, yvzhi, 255, cv2.THRESH_BINARY)
print(ret1)
plt.imshow(th1,cmap=cm.gray)
plt.show()        

结果:

图像图像处理作业—全局阈值迭代法和大津阈值法+python代码_第3张图片

 2、大津阈值法完整代码(我直接看别人的,良心一点都不痛):链接  

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
img = cv2.imread("dog.jpg")
img = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
img = cv2.resize(gray,(200,200))#大小
img = np.array(img).astype(np.float32)
best_thresold=OTSU(img)
ret2, th2 = cv2.threshold(img, best_thresold, 255, cv2.THRESH_BINARY)
print(ret2)
plt.imshow(th2,cmap=cm.gray)
plt.show()  

结果(此时选取的阈值为141了):

图像图像处理作业—全局阈值迭代法和大津阈值法+python代码_第4张图片

   

你可能感兴趣的:(图像处理技术杂记)