opencv-python图像增强十五:高级滤镜实现


前言

在之前两个滤镜文章中介绍了六种简单的滤镜实现,它们大多都是由一个单独函数实现的接下来介绍五种结合了之前图像增强文章提的的算法的复合滤镜。本案例中的算法来自于文章一文章二文章三,感兴趣的小伙伴可以看看。

二、鲜食滤镜

鲜食滤镜是一种图像处理技术,旨在提升食物照片的吸引力,通过增强色彩饱和度和对比度,提高亮度并减少阴影,以及锐化处理来使食物色彩鲜艳、质感清晰;同时,它还会调整色调以增加暖意,去除背景杂色,优化食物细节,并通过调整高光和阴影来模仿新鲜食物的自然光泽,从而使食物看起来更加诱人和新鲜。
算法实现:
图像锐化增强食物对比度,图像阴影区域减弱提升暗部细节,饱和度提升提亮食物颜色
算法实现:

import cv2
import numpy as np

def shadow(input_image, light):
    # 将输入图像转换为浮点类型并归一化,便于后续处理
    f = input_image.astype(np.float32) / 255.0
    # 使用OpenCV将归一化的图像转换为灰度图
    gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)

    # 计算灰度图的平方,用以确定阴影区域
    thresh = (1.0 - gray) ** 2
    # 计算阴影区域的平均值,用作后续的阈值
    t = np.mean(thresh)
    # 创建一个掩码,标记阴影区域(高于平均值的区域)
    mask = np.where(thresh >= t, 255, 0).astype(np.uint8)
    # 设置校正参数
    max_val = 4  # 最大校正范围
    bright = light / 100.0 / max_val  # 计算校正强度
    mid = 1.0 + max_val * bright  # 计算中间值
    # 创建两个过渡矩阵,用于调整图像的亮度和对比度
    midrate = np.where(mask == 255, mid, ((mid - 1.0) / t * thresh) + 1.0)
    brightrate = np.where(mask == 255, bright, (1.0 / t * thresh) * bright)
    # 使用指数函数调整图像亮度,并通过掩码实现平滑过渡
    result = np.clip(pow(f, 1.0 / midrate[:, :, np.newaxis]), 0.0, 1.0)
    # 根据计算出的亮度率调整图像,限制值在0到1之间
    result = np.clip(result * (1.0 / (1 - brightrate[:, :, np.newaxis])), 0.0, 1.0) * 255
    # 将结果转换为8位无符号整型,以便显示和保存
    result = result.astype(np.uint8)
    return result

def Saturation(rgb_img, increment):
    # 将输入图像转换为浮点数,并归一化到0-1范围
    img = rgb_img.astype(np.float64) / 255.0
    # 计算每个像素的最小值,即HSL颜色空间中的亮度最低的部分
    img_min = img.min(axis=2)
    # 计算每个像素的最大值,即HSL颜色空间中的亮度最高的部分
    img_max = img.max(axis=2)

    # 计算饱和度(delta)和亮度(value)的中间值
    delta = (img_max - img_min)
    value = (img_max + img_min)
    # 计算HSL颜色空间中的亮度L
    L = value / 2.0

    # 根据亮度L计算饱和度s的两个可能值
    s1 = delta / (value + 1e-8)  # 防止除以0的情况,添加一个很小的数
    s2 = delta / (2 - value + 1e-8)
    # 根据亮度L选择饱和度s的正确值
    s = np.where(L < 0.5, s1, s2)

    # 计算增量调整后的饱和度,如果饱和度加上增量大于1,则保持原饱和度,否则用1减去增量
    temp = increment + s
    alpha = np.where(temp > 1, s, 1 - increment)
    # 计算调整后的alpha值
    alpha = 1 / alpha - 1

    # 对RGB图像的每个通道进行调整,以改变饱和度
    for i in range(3):
        img[:, :, i] += (img[:, :, i] - L) * alpha
    # 确保调整后的RGB值在0到1之间,如果超出这个范围,则将其限制在这个范围内
    img = np.clip(img, 0, 1)

    # 返回调整后的图像
    return img


