双边滤波实现-python

双边滤波实现

原理

双边滤波的作用主要是为了保护图像的边缘信息不被滤掉;利用高斯滤波和空间滤波相乘,计算(i,j)点位置的权重。
其中,高斯滤波函数是:
G a s [ i , j ] = e − ( i 2 + j 2 ) 2 ∗ σ 2 , − r < i , j < r , r 表 示 核 的 半 径 Gas[i,j]=e^{\frac{-(i^2+j^2)}{2*\sigma^2}},-r <i,j<r,r表示核的半径 Gas[i,j]=e2σ2(i2+j2)r<i,j<r,r
对用的空间滤波器的
S p a [ i , j ] = e − ( I [ i , j ] − I [ 0 , 0 ] ) 2 2 ∗ σ 2 , − r < i , j < r , r 表 示 核 的 半 径 , I [ i , j ] 表 示 ( i , j ) 对 应 的 像 素 值 Spa[i,j]=e^{\frac{-(I[i,j]-I[0,0])^2}{2*\sigma^2}},-r <i,j<r,r表示核的半径,I[i,j]表示(i,j)对应的像素值 Spa[i,j]=e2σ2(I[i,j]I[0,0])2r<i,j<r,r,I[i,j](i,j)
由高斯核和空间滤波核相乘后进行归一化处理,然后逐一求各个像素点对应的输出值。
k e r n e l = G a s ∗ S p a kernel = Gas * Spa kernel=GasSpa
k e r n e l o u t = k e r n e l / s u m ( k e r n e l ) kernelout = kernel/sum(kernel) kernelout=kernel/sum(kernel)

代码

# -*- coding: utf-8 -*-
"""
Created on Sat Jun 27 18:21:39 2020
@author: PRCZ
"""
import numpy as np
import random
from skimage import io
import cv2
from matplotlib import pyplot as plt
#path = "D:/2_project/0_test/1.jpg"
path1 = 'D:/2_project/0_test/median_filter/anr/input/inputdc4.jpg'
I = io.imread(path1) #R*0.299+G*0.587+B*0.114
I1 = cv2.imread(path1, cv2.IMREAD_GRAYSCALE)
image = I1
def sp_noise(image,prob):
    output = np.zeros(image.shape,np.uint8)
    thres = (1 - prob)*255
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            rdn = random.randint(0,255)
            if rdn < prob*255:
                output[i][j] = 0
            elif rdn > 230:
                output[i][j] = 200
            else:
                output[i][j] = image[i][j]
    return output
    
def gaus_kernel(winsize, gsigma):
    r = int(winsize/2)
    c = r
    kernel = np.zeros((winsize, winsize))
    sigma1 = 2*gsigma*gsigma
    for i in range(-r, r+1):
        for j in range(-c, c+1):
            kernel[i+r][j+c] = np.exp(-float(float((i*i+j*j))/sigma1))
    return kernel

def bilateral_filter(image, gsigma, ssigma, winsize):
    r = int(winsize/2)
    c = r
    image1 = np.pad(image, ((r, c),(r, c)), constant_values=0)
    #image1 = sp_noise(image1, prob=0.01)
    image = image1
    row, col = image.shape    
    sigma2 = 2*ssigma*ssigma
    gkernel = gaus_kernel(winsize, gsigma)
    kernel = np.zeros((winsize, winsize))
    bilater_image = np.zeros((row, col))
    for i in range(1,row-r):
        for j in range(1,col-c):
            skernel = np.zeros((winsize, winsize))
            #print(i, j)
            for m in range(-r, r+1):
                for n in range(-c, c+1):
                    #print(m, n)
                    #if (i != 0 and j !=0 and i != r and j !=c):
                    skernel[m+r][n+c] = np.exp(-pow((image[i][j]-image[i+m][j+n]),2)/sigma2)
                   # else:
                        #skernel[m+r][n+c] = np.exp(-pow((image[i][j]),2)/sigma2) 
                    #print(skernel[m+r][n+c])
                    kernel[m+r][n+c] = skernel[m+r][n+r] * gkernel[m+r][n+r]
            sum_kernel = sum(sum(kernel))
            kernel = kernel/sum_kernel
            for m in range(-r, r+1):
                for n in range(-c, c+1):    
                    bilater_image[i][j] =  image[i+m][j+n] * kernel[m+r][n+c] + bilater_image[i][j] 
 
    return bilater_image

bilater_image = bilateral_filter(image, 10, 3, 15)
err = bilater_image - np.pad(image, ((7, 7),(7, 7)), constant_values=0)
#image1 = sp_noise(image, prob=0.01)
bilater_image1 = cv2.bilateralFilter(image, d=0, sigmaColor=10, sigmaSpace=3)
err1 = bilater_image1 - image
plt.figure()
plt.subplot(231)
plt.imshow(image)
#plt.figure()
plt.subplot(232)
plt.imshow(bilater_image)
plt.subplot(233)
plt.imshow(bilater_image1)
plt.subplot(235)
plt.imshow(bilater_image - np.pad(image, ((7, 7),(7, 7)), constant_values=0))
plt.subplot(236)
plt.imshow(err1)
path2 = 'D:/2_project/0_test/median_filter/bilater/'
io.imsave('D:/2_project/0_test/median_filter/bilater/bilater_img.jpg', bilater_image)
io.imsave('D:/2_project/0_test/median_filter/bilater/bilater_img1.jpg', bilater_image1)

示例图

butterfly

  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值