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

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

我们先看一下实测效果:(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}")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/141349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动化测试的成本高效果差,那么自动化测试的意义在哪呢?

一、自动化测试的成本高效果差&#xff0c;那么自动化测试的意义在哪呢&#xff1f; 我觉得这个问题带有很强的误导性&#xff0c;是典型的逻辑陷阱之一。“自动化测试的成本高效果差”是真的吗&#xff1f;当然不是。而且我始终相信&#xff0c;回答问题的最好方式是把问题本身…

达索系统3DEXPERIENCE WORKS 2024流体仿真功能增强

设计工作中&#xff0c;网格划分和设计验证十分重要&#xff0c;它可以方便我们把复杂组件简单化处理&#xff0c;从而提升工作效率。 轻松应对&#xff0c;精准划分 在优化设计以获得更好的空气动力学性能时&#xff0c;需要了解空气在其周围产生的流动方式。达索系统3DEXPE…

(论文阅读29/100 人体姿态估计)

29.文献阅读笔记 简介 题目 DeepCut: Joint Subset Partition and Labeling for Multi Person Pose Estimation 作者 Leonid Pishchulin, Eldar Insafutdinov, Siyu Tang, Bjoern Andres, Mykhaylo Andriluka, Peter Gehler, and Bernt Schiele, CVPR, 2016. 原文链接 h…

STM32 X-CUBE-AI:Pytorch模型部署全流程

文章目录 概要版本&#xff1a;参考资料STM32CUBEAI安装CUBEAI模型支持LSTM模型转换注意事项模型转换模型应用1 错误类型及代码2 模型创建和初始化3 获取输入输出数据变量4 获取模型前馈输出模型应用小结 小结 概要 STM32 CUBE MX扩展包&#xff1a;X-CUBE-AI部署流程&#xf…

Accelerate 0.24.0文档 一:两万字极速入门

文章目录 一、概述1.1 PyTorch DDP1.2 Accelerate 分布式训练简介1.2.1 实例化Accelerator类1.2.2 将所有训练相关 PyTorch 对象传递给 prepare()方法1.2.3 启用 accelerator.backward(loss) 1.3 Accelerate 分布式评估1.4 accelerate launch1.4.1 使用accelerate launch启动训…

k8s集群搭建(ubuntu 20.04 + k8s 1.28.3 + calico + containerd1.7.8)

环境&需求 服务器&#xff1a; 10.235.165.21 k8s-master 10.235.165.22 k8s-slave1 10.235.165.23 k8s-slave2OS版本&#xff1a; rootvms131:~# lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.04.5 LTS Release: …

Java自学第11课:电商项目(4)重新建立项目

经过前几节的学习&#xff0c;我们已经找到之前碰到的问题的原因了。那么下面接着做项目学习。 1 新建dynamic web project 建立时把web.xml也生成下&#xff0c;省的右面再添加。 会询问是否改为java ee环境&#xff1f;no就行&#xff0c;其实改过来也是可以的。这个不重要。…

css3 初步了解

1、css3的含义及简介 简而言之&#xff0c;css3 就是 css的最新标准&#xff0c;使用css3都要遵循这个标准&#xff0c;CSS3 已完全向后兼容&#xff0c;所以你就不必改变现有的设计&#xff0c; 2、一些比较重要的css3 模块 选择器 1、标签选择器&#xff0c;也称为元素选择…

滚珠螺杆在注塑机械手中起什么作用?

注塑机械手的配件中滚珠螺杆是重要的一环&#xff0c;在注塑机械手中起着重要的作用。注塑机械手是一种自动化设备&#xff0c;可以在注塑生产中实现自动化操作&#xff0c;而滚珠螺杆则是实现这一操作的关键部件之一。 滚珠螺杆是一种将旋转运动转化为直线运动的精密传动部件&…

在Linux系统下微调Llama2(MetaAI)大模型教程—Qlora

Llama2是Meta最新开源的语言大模型&#xff0c;训练数据集2万亿token&#xff0c;上下文长度是由Llama的2048扩展到4096&#xff0c;可以理解和生成更长的文本&#xff0c;包括7B、13B和70B三个模型&#xff0c;在各种基准集的测试上表现突出&#xff0c;最重要的是&#xff0c…

【Linux网络】本地DNS服务器搭建

目录 一、什么是DNS&#xff0c;相关介绍 1、dns是什么&#xff1a; 2、域名的分类&#xff1a; 3、服务器的类型 二、DNS解析的过程 三、DNS的相关配置文件学习 1、本地主机有关的DNS文件学习 2、本地的DNS缓存服务器的文件 3、bind软件的相关配置文件&#xff1a; 4…

Jmeter执行接口自动化测试-如何初始化清空旧数据

需求分析&#xff1a; 每次执行完自动化测试&#xff0c;我们不会执行删除接口把数据删除&#xff0c;而需要留着手工测试&#xff0c;此时会导致下次执行测试有旧数据我们手工可能也会新增数据&#xff0c;导致下次执行自动化测试有旧数据 下面介绍两种清空数据的方法 一、通…

nginx代理docker容器服务

场景描述 避免暴力服务端口&#xff0c;使用nginx代理 一个前端&#xff0c;一个后端&#xff0c;docker方式部署到服务器&#xff0c;使用docker创建的nginx代理端口请求到前端端口 过程 1 docker 安装nginx 1.1 安装一个指定版本的nginx docker pull nginx#启动一个ngi…

vuejs - - - - - 移动端设备兼容(pxtorem)

pxtorem的使用 1. 依赖安装2. vue.config.js配置3. 动态设置html的font-size大小4. 效果如图&#xff1a; 1. 依赖安装 yarn add postcss-pxtorem -D 2. vue.config.js配置 module.exports {...css: {loaderOptions: {postcss: {plugins: [require("postcss-pxtorem&quo…

22.能被7整除,并且求和。

#include<stdio.h>int main(){int i ,sum0;printf("1-1000能被7整除的数字有&#xff1a;\n");for(i1;i<1000;i){if(i%70){printf("%d ",i);sumsumi;} }printf("\n");printf("能被7整除的数字的和是&#xff1a;%d ",sum);re…

这样书写Python代码的方式,实在是太优雅了~

文章目录 前言一、在Python中配合pipe灵活使用链式写法二 、pipe中常用的管道操作函数1.使用traverse()展平嵌套数组2.使用dedup()进行顺序去重3.使用filter()进行值过滤4.使用groupby()进行分组运算5.使用select()对上一步结果进行自定义遍历运算6.使用sort()进行排序 总结关于…

线性表->栈

文章目录 前言概述栈的初始化销毁压栈出栈判断栈为不为空栈的有效个数 前言 栈相对于链表&#xff0c;稍微简单一点&#xff0c;但是栈的难点在于通过栈去理解递归算法。 概述 **栈&#xff1a;**一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。…

Redis解决缓存问题

目录 一、引言二、缓存三、Redis缓存四、缓存一致性1.缓存更新策略2.主动更新 五、缓存穿透六、缓存雪崩七、缓存击穿1.基于互斥锁解决具体业务2.基于逻辑过期解决具体业务 一、引言 在一些大型的网站中会有十分庞大的用户访问流量&#xff0c;而过多的用户访问对我们的MySQL数…

初学UE5 C++①

游戏类 1.创建所需项的类 2.创建游戏模式类&#xff0c;在该类上实现所需项&#xff0c;引入头文件和构造函数时实例化 三种时间函数类型函数和提示类型 FName、FString、FText类型相互转化 FName用FName FString用ToString&#xff08;&#xff09; FText用FText&#xff1a;…