人像的一些算法和技巧

2024/06/24 algorithm 共 2811 字,约 9 分钟
闷骚的程序员

人像的一些算法和技巧

滤波磨皮

均值滤波

import cv2
# 读取图像
image = cv2.imread('path_to_your_image.jpg')
# 均值滤波
kernel_size = (5, 5)
mean_filtered_image = cv2.blur(image, kernel_size)

使用周围的像素值做平均,kernel_size控制使用多大范围的周围像素

高斯滤波

import cv2
# 读取图像
image = cv2.imread('path_to_your_image.jpg')
# 高斯滤波
kernel_size = (5, 5)
sigma = 1.5
gaussian_filtered_image = cv2.GaussianBlur(image, kernel_size, sigma)

使用周围的像素来平均,但是不同距离的像素权重不同。kernel_size控制使用多大范围的周围像素,sigma高斯函数的标准差

双边滤波

import cv2
# 读取图像
image = cv2.imread('path_to_your_image.jpg')
# 双边滤波
d = 9
sigma_color = 75
sigma_space = 75
bilateral_filtered_image = cv2.bilateralFilter(image, d, sigma_color, sigma_space)

d 滤波器在每个方向上的直径。如果设置为负值,函数会自动计算一个合适的值
sigma_color 颜色空间的滤波器 sigma 值。该值越大,颜色的容差度越高,导致更多的颜色被认为是相似的,导致更多的平滑
sigma_space 坐标空间的滤波器 sigma 值。该值越大,空间距离的权重衰减得越慢,导致更强的平滑效果

总结

均值滤波:适合快速平滑和去噪,但会模糊边缘和细节。
高斯滤波:适合去除高斯噪声,保留边缘效果比均值滤波好,但仍会模糊细节。
双边滤波:适合在保留边缘的同时进行平滑,效果最好但计算量较大,参数较多需要细致调优。

填充

给一个图像的掩膜,需要进行操作的地方赋值255,其他地方赋值0,就是一个图像的掩膜,将下图脏的地方通过模型识别生成掩膜,利用opencv的填充算法修复图像
inpaint

# dst = cv2.inpaint(src,mask, inpaintRadius,flags)
import numpy as np
from matplotlib import pyplot as plt
import cv2
img = cv2.imread('OpenCV_Logo_B.png')     # input
mask = cv2.imread('OpenCV_Logo_C.png',0)  # mask
dst_TELEA = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA)
dst_NS = cv2.inpaint(img,mask,3,cv2.INPAINT_NS)
plt.subplot(221), plt.imshow(img)
plt.title('degraded image')
plt.subplot(222), plt.imshow(mask, 'gray')
plt.title('mask image')
plt.subplot(223), plt.imshow(dst_TELEA)
plt.title('TELEA')
plt.subplot(224), plt.imshow(dst_NS)
plt.title('NS')
plt.tight_layout()
plt.show()

参数是:
src:输入8位1通道或3通道图像。
inpaintMask:修复掩码,8位1通道图像。非零像素表示需要修复的区域。
dst:输出与src具有相同大小和类型的图像。
inpaintRadius:算法考虑的每个点的圆形邻域的半径。
flags:
INPAINT_NS基于Navier-Stokes的方法
Alexandru Telea的INPAINT_TELEA方法

融合

将一张图像一部分融合到另外一个图上,可以使用掩膜加高斯模糊的方式来

# image1原始图  imag2处理后的图  mask是高斯模糊后的掩膜,注意要是三通道的掩膜
def image_fuse(imag1,imag2,mask):
    if isinstance(imag1, str): 
        imag1 = cv2.imread(imag1)
    if isinstance(imag2, str): 
        imag2 = cv2.imread(imag2)
    if isinstance(mask, str): 
        mask  = cv2.imread(mask)
    # 高斯模糊掩膜
    blurred_mask = cv2.GaussianBlur(mask, (11, 11), 33)
    # 把模糊后的高斯掩膜做归一化当作权值
    normalized_mask = blurred_mask/255
    # 将原始图和目标图做融合
    dest = normalized_mask * imag2 + imag1 * (1 - normalized_mask)
    dest = cv2.convertScaleAbs(dest)
    return dest

美白/提亮/锐度增加

    image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    pil_image = Image.fromarray(image_rgb)
    # # 亮度因子(1-1.5)
    enhancer = ImageEnhance.Brightness(pil_image)
    enhanced_image = enhancer.enhance(1.1) 
    # 增加白度
    contrast_enhancer = ImageEnhance.Contrast(enhanced_image)
    enhanced_image = contrast_enhancer.enhance(1.2)  # 调整对比度因子(1-1.5)
    # # 增加锐度
    sharpness_enhancer = ImageEnhance.Sharpness(enhanced_image)
    enhanced_image = sharpness_enhancer.enhance(1.5)  # 调整锐度因子(1-2)
    enhanced_image_np = np.array(enhanced_image)
    enhanced_image_bgr = cv2.cvtColor(enhanced_image_np, cv2.COLOR_RGB2BGR)

整体解决方案

一般做出去除黑眼圈/去皱纹/去痘痘的效果可以先用模型识别/分割生成操作掩膜,然后使用上面的方式组合,例如祛痘效果可以使用目标检测模型生成矩形框然后利用填充算法填充,但是填充算法会带来填充边界,可以接着对填充好的图使用双边滤波产生磨皮的效果,但是磨皮后图像的纹理细节会丢失,我们的目的就是祛痘,这时候可以再结合融合中的方式,只取磨皮后的图像掩膜内区域其他地方取原图,这样痘痘就去掉了。
完整代码
inpaint
inpaint

文档信息

Search

    Table of Contents