基于Python美化图片亮度和噪点

news/2024/7/21 5:44:39 标签: python, 开发语言, 图像处理, 噪点, 亮度, pycharm

支持添加噪点类型包括:添加高斯噪点、添加椒盐噪点、添加波动噪点、添加泊松噪点、添加周期性噪点、添加斑点噪点、添加相位噪点,还提供清除噪点的功能。

我们先看一下实测效果:(test.jpg为原图,new.jpg为添加后的图片)

测试添加椒盐噪点

测试添加波动噪点

测试添加高斯噪点

针对上面刚生成的添加了30高斯噪点的图片,测试清理噪点的效果

这里清除噪点采用的是中值滤波器,其实还有很多其他类型的滤波器,各有其优势和适用场景。

效果还是有的,但是我在测使处理斑点噪点时效果不理想,因此这个噪点清除主要还是用于原图的一个处理优化,用于人为严重的噪点处理起来效果不太好。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面介绍一下上述七种类型的噪点生成的方法和去除噪点的原理:

高斯噪点(选项1)

方法:通过在每个像素的颜色通道上添加服从正态分布的随机数,模拟真实场景中的随机噪点
参数:强度(intensity)表示添加的噪点的强度,即随机数的标准差。


椒盐噪点(选项2)

方法:在图像中随机选择像素,并将其设置为黑色或白色,模拟图像中的椒盐噪点
参数:密度(density)表示椒盐噪点的比例,即在图像中设置为黑色或白色的像素的比例。


波动噪点(选项3)

方法:在每个像素的颜色通道上添加从均匀分布中随机选择的整数,模拟图像中的波动噪点
参数:强度(intensity)表示添加的波动噪点的强度,即随机整数的范围。


泊松噪点(选项4)

方法:使用泊松分布生成噪点,模拟一些自然场景中的光子计数的泊松分布。
参数:泊松噪点无需用户指定参数。


周期性噪点(选项5)

方法:在图像中添加具有特定频率的正弦波噪点,模拟周期性干扰。
参数:频率(frequency)表示添加的正弦波噪点的频率。


斑点噪点(选项6)

方法:在图像中随机选择位置,并将其设置为具有随机颜色的斑点,模拟斑点噪点
参数:密度(density)表示斑点噪点的比例,即在图像中设置为斑点的像素的比例。


相位噪点(选项7)

方法:在图像的相位上引入随机值,模拟相位噪点
参数:强度(intensity)表示添加的相位噪点的强度,即在相位上引入的随机值的范围。


清除噪点(选项8)

方法:使用中值滤波器去除图像中的噪点
参数:清除噪点无需指定参数。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

对于亮度各位可以自行设置,我代码里给的是20,关于亮度设置的一些建议:

风景照片:10到20之间

一幅风景照片可能在稍微提高亮度后更加清晰和宜人。


人物照片:5到15之间

对于人物照片,适度的亮度提升可能会使面部特征更加清晰,但不要过分。


黑白照片:0到10之间。
在黑白照片中,适度的亮度提升可以改善整体对比度。


艺术照片:-10到10之间。

对于一些艺术性质的照片,可以尝试一些负值,以产生一些有趣的阴影效果。


室内照片:5到15之间。
室内照片可能因光线不足而显得较暗,轻微提升亮度可以改善整体亮度

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

下面附上源码:(其中图片所在路径以及生成图片放置路径改成自己的即可)

python">from PIL import Image, ImageFilter
import numpy as np
from typing import Tuple


def change_brightness(img: Image, level: float) -> Image:
    """
    调整 PIL 图像的亮度到指定水平。
    """

    def brightness(c: int) -> float:
        """
        对每个位执行的基本变换/操作。
        """
        return 128 + level + (c - 128)

    if not -50.0 <= level <= 50.0:
        raise ValueError("亮度水平必须在 -50.0 到 50.0 之间")
    return img.point(brightness)


def add_gaussian_noise(img: Image, intensity: float) -> Image:
    """
    向 PIL 图像添加高斯噪点。
    """
    if not 0.0 <= intensity <= 30.0:
        raise ValueError("高斯噪点强度必须在 0.0 到 30.0 之间")

    np_img = np.array(img)
    noise = np.random.normal(scale=intensity, size=np_img.shape)
    noisy_img = np_img + noise
    noisy_img = np.clip(noisy_img, 0, 255).astype(np.uint8)
    return Image.fromarray(noisy_img)