def laplacian_sharpening(image, kernel_size=3, scale=0.03, delta=0):
    """
    Apply Laplacian sharpening to an image.

    Parameters:
    image: The input image in BGR format.
    kernel_size: The size of the Laplacian kernel (must be 1, 3, 5, or 7).
    scale: The optional scale factor for the computed Laplacian values.
    delta: The optional delta value added to the results prior to storing them.

    Returns:
    The sharpened image.
    """
    # Check if kernel size is valid
    if kernel_size not in [1, 3, 5, 7]:
        raise ValueError("Kernel size must be 1, 3, 5, or 7.")

    # Convert the image to grayscale
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Compute the Laplacian of the image
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F, ksize=kernel_size, scale=scale, delta=delta)

    # Convert Laplacian image to 8-bit
    laplacian_8u = cv2.convertScaleAbs(laplacian)

    # Convert the 8-bit Laplacian image to BGR
    laplacian_8u_bgr = cv2.cvtColor(laplacian_8u, cv2.COLOR_GRAY2BGR)

    # Add the Laplacian image to the original image
    sharpened_image = cv2.addWeighted(image, 1, laplacian_8u_bgr, 1.5, 0)

    return sharpened_image

img = cv2.imread(r"D:\AI_tool\GFPGAN-master\1.jpg")
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
lap=laplacian_sharpening(img)
shd=shadow(lap,-10)
sat=Saturation(shd,0.3)
cv2.imshow("img",img)
cv2.imshow("sat",sat)

cv2.waitKey(0)

原图:
在这里插入图片描述
效果:
在这里插入图片描述

三、巧克力滤镜

巧克力滤镜是一种图像处理效果,它通过增加棕色调、降低亮度并轻微增加对比度,使照片呈现出类似巧克力的温暖和浓郁感,常用于增强食物、饮品以及某些场景的视觉效果,使其显得更加诱人和舒适。
算法实现:
首先增强巧克力对比度与亮度,在对增强后的图像进行锐化以及阴影处理,最后提升巧克力颜色的饱和度让其更有食欲:

import cv2
import numpy as np

def shadow(input_image, light):
    # 将输入图像转换为浮点类型并归一化,便于后续处理
    f = input_image.astype(np.float32) / 255.0
    # 使用OpenCV将归一化的图像转换为灰度图
    gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)

    # 计算灰度图的平方,用以确定阴影区域
    thresh = (1.0 - gray) ** 2
    # 计算阴影区域的平均值,用作后续的阈值
    t = np.mean(thresh)
    # 创建一个掩码,标记阴影区域(高于平均值的区域)
    mask = np.where(thresh >= t, 255, 0).astype(np.uint8)
    # 设置校正参数
    max_val = 4  # 最大校正范围
    bright = light / 100.0 / max_val  # 计算校正强度
    mid = 1.0 + max_val * bright  # 计算中间值
    # 创建两个过渡矩阵,用于调整图像的亮度和对比度
    midrate = np.where(mask == 255, mid, ((mid - 1.0) / t * thresh) + 1.0)
    brightrate = np.where(mask == 255, bright, (1.0 / t * thresh) * bright)
    # 使用指数函数调整图像亮度,并通过掩码实现平滑过渡
    result = np.clip(pow(f, 1.0 / midrate[:, :, np.newaxis]), 0.0, 1.0)
    # 根据计算出的亮度率调整图像,限制值在0到1之间
    result = np.clip(result * (1.0 / (1 - brightrate[:, :, np.newaxis])), 0.0, 1.0) * 255
    # 将结果转换为8位无符号整型,以便显示和保存
    result = result.astype(np.uint8)
    return result

def Saturation(rgb_img, increment):
    # 将输入图像转换为浮点数,并归一化到0-1范围
    img = rgb_img.astype(np.float64) / 255.0
    # 计算每个像素的最小值,即HSL颜色空间中的亮度最低的部分
    img_min = img.min(axis=2)
    # 计算每个像素的最大值,即HSL颜色空间中的亮度最高的部分
    img_max = img.max(axis=2)

    # 计算饱和度(delta)和亮度(value)的中间值
    delta = (img_max - img_min)
    value = (img_max + img_min)
    # 计算HSL颜色空间中的亮度L
    L = value / 2.0

    # 根据亮度L计算饱和度s的两个可能值
    s1 = delta / (value + 1e-8)  # 防止除以0的情况,添加一个很小的数
    s2 = delta / (2 - value + 1e-8)
    # 根据亮度L选择饱和度s的正确值
    s = np.where(L < 0.5, s1, s2)

    # 计算增量调整后的饱和度,如果饱和度加上增量大于1,则保持原饱和度,否则用1减去增量
    temp = increment + s
    alpha = np.where(temp > 1, s, 1 - increment)
    # 计算调整后的alpha值
    alpha = 1 / alpha - 1

    # 对RGB图像的每个通道进行调整,以改变饱和度
    for i in range(3):
        img[:, :, i] += (img[:, :, i] - L) * alpha
    # 确保调整后的RGB值在0到1之间,如果超出这个范围,则将其限制在这个范围内
    img = np.clip(img, 0, 1)

    # 返回调整后的图像
    return img


