快速引导滤波python-opencv

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import sys


def integral(image):
    rows,cols = image.shape
    #行积分运算
    inteImageC = np.zeros((rows,cols),np.float32)
    for r in range(rows):
        for c in range(cols):
            if c == 0:
                inteImageC[r][c] = image[r][c]
            else:
                inteImageC[r][c] = inteImageC[r][c-1] + image[r][c]
    #列积分运算
    inteImage = np.zeros(image.shape,np.float32)
    for c in range(cols):
        for r in range(rows):
            if r == 0:
                inteImage[r][c] = inteImageC[r][c]
            else:
                inteImage[r][c] = inteImage[r-1][c] + inteImageC[r][c]
    #为了在快速均值平滑使用中省去判断边界的问题
    #上边和左边进行补零
    inteImage_0 = np.zeros((rows+1,cols+1),np.float32)
    inteImage_0[1:rows+1,1:cols+1] = inteImage
    return inteImage_0
#快速均值平滑:返回数组的数据类型是浮点型,winSize = ( 高,宽 )
def fastMeanBlur(image,winSize,borderType = cv2.BORDER_DEFAULT):
    halfH = (winSize[0]-1)//8
    halfW = (winSize[1]-1)//8
    ratio = 1.0/(winSize[0]*winSize[1])
    #边缘扩充
    paddImage = cv2.copyMakeBorder(image,halfH,halfH,halfW,halfW,borderType)
    #图像积分
    paddIntegral = integral(paddImage)
    #图像的宽高
    rows,cols = image.shape
    #均值滤波后的结果
    meanBlurImage = np.zeros(image.shape,np.float32)
    r,c = 0,0
    for h in range(halfH,halfH+rows,1):
        for w in range(halfW,halfW+cols,1):
            meanBlurImage[r][c] = (paddIntegral[h+halfH+1][w+halfW+1] + paddIntegral[h-halfH][w-halfW]
                                    -paddIntegral[h+halfH+1][w-halfW]-paddIntegral[h-halfH][w+halfW+1])*ratio
            c+=1
        r+=1
        c=0
    return meanBlurImage
#导向滤波
def guidedFilter(I,p,winSize,eps):
    #输入图像的宽高
    rows,cols = I.shape
    # I 的均值平滑
    mean_I = fastMeanBlur(I,winSize,cv2.BORDER_DEFAULT)
    # p 的均值平滑
    mean_p = fastMeanBlur(p,winSize,cv2.BORDER_DEFAULT)
    # I.*p 的均值平滑
    Ip = I*p
    mean_Ip = fastMeanBlur(Ip,winSize,cv2.BORDER_DEFAULT)
    #协方差
    cov_Ip = mean_Ip - mean_I*mean_p
    mean_II = fastMeanBlur(I*I,winSize,cv2.BORDER_DEFAULT)
    #方差
    var_I = mean_II - mean_I*mean_I
    a = cov_Ip/(var_I+eps)
    b = mean_p - a*mean_I
    # 对 a 和 b进行均值平滑
    mean_a = fastMeanBlur(a,winSize,cv2.BORDER_DEFAULT)
    mean_b = fastMeanBlur(b,winSize,cv2.BORDER_DEFAULT)
    q = mean_a*I + mean_b
    return q
#主函数
if __name__ =="__main__":
    # if len(sys.argv) > 1:
    #     I = cv2.imread(sys.argv[1],cv2.CV_LOAD_IMAGE_COLOR)
    #     p = cv2.imread(sys.argv[2],cv2.CV_LOAD_IMAGE_GRAYSCALE)
    # else:
    #     print "Usge:python guidedFilter.py imageFile"
    I = cv2.imread("fog1.jpg")
    p = I
    #将图像归一化
    image_0_1 = I/255.0
    p = p/255.0
    #显示原图
    cv2.imshow("image_0_1",image_0_1)
    #导向滤波
    result = np.zeros(I.shape)
    result[:,:,0] = guidedFilter(image_0_1[:,:,0],image_0_1[:,:,0],(17,17),pow(0.2,2.0))
    result[:,:,1] = guidedFilter(image_0_1[:,:,1],image_0_1[:,:,1],(17,17),pow(0.2,2.0))
    result[:,:,2] = guidedFilter(image_0_1[:,:,2],image_0_1[:,:,2],(17,17),pow(0.2,2.0))
    cv2.imshow("guidedFilter",result)
    #保存导向滤波的结果
    result = result*255
    result[result>255] = 255
    result = np.round(result)
    result = result.astype(np.uint8)
    cv2.imwrite("guidedFilter.jpg",result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

你可能感兴趣的:(Python-opencv专栏)