基于Python优化图片亮度与噪点

news2024/11/18 16:22:02

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

我们先看一下实测效果:(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之间。
室内照片可能因光线不足而显得较暗,轻微提升亮度可以改善整体亮度。

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

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

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.coloradmin.cn/o/1204839.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于JavaWeb+SSM+校园零售商城微信小程序系统的设计和实现

基于JavaWebSSM校园零售商城微信小程序系统的设计和实现 源码获取入口前言主要技术系统设计功能截图Lun文目录订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 前言 摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应…

HRNet关键点检测

HRNet是一种用于关键点检测的网络架构&#xff0c;它具有一些优点和缺点。 优点&#xff1a; 可以保持高分辨率&#xff1a;HRNet将高分辨率到低分辨率的子网并联连接&#xff0c;而不是像大多数现有解决方案那样串联连接。因此&#xff0c;HRNet能够保持高分辨率&#xff0c…

动态修改hosts

前言 因工作需要频繁变更hosts&#xff0c; 故须自己实现一个动态管理器&#xff0c; 市面上其实已经有了类似的软件&#xff0c;比如switchhosts!但因为不好集成其他功能&#xff08;如远程连接KVM&#xff09;&#xff0c;所以还是决定自己开发一套。 原理 使用之前强烈建…

tcpdump抓包的字节数量与ethtool统计数据不同的原因

情况介绍 在进行RDMA抓包流量分析时&#xff0c;我使用ethtool工具统计了RDMA网卡的流量发送数据数量&#xff0c;然后使用tcpdump进行抓包。 经过分析发现&#xff0c;tcpdump得到的数据数量总是大于ethtool得到的数据数量&#xff0c;而且每个数据包会多出4个字节。 分析 …

Juniper PPPOE双线路冗余RPM配置

------------------ 浮动静态路由 set routing-options static route 0.0.0.0/0 next-hop pp0.0 qualified-next-hop pp0.1 preference 10 ----------------- RPM测试的内容,包括从哪个接口发起测试,测试ping等等 #指定探针类型用ICMP请求 #探测的目标地址 #探测间隔 #探测阈…

Java第十八章Swing程序设计

一、Swing概述 Swing 是 Java 平台的用户界面&#xff08;UI&#xff09;工具包&#xff0c;它是一种现代化的、跨平台的 UI 工具包&#xff0c;可以使用各种操作系统上的 Java 虚拟机&#xff08;JVM&#xff09;来实现&#xff0c;包括 Windows、Linux 和 MacOS 等。Swing 提…

CopyOnWriteArrayList内存占用过多

目录 一、CopyOnWriteArrayList二、CopyOnWriteArrayList的适用场景三、CopyOnWriteArrayList内存占用过多的解决方法四、CopyOnWriteArrayList.add()源码分析 大家好&#xff0c;我是哪吒。 一、CopyOnWriteArrayList CopyOnWriteArrayList是Java中的一个线程安全的ArrayLis…

docker小技能

文章目录 I 预备知识Docker组成命名空间 (进程隔离)II 常用命令2.1 案例:流水线docker 部署2.2 删除没有使用的镜像2.3 shell 不打印错误输出2.4 阿里云流水线/jenkins忽略shell步骤中的报错https://www.runoob.com/docker/docker-architecture.html I 预备知识 Docker组成…

ElementUI表格el-table自适应高度(表头表尾固定不动)

ElementUI表格el-table自适应高度&#xff08;表头表尾固定不动&#xff09;&#xff0c;内容只在中间滚动&#xff0c;效果如图&#xff1a; 实现代码 <div class"mt-10" :style"{height:tableHeight}"><div class"operation-bar">…

15年之后再回低价的双十一,几分像从前?

文 | 螳螂观察 作者 | 易不二 今年双十一&#xff0c;全网铺天盖地的“低价”字眼&#xff0c;让人有种时空错乱的感觉。 犹记得&#xff0c;2009年双十一也是以一刀直砍到5折的低价&#xff0c;推开了一扇新世界的大门。在那个车马邮件还有网速都很慢的年月&#xff0c;人们…

深入理解强化学习——马尔可夫决策过程:随机过程和马尔可夫性质

分类目录&#xff1a;《深入理解强化学习》总目录 下图介绍了强化学习里面智能体与环境之间的交互&#xff0c;智能体得到环境的状态后&#xff0c;它会采取动作&#xff0c;并把这个采取的动作返还给环境。环境得到智能体的动作后&#xff0c;它会进入下一个状态&#xff0c;把…

【Transformer从零开始代码实现 pytoch版】(三)Decoder编码器组件:多头自注意力+多头注意力+全连接层+规范化层

解码器组件 解码器部分&#xff1a; 由N个解码器层堆叠而成每个解码器层由三个子层连接结构组成第一个子层连接结构包括一个多头自注意力子层和规范化层以及一个残差连接第二个子层连接结构包括一个多头注意力子层和规范化层以及一个残差连接第三个子层连接结构包括一个前馈全…

牛客网上收藏题目总结及重写(C语言)(3)

每日一言 如果预计中的不幸没有发生的话&#xff0c;我们就会收获意外的喜悦。 --人生的智慧 题目BC84 错因&#xff1a;忘记要使用小数除法 代码 #include <stdio.h> int main() {int i 0;int n 0;scanf("%d",&n);double sum 0;for(i1;i<n;i){su…

分享一些有趣的MATLAB提示音(代码可直接复制)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

联想笔记本Fn + A可以全选,Ctrl失效

问题&#xff1a;联想笔记本Fn A可以全选&#xff0c;ctrl失效。 原因&#xff1a;BIOS启用了Fn键和Ctrl键互换。 解决操作&#xff1a; 1.开机时一直按F2&#xff0c;进入BIOS 2.点击More Settings > 2.选取Configuration 3.将Fool Proof Fn Ctrl 设定变更为Disabled 4.按…

【算法与数据结构】491、LeetCode递增子序列

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题和【算法与数据结构】78、90、LeetCode子集I&#xff0c; II中90.子集II问题有些类似&#xff0c;…

(四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁殖…

Outlook如何精准搜索邮件

说明&#xff1a; 使用Outlook默认的搜索时&#xff0c;会出来很多无关的信息&#xff0c;对搜索邮件带来很大的不便&#xff0c;下面介绍一个使用精准搜索的方法。 操作指引&#xff1a; 1、在outlook左上角&#xff0c;进行如下操作&#xff0c;打开“其他命令” 2、打开快…

UBoot

uboot是什么&#xff1f; 嵌入式linux系统启动过程 嵌入式系统上电后先执行uboot、然后uboot负责初始化DDR&#xff0c;初始化Flash&#xff0c;然后将OS从Flash中读取到DDR中&#xff0c;然后启动OS&#xff08;OS启动后uboot就无用了&#xff09;uboot是什么&#xff0c;ubo…

【Java】集合(二)Set

1.Set接口基本介绍 无序:存取顺序不一致不重复:可以去除重复无索引:没有带索引的方法&#xff0c;所以不能使用普通for循环遍历&#xff0c;也不能通过索引来获取元素 2.Set集合的实现类 HashSet:无序、不重复、无索引LinkedHashSet: 有序、不重复、无索引TreeSet: 可排序、不…