def laplacian_sharpening(image, kernel_size=3, scale=0.01, delta=0):
    """
    Apply Laplacian sharpening to an image.

    Parameters:
    image: The input image in BGR format.
    kernel_size: The size of the Laplacian kernel (must be 1, 3, 5, or 7).
    scale: The optional scale factor for the computed Laplacian values.
    delta: The optional delta value added to the results prior to storing them.

    Returns:
    The sharpened image.
    """
    # Check if kernel size is valid
    if kernel_size not in [1, 3, 5, 7]:
        raise ValueError("Kernel size must be 1, 3, 5, or 7.")

    # Convert the image to grayscale
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Compute the Laplacian of the image
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F, ksize=kernel_size, scale=scale, delta=delta)

    # Convert Laplacian image to 8-bit
    laplacian_8u = cv2.convertScaleAbs(laplacian)
    # Convert the 8-bit Laplacian image to BGR
    laplacian_8u_bgr = cv2.cvtColor(laplacian_8u, cv2.COLOR_GRAY2BGR)
    # Add the Laplacian image to the original image
    sharpened_image = cv2.addWeighted(image, 1, laplacian_8u_bgr, 1.5, 0)
    return sharpened_image
img = cv2.imread(r"D:\AI_tool\GFPGAN-master\2.jpg")
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
abs = cv2.convertScaleAbs(img, alpha=1.3, beta=10)
lap=laplacian_sharpening(abs)
shd=shadow(lap,-20)
sat=Saturation(shd,0.3)
cv2.imshow("img",img)
cv2.imshow("sat",sat)

cv2.waitKey(0)

效果:
在这里插入图片描述
在这里插入图片描述

三,冷艳滤镜:

人物冷艳滤镜是一种图像处理效果,它通过降低色调的温度,增加蓝色的分量,同时减少红色和绿色,使得人物肤色和整体画面呈现出一种冷静、高傲的美感。这种滤镜通常用于肖像摄影,能够营造出一种距离感、神秘感和高级感,让人物显得更加清冷、优雅,适合表现人物的独特气质和深邃眼神。
算法实现:
先调节色温让颜色偏冷,在对人物进行锐化与对比度增强提升人像细节,降低图像阴影并修正人物颜色

import cv2
import numpy as np


def create_lut(level):
    # 创建一个查找表(LUT),范围从0到255
    lut = np.arange(256, dtype=np.uint8)
    # 更复杂的颜色映射,这里使用简单的线性映射作为示例
    # 实际上,可以在这里使用更复杂的非线性映射
    for i in range(256):
        if i + level > 255:
            lut[i] = 255
        elif i + level < 0:
            lut[i] = 0
        else:
            lut[i] = i + level
    return lut


def apply_lut(image, lut):
    # 使用OpenCV的LUT函数应用查找表
    return cv2.LUT(image, lut)


def color_temperature(input, n):
    result = input.copy()
    level = n // 2
    # 创建查找表并应用它到RGB通道
    lut_r = create_lut(level)
    lut_g = create_lut(level)
    lut_b = create_lut(-level)
    result[:, :, 2] = apply_lut(result[:, :, 2], lut_r)  # R通道
    result[:, :, 1] = apply_lut(result[:, :, 1], lut_g)  # G通道
    result[:, :, 0] = apply_lut(result[:, :, 0], lut_b)  # B通道
    return result


