Surface-blur算法尝试

最近做图像处理尝试的时候发现了一个磨皮算法发现不仅可以磨皮还可以很好的进行去噪消除一些斑点的图形,于是分享在这里。

本文的参考:图像保边滤波算法集锦--Surface Blur(表面模糊滤波)算法与实现_surface blur算法-CSDN博客

 我们从surface-blur的执行方式谈一下自己的理解,实际上就是开一个窗口,对窗口中的中心像素与窗口中其他的像素值进行对比通过权重调整,使得图像中的平滑区域得到有效的平滑处理,而边缘区域的细节得以保留。也是一种保边滤波。

\mathrm{x}_{\text {out }}=\frac{\sum_{i=1}^{(2 r+1)^{2}}\left[\left(1-\frac{\left|x_{i}-x\right|}{2.5 Y}\right) x_{i}\right]}{\sum_{i=1}^{(2 r+1)^{2}}\left(1-\frac{\left|x_{i}-x\right|}{2.5 Y}\right)}

在这个公式中:

X_{out}是输出的像素值;

r是在这个公式中的邻域半径,实际上指的是在这个算法中窗口开的大小;

Y是一个阈值,这个阈值需要自己给出来,取值的范围是[0-255],这阈值我自己理解的是用来判断这个窗口中心像素是否是边缘的一个判断条件。

x是当前像素,也就是窗口的中心像素。

x_{i}是窗口中第i个像素。

公式通过计算邻域内像素值的加权平均来确定当前像素的值,\left(1-\frac{\left|x_{i}-x\right|}{2.5 Y}\right)实际上就是根据每个像素值与当前窗口中心像素值的差异来调整输出的权重。

\left|x_{i}-x\right|很大的时候\left(1-\frac{\left|x_{i}-x\right|}{2.5 Y}\right)会比较小,也就是减小当前窗口对中心像素的影响,其实这个时候中心像素值会被判断为图像的边缘,不会被过渡平滑。

\left|x_{i}-x\right|很小的时候\left(1-\frac{\left|x_{i}-x\right|}{2.5 Y}\right)会很大,会让这个像素进行平滑。

通过如上方式这个公式即实现了平滑磨皮,也实现保留边缘信息。

import cv2
import numpy as np


def surfaceblur(img, r, y):
    # 获取图片的大小,只取图片前两个维度,忽略颜色通道
    h, w = img.shape[:2]
    # 拆分图像的RGB通道
    R, G, B = cv2.split(img)

    # surface-blur function
    def surfaceblurprocess(channel):
        # 填充图像边界,r为填充的半径
        padded = np.pad(channel, [(r, r), (r, r)], 'reflect')
        output = np.zeros_like(channel, dtype=np.float32)

        # 遍历像素区
        for i in range(r, h + r):
            for j in range(r, w + r):
                neighborhood = padded[i - r:i + r + 1, j - r:j + r + 1]
                center_value = padded[i, j]
                weight = 1 - np.abs(neighborhood - center_value) / (2.5 * y)
                weighted_sum = np.sum(weight * neighborhood)
                weight_sum = np.sum(weight)
                output[i - r, j - r] = weighted_sum / weight_sum
        output = np.clip(output, 0, 255).astype(np.uint8)
        return output
    # 计算通道
    R_blurred = surfaceblurprocess(R)
    G_blurred = surfaceblurprocess(G)
    B_blurred = surfaceblurprocess(B)
    # 合并处理后的通道
    blurred_img = cv2.merge((R_blurred, G_blurred, B_blurred))

    return blurred_img

# 图片的读取PNG
img = cv2.imread('path')

# 设置参数
r1 = 1  # 邻域半径
y1 = 8  # 阈值
blurred_img1 = surfaceblur(img, r1, y1)

# 显示图像
cv2.imshow('Original Image', img)
cv2.imshow('Surface Blurred Image1', blurred_img1 )
cv2.waitKey(0)  # 等待按键按下
cv2.destroyAllWindows()  # 销毁所有窗口

原图

 磨皮后

 

可以看到对于椒盐噪声也有一些用处。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值