opencv+python3图像增强之Sauvola二值化

       sauvola是一种考虑局部均值亮度的图像二值化方法, 以局部均值为基准在根据标准差做些微调.算法实现上一般用积分图方法来实现的.

步骤1 计算区域像素积分和和积分平方和

步骤2 计算标准差,标准差的计算方法为: std = sqrt((sqdiff - diff*diff / area) / (area - 1))

步骤3 sauvola二值化算法的阈值为T = mean*(1 + k*((std / 128) - 1)).

python代码如下:

def integral(img):
    '''
    计算图像的积分和平方积分
    :param img:Mat--- 输入待处理图像
    :return:integral_sum, integral_sqrt_sum:Mat--- 积分图和平方积分图
    '''
    integral_sum=np.zeros((img.shape[0],img.shape[1]),dtype=np.int32)
    integral_sqrt_sum=np.zeros((img.shape[0],img.shape[1]),dtype=np.int32)

    rows,cols=img.shape
    for r in range(rows):
        sum=0
        sqrt_sum=0
        for c in range(cols):
            sum+=img[r][c]
            sqrt_sum+=math.sqrt(img[r][c])

            if r==0:
                integral_sum[r][c]=sum
                integral_sqrt_sum[r][c]=sqrt_sum
            else:
                integral_sum[r][c]=sum+integral_sum[r-1][c]
                integral_sqrt_sum[r][c]=sqrt_sum+integral_sqrt_sum[r-1][c]

    return integral_sum, integral_sqrt_sum

def sauvola(img,k=0.1,kernerl=(31,31)):
    '''
    sauvola阈值法。
    根据当前像素点邻域内的灰度均值与标准方差来动态计算该像素点的阈值
    :param img:Mat--- 输入待处理图像
    :param k:float---修正参数,一般0>1#计算领域类半径的一半

    for row in range(rows):
        print('第{}行处理中...'.format(row))
        for col in range(cols):
            xmin=max(0,row-whalf)
            ymin=max(0,col-whalf)
            xmax=min(rows-1,row+whalf)
            ymax=min(cols-1,col+whalf)

            area=(xmax-xmin+1)*(ymax-ymin+1)
            if area<=0:
                sys.exit(1)

            if xmin==0 and ymin==0:
                diff[row,col]=integral_sum[xmax,ymax]
                sqrt_diff[row,col]=integral_sqrt_sum[xmax,ymax]
            elif xmin>0 and ymin==0:
                diff[row, col] = integral_sum[xmax, ymax]-integral_sum[xmin-1,ymax]
                sqrt_diff[row, col] = integral_sqrt_sum[xmax, ymax]-integral_sqrt_sum[xmin-1, ymax]
            elif xmin==0 and ymin>0:
                diff[row, col] = integral_sum[xmax, ymax] - integral_sum[xmax, ymax-1]
                sqrt_diff[row, col] = integral_sqrt_sum[xmax, ymax] - integral_sqrt_sum[xmax, ymax-1]
            else:
                diagsum=integral_sum[xmax, ymax]+integral_sum[xmin-1, ymin-1]
                idiagsum=integral_sum[xmax, ymin-1]+integral_sum[xmin-1, ymax]
                diff[row,col]=diagsum-idiagsum

                sqdiagsum=integral_sqrt_sum[xmax, ymax]+integral_sqrt_sum[xmin-1, ymin-1]
                sqidiagsum=integral_sqrt_sum[xmax, ymin-1]+integral_sqrt_sum[xmin-1, ymax]
                sqrt_diff[row,col]=sqdiagsum-sqidiagsum

            mean[row,col]=diff[row, col]/area
            std[row,col]=math.sqrt((sqrt_diff[row,col]-math.sqrt(diff[row,col])/area)/(area-1))
            threshold[row,col]=mean[row,col]*(1+k*((std[row,col]/128)-1))

            if img[row,col]

原图:

opencv+python3图像增强之Sauvola二值化_第1张图片

Sauvola二值化后:

opencv+python3图像增强之Sauvola二值化_第2张图片

你可能感兴趣的:(opencv)