def shadow(input_image, light):
    # 将输入图像转换为浮点类型并归一化,便于后续处理
    f = input_image.astype(np.float32) / 255.0
    # 使用OpenCV将归一化的图像转换为灰度图
    gray = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)

    # 计算灰度图的平方,用以确定阴影区域
    thresh = (1.0 - gray) ** 2
    # 计算阴影区域的平均值,用作后续的阈值
    t = np.mean(thresh)
    # 创建一个掩码,标记阴影区域(高于平均值的区域)
    mask = np.where(thresh >= t, 255, 0).astype(np.uint8)
    # 设置校正参数
    max_val = 4  # 最大校正范围
    bright = light / 100.0 / max_val  # 计算校正强度
    mid = 1.0 + max_val * bright  # 计算中间值
    # 创建两个过渡矩阵,用于调整图像的亮度和对比度
    midrate = np.where(mask == 255, mid, ((mid - 1.0) / t * thresh) + 1.0)
    brightrate = np.where(mask == 255, bright, (1.0 / t * thresh) * bright)
    # 使用指数函数调整图像亮度,并通过掩码实现平滑过渡
    result = np.clip(pow(f, 1.0 / midrate[:, :, np.newaxis]), 0.0, 1.0)
    # 根据计算出的亮度率调整图像,限制值在0到1之间
    result = np.clip(result * (1.0 / (1 - brightrate[:, :, np.newaxis])), 0.0, 1.0) * 255
    # 将结果转换为8位无符号整型,以便显示和保存
    result = result.astype(np.uint8)
    return result

def Saturation(rgb_img, increment):
    # 将输入图像转换为浮点数,并归一化到0-1范围
    img = rgb_img.astype(np.float64) / 255.0
    # 计算每个像素的最小值,即HSL颜色空间中的亮度最低的部分
    img_min = img.min(axis=2)
    # 计算每个像素的最大值,即HSL颜色空间中的亮度最高的部分
    img_max = img.max(axis=2)

    # 计算饱和度(delta)和亮度(value)的中间值
    delta = (img_max - img_min)
    value = (img_max + img_min)
    # 计算HSL颜色空间中的亮度L
    L = value / 2.0

    # 根据亮度L计算饱和度s的两个可能值
    s1 = delta / (value + 1e-8)  # 防止除以0的情况,添加一个很小的数
    s2 = delta / (2 - value + 1e-8)
    # 根据亮度L选择饱和度s的正确值
    s = np.where(L < 0.5, s1, s2)

    # 计算增量调整后的饱和度,如果饱和度加上增量大于1,则保持原饱和度,否则用1减去增量
    temp = increment + s
    alpha = np.where(temp > 1, s, 1 - increment)
    # 计算调整后的alpha值
    alpha = 1 / alpha - 1

    # 对RGB图像的每个通道进行调整,以改变饱和度
    for i in range(3):
        img[:, :, i] += (img[:, :, i] - L) * alpha
    # 确保调整后的RGB值在0到1之间,如果超出这个范围,则将其限制在这个范围内
    img = np.clip(img, 0, 1)

    # 返回调整后的图像
    return img


def laplacian_sharpening(image, kernel_size=3, scale=0.05, delta=0):
    """
    Apply Laplacian sharpening to an image.

    Parameters:
    image: The input image in BGR format.
    kernel_size: The size of the Laplacian kernel (must be 1, 3, 5, or 7).
    scale: The optional scale factor for the computed Laplacian values.
    delta: The optional delta value added to the results prior to storing them.

    Returns:
    The sharpened image.
    """
    # Check if kernel size is valid
    if kernel_size not in [1, 3, 5, 7]:
        raise ValueError("Kernel size must be 1, 3, 5, or 7.")

    # Convert the image to grayscale
    gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # Compute the Laplacian of the image
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F, ksize=kernel_size, scale=scale, delta=delta)

    # Convert Laplacian image to 8-bit
    laplacian_8u = cv2.convertScaleAbs(laplacian)

    # Convert the 8-bit Laplacian image to BGR
    laplacian_8u_bgr = cv2.cvtColor(laplacian_8u, cv2.COLOR_GRAY2BGR)

    # Add the Laplacian image to the original image
    sharpened_image = cv2.addWeighted(image, 1, laplacian_8u_bgr, 1.5, 0)

    return sharpened_image

img = cv2.imread(r"D:\AI_tool\GFPGAN-master\273813a415dbe086179ec092b693e8bb.jpg")
img = cv2.resize(img,(0,0),fx=0.5,fy=0.5)
col=color_temperature(img,-20)
abs = cv2.convertScaleAbs(col, alpha=1.1, beta=-10)

lap=laplacian_sharpening(abs)
shd=shadow(lap,-20)
sat=Saturation(shd,0.1)

cv2.imshow("img",img)
cv2.imshow("sat",shd)
cv2.waitKey(0)

效果:

在这里插入图片描述

在这里插入图片描述

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值