def add_salt_and_pepper_noise(img: Image, density: float) -> Image:
    """
    向 PIL 图像添加椒盐噪点。
    """
    if not 0.0 <= density <= 1.0:
        raise ValueError("椒盐噪点密度必须在 0.0 到 1.0 之间")

    np_img = np.array(img)
    salt_and_pepper = np.random.rand(*np_img.shape[:2])

    noisy_img = np_img.copy()
    noisy_img[salt_and_pepper < density / 2] = 0
    noisy_img[salt_and_pepper > (1 - density / 2)] = 255

    return Image.fromarray(noisy_img)


def add_random_noise(img: Image, intensity: float) -> Image:
    """
    向 PIL 图像添加波动噪点。
    """
    if not 0.0 <= intensity <= 30.0:
        raise ValueError("波动噪点强度必须在 0.0 到 30.0 之间")

    np_img = np.array(img)
    noise = np.random.randint(-intensity, intensity + 1, size=np_img.shape)
    noisy_img = np_img + noise
    noisy_img = np.clip(noisy_img, 0, 255).astype(np.uint8)
    return Image.fromarray(noisy_img)


def add_poisson_noise(img: Image) -> Image:
    """
    向 PIL 图像添加泊松噪点。
    """
    np_img = np.array(img)
    noisy_img = np.random.poisson(np_img)
    noisy_img = np.clip(noisy_img, 0, 255).astype(np.uint8)
    return Image.fromarray(noisy_img)


def add_periodic_noise(img: Image, frequency: float) -> Image:
    """
    向 PIL 图像添加周期性噪点。
    """
    if not 0.0 <= frequency <= 0.5:
        raise ValueError("周期性噪点频率必须在 0.0 到 0.5 之间")

    np_img = np.array(img)
    rows, cols, _ = np_img.shape
    x = np.arange(cols)
    y = np.arange(rows)
    X, Y = np.meshgrid(x, y)
    noise = np.sin(2 * np.pi * frequency * X / cols) + np.sin(2 * np.pi * frequency * Y / rows)
    noisy_img = np_img + 30 * noise[:, :, np.newaxis]
    noisy_img = np.clip(noisy_img, 0, 255).astype(np.uint8)
    return Image.fromarray(noisy_img)


def add_spotty_noise(img: Image, density: float) -> Image:
    """
    向 PIL 图像添加斑点噪点。
    """
    if not 0.0 <= density <= 1.0:
        raise ValueError("斑点噪点密度必须在 0.0 到 1.0 之间")

    np_img = np.array(img)
    spotty = np.random.rand(*np_img.shape[:2])

    noisy_img = np_img.copy()
    noise = np.random.randint(0, 256, size=(np_img.shape[0], np_img.shape[1], 3))
    noisy_img[spotty < density] = noise[spotty < density]

    return Image.fromarray(noisy_img)


def add_phase_noise(img: Image, intensity: float) -> Image:
    """
    向 PIL 图像添加相位噪点。
    """
    if not 0.0 <= intensity <= 30.0:
        raise ValueError("相位噪点强度必须在 0.0 到 30.0 之间")

    np_img = np.array(img)
    phase = np.random.uniform(-intensity, intensity, size=np_img.shape[:2])
    noisy_img = np_img * np.exp(1j * phase[:, :, np.newaxis])
    noisy_img = np.abs(noisy_img).astype(np.uint8)

    return Image.fromarray(noisy_img)


def remove_noise(img: Image) -> Image:
    """
    清除 PIL 图像中的所有噪点。
    """
    return img.filter(ImageFilter.MedianFilter(size=3))


if __name__ == "__main__":
    # 加载图像
    image_path = "D:/swctf/image/test.jpg"
    with Image.open(image_path) as img:
        # 将亮度调整为20
        bright_img = change_brightness(img, 20)

        # 用户选择操作类型
        print("选择操作类型:")
        print("1: 添加高斯噪点")
        print("2: 添加椒盐噪点")
        print("3: 添加波动噪点")
        print("4: 添加泊松噪点")
        print("5: 添加周期性噪点")
        print("6: 添加斑点噪点")
        print("7: 添加相位噪点")
        print("8: 清除噪点")
        operation_type = input("请输入选项数字: ")

        # 根据操作类型明确输入范围和类型
        if operation_type == "1":
            intensity = float(input("请输入高斯噪点强度(0.0 到 30.0): "))
            processed_img = add_gaussian_noise(bright_img, intensity)
        elif operation_type == "2":
            intensity = float(input("请输入椒盐噪点密度(0.0 到 1.0): "))
            processed_img = add_salt_and_pepper_noise(bright_img, intensity)
        elif operation_type == "3":
            intensity = float(input("请输入波动噪点强度(0.0 到 30.0): "))
            processed_img = add_random_noise(bright_img, intensity)
        elif operation_type == "4":
            processed_img = add_poisson_noise(bright_img)
        elif operation_type == "5":
            frequency = float(input("请输入周期性噪点频率(0.0 到 0.5): "))
            processed_img = add_periodic_noise(bright_img, frequency)
        elif operation_type == "6":
            density = float(input("请输入斑点噪点密度(0.0 到 1.0): "))
            processed_img = add_spotty_noise(bright_img, density)
        elif operation_type == "7":
            intensity = float(input("请输入相位噪点强度(0.0 到 30.0): "))
            processed_img = add_phase_noise(bright_img, intensity)
        elif operation_type == "8":
            processed_img = remove_noise(bright_img)
        else:
            raise ValueError("不支持的操作类型")

        # 保存处理后的图像
        output_path = "D:/swctf/image/new.jpg"
        processed_img.save(output_path, format="jpeg")
        print(f"处理后的图像已保存至: {output_path}")


http://www.niftyadmin.cn/n/5176992.html

相关文章

Web相机和浏览器的二维码扫描方案

Web相机和适用于浏览器的二维码扫描方案 qr-camera 在线体验 | English 功能 支持浏览器扫描二维码支持拍照支持录像功能支持二维码解析和生成 quickstart npm i qr-cameraimport {QRCamera} from qr-camera;function main(){const camera new QRCamera();document.body…

MyBatis 知识总结

1 MyBatis 1.1 简介 持久层框架&#xff0c;用于简化JDBC开发 JavaEE三层架构&#xff1a;表现层、业务层、持久层 表现层&#xff1a;做页面展示 业务层&#xff1a;做逻辑处理 持久层&#xff1a;负责将数据保存到数据库的那一层代码 框架&#xff1a;半成品软件&#xff0…

堆排序(小根堆模板)

输入一个长度为 n 的整数数列&#xff0c;从小到大输出前 m 小的数。 输入格式 第一行包含整数 n 和 m。 第二行包含 n 个整数&#xff0c;表示整数数列。 输出格式 共一行&#xff0c;包含 m 个整数&#xff0c;表示整数数列中前 m 小的数。 数据范围 1≤m≤n≤10^5&am…

如何调用 DBMS_DISKGROUP 对 ASM 文件进行随机读取

目录 一、概述 二、实现思路与注意点 三、Java Demo 1、直接调用 2、读写异步 一、概述 对于 Oracle Rac 环境下,数据文件大多默认存放在 ASM 共享存储上,当我们需要读取 ASM 上存储的数据文件时可以使用 Oracle 提供的一些方法,比如 ASMCMD CP。但是,对于一些备份场景…

Hbuilder介绍,uniapp框架

Hbuilder对程序前端页面进行开发&#xff08;包括android&#xff0c;ios&#xff0c;小程序&#xff0c;web等等&#xff09;,其实也就是相当于把android开发进行前后端分离了。方便分工协作。提高开发效率。 用前端框架开发可以实现一次编码&#xff0c;多平台运行。 &…

酷柚易汛ERP - 商品库存余额表操作指南

1、应用场景 商品库存余额表用于查询商品在各仓库的实际结存量、单位成本以及成本等明细。 2、主要操作 打开【仓库】-【商品库存余额表】&#xff0c;可筛选仓库、商品、商品类别&#xff0c;导出/打印等操作见【销货单】不再赘述。 3、分享操作 库存余额分享&#xff0c;…

Spring IoC DI 使⽤

关于 IoC 的含义&#xff0c;推荐看IoC含义介绍&#xff08;Spring的核心思想&#xff09; 喜欢 Java 的推荐点一个免费的关注&#xff0c;主页有更多 Java 内容 前言 通过上述的博客我们知道了 IoC 的含义&#xff0c;既然 Spring 是⼀个 IoC&#xff08;控制反转&#xff09…

linux安装多个python环境

# 更新源 apt-get update# 安装python特定版本 apt-get install python3.7# 验证安装 python3.7 --version# 使用3.7的版本安装python包 python3.7 -m pip install 需要安装的包名# 创建虚拟环境 python3.7 -m pip install virtualenv python3.7 -m virtualenv venv source ven…