python图像处理 —— 实现图像滤镜效果

news2024/11/25 10:51:39

python图像处理 —— 实现图像滤镜效果

  • 前言
  • 一、浮雕
  • 二、素描
  • 三、怀旧
  • 四、水彩画
  • 五、水波
  • 六、卡通
  • 七、流年
  • 八、美颜
  • 完整代码

前言

随着数字图像处理技术的不断发展,越来越多的人开始关注图像滤镜的应用。其中,使用Python的Opencv库实现图像滤镜效果成为了一种流行的技术手段。而图像滤镜是一种可以改变图像外观和色彩的技术,可以帮助我们创建独特的视觉效果。在本文中,我们将介绍如何使用Python和Opencv实现图像滤镜效果,为读者提供一个简单的入门指南。

一、浮雕

图像浮雕原理是通过对图像进行灰度变换,使得某些局部区域的像素值相对于周围像素值有一定的增加或减少,从而使得图像呈现出明显的浮雕感觉。具体来说,浮雕效果的实现可以通过以下步骤:

(1)将彩色图像转换为灰度图像。
(2)对灰度图像进行卷积操作,使用卷积核进行滤波,得到一组新的像素值。卷积核的大小可以根据需要进行调整,通常采用3x3或5x5的大小。
(3)对于每个像素,将卷积操作后得到的像素值减去该像素在原始图像中的像素值,得到浮雕值。
(4)根据浮雕值,将像素点的灰度值进行调整,使得局部区域的像素值相对于周围的像素值有一定的增加或减少。
(5)将处理后的像素值重新映射到0-255的灰度值范围内,生成浮雕效果的图像。

# ===============================图像浮雕处理===============================
img_Fudiao = np.zeros((h, w, 3), np.uint8)
for i in range(0, h):
    for j in range(0, w - 2):              # 减2的效果和上面一样
        grayP0 = int(gray[i, j])
        grayP1 = int(gray[i, j + 2])        # 取与前一个像素点相邻的点
        newP = grayP0 - grayP1 + 150       # 得到差值,加一个 150 常数可以增加浮雕立体感
        if newP > 255:  # 新的像素值,防止像素溢出
            newP = 255
        if newP < 0:    # 新的像素值,防止像素溢出
            newP = 0
        img_Fudiao[i, j] = newP

二、素描

通过滤波、边缘检测、二值化可以将将一幅RGB图像转换成素描

#  ===============================图像素描处理==================================
gaussian = cv2.GaussianBlur(gray, (3, 3), 0)  # 通过高斯滤波过滤噪声
# 通过canny算法提取图像轮过
canny = cv2.Canny(gaussian, 50, 140)
# 对轮廓图像进行反二进制阈值化处理
ret, img_Sumiao = cv2.threshold(canny, 50, 255, cv2.THRESH_BINARY_INV)

三、怀旧

将一幅RGB图像转为怀旧图像的基本原理是将原始图像的颜色进行调整,使其呈现出类似老照片的色调。

# ===============================图像怀旧处理===============================
img_old = np.zeros((h, w, 3), dtype=img.dtype)
# 通过对原始图像进行遍历,通过怀旧公式修改像素值,然后进行怀旧处理
for i in range(h):
    for j in range(w):
        B = 0.272 * img[i, j][2] + 0.534 * img[i, j][1] + 0.131 * img[i, j][0]
        G = 0.349 * img[i, j][2] + 0.686 * img[i, j][1] + 0.168 * img[i, j][0]
        R = 0.393 * img[i, j][2] + 0.769 * img[i, j][1] + 0.189 * img[i, j][0]
        # 防止图像溢出
        if B > 255:
            B = 255
        if G > 255:
            G = 255
        if R > 255:
                R = 255
        img_old[i, j] = [int(R), int(G), int(B)]  # B\G\R三通道都设置为怀旧值

四、水彩画

cv2.stylization是OpenCV库中的一种图像风格化函数,它可以用于将图像转换为带有不同风格的艺术作品。该函数的实现基于快速风格迁移(Fast Style Transfer)技术,可以在短时间内将一张普通照片转化为梵高,毕加索或印象派等多种不同风格的艺术作品。

# ===============================图像水彩画效果处理===============================
"""
src:需要进行风格化的原始图像。
sigma_s:控制空间域滤波器的尺度,通常取值在0到200之间,数值越大则滤波器的尺度越大,图像的细节信息会被平滑处理。
sigma_r:控制像素值域滤波器的尺度,通常取值在0到1之间,数值越小则滤波器的尺度越小,图像的细节信息会被保留。
"""
img_color = cv2.stylization(img, sigma_s=60, sigma_r=0.6)

五、水波

添加水波特效的原理是通过对RGB图像进行仿射变换和图像处理,使图像呈现出波动效果。

# ===============================水波特效===============================
img_wave = np.zeros((h, w, 3), np.uint8)
wavelength = 30                                 #定义水波特效波长
amplitude = 20                                  #幅度
phase = math.pi / 4                             #相位
centreX = 0.5                                   #水波中心点X
centreY = 0.5                                   #水波中心点Y
radius = min(h, w) / 2
icentreX = w*centreX                            #水波覆盖宽度
icentreY = h*centreY                            #水波覆盖高度
for i in range(0, h):
    for j in range(0, w):
        dx = j - icentreX
        dy = i - icentreY
        distance = dx * dx + dy * dy
        if distance > radius * radius:
            x = j
            y = i
        else:
            # 计算水波区域
            distance = math.sqrt(distance)
            amount = amplitude * math.sin(distance / wavelength * 2 * math.pi - phase)
            amount = amount * (radius - distance) / radius
            amount = amount * wavelength / (distance + 0.0001)
            x = j + dx * amount
            y = i + dy * amount
        # 边界判断
        if x < 0:
            x = 0
        if x >= w - 1:
            x = w - 2
        if y < 0:
            y = 0
        if y >= h - 1:
            y = h - 2
        p = x - int(x)
        q = y - int(y)
        # 图像水波赋值
        img_wave[i, j, :] = (1 - p) * (1 - q) * img[int(y), int(x), :] + p * (1 - q) * img[int(y), int(x), :]
        + (1 - p) * q * img[int(y), int(x), :] + p * q * img[int(y), int(x), :]
img_wave = cv2.cvtColor(img_wave, cv2.COLOR_BGR2RGB)

六、卡通

将一幅RGB图像添加卡通特效的原理是将图像进行多次模糊、锐化、边缘检测等处理,使得图像呈现出光滑的颜色渐变和明显的边缘线条,从而使得图像具有卡通般的效果。

# ===============================卡通特效===============================
img_blur = cv2.medianBlur(gray, 7)                     # 中值滤波处理
img_edge = cv2.adaptiveThreshold(img_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize = 5, C = 2) #边缘检测及自适应阈值化处理
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)  # 转换回彩色图像
img_cartoon = cv2.bitwise_and(img, img_edge)          # 图像的与运算
img_cartoon = cv2.cvtColor(img_cartoon, cv2.COLOR_BGR2RGB)

七、流年

添加流年特效是一种常见的图像处理操作,它可以使一幅RGB图像呈现出类似老照片的效果。实现流年特效的主要原理是通过对图像的色彩、亮度、对比度等进行调整,使得图像呈现出一种偏暗、偏黄、颗粒状的效果。

# ===============================流年特效===============================
img_nian = np.zeros((h, w, 3), np.uint8)
for i in range(0, h):
    for j in range(0, w):
        B = math.sqrt(img[i, j][0]) *14       # B通道的数值开平方乘以参数14
        G = img[i, j][1]
        R = img[i, j][2]
        if B > 255:
            B = 255
        img_nian[i, j] = np.uint8((B, G, R))
img_nian = cv2.cvtColor(img_nian, cv2.COLOR_BGR2RGB)

八、美颜

美颜本质上就是双边滤波,函数 cv2.bilateralFilter() 能在保持边界清晰的情况下有效的去除噪音,就是人脸上的痘痘,所以有美颜效果

# ===============================美颜===============================
img_bit = cv2.bilateralFilter(src=img, d=0, sigmaColor=30, sigmaSpace=15)
img_bit = cv2.cvtColor(img_bit, cv2.COLOR_BGR2RGB)

在这里插入图片描述

完整代码

# -*- coding:utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
import math
plt.rcParams['font.family'] = 'SimHei'
img = cv2.imread('bin.png')
img_Org = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
h, w = img.shape[:2]
# ===============================图像浮雕处理===============================
img_Fudiao = np.zeros((h, w, 3), np.uint8)
for i in range(0, h):
    for j in range(0, w - 2):              # 减2的效果和上面一样
        grayP0 = int(gray[i, j])
        grayP1 = int(gray[i, j + 2])        # 取与前一个像素点相邻的点
        newP = grayP0 - grayP1 + 150       # 得到差值,加一个 150 常数可以增加浮雕立体感
        if newP > 255:  # 新的像素值,防止像素溢出
            newP = 255
        if newP < 0:    # 新的像素值,防止像素溢出
            newP = 0
        img_Fudiao[i, j] = newP

#  ===============================图像素描处理==================================
gaussian = cv2.GaussianBlur(gray, (3, 3), 0)  # 通过高斯滤波过滤噪声
# 通过canny算法提取图像轮过
canny = cv2.Canny(gaussian, 50, 140)
# 对轮廓图像进行反二进制阈值化处理
ret, img_Sumiao = cv2.threshold(canny, 50, 255, cv2.THRESH_BINARY_INV)

# ===============================图像怀旧处理===============================
img_old = np.zeros((h, w, 3), dtype=img.dtype)
# 通过对原始图像进行遍历,通过怀旧公式修改像素值,然后进行怀旧处理
for i in range(h):
    for j in range(w):
        # B = 0.131 * img[i, j, 0] + 0.534 * img[i, j, 1] + 0.272 * img[i, j, 2]
        # G = 0.168 * img[i, j, 0] + 0.686 * img[i, j, 1] + 0.349 * img[i, j, 2]
        # R = 0.189 * img[i, j, 0] + 0.769 * img[i, j, 1] + 0.393 * img[i, j, 2]
        B = 0.272 * img[i, j][2] + 0.534 * img[i, j][1] + 0.131 * img[i, j][0]
        G = 0.349 * img[i, j][2] + 0.686 * img[i, j][1] + 0.168 * img[i, j][0]
        R = 0.393 * img[i, j][2] + 0.769 * img[i, j][1] + 0.189 * img[i, j][0]
        # 防止图像溢出
        if B > 255:
            B = 255
        if G > 255:
            G = 255
        if R > 255:
                R = 255
        img_old[i, j] = [int(R), int(G), int(B)]  # B\G\R三通道都设置为怀旧值

# ===============================图像水彩画效果处理===============================
"""
src:需要进行风格化的原始图像。
sigma_s:控制空间域滤波器的尺度,通常取值在0到200之间,数值越大则滤波器的尺度越大,图像的细节信息会被平滑处理。
sigma_r:控制像素值域滤波器的尺度,通常取值在0到1之间,数值越小则滤波器的尺度越小,图像的细节信息会被保留。
"""
img_color = cv2.stylization(img, sigma_s=60, sigma_r=0.6)
img_color = cv2.cvtColor(img_color, cv2.COLOR_BGR2RGB)

# ===============================水波特效===============================
img_wave = np.zeros((h, w, 3), np.uint8)
wavelength = 30                                 #定义水波特效波长
amplitude = 20                                  #幅度
phase = math.pi / 4                             #相位
centreX = 0.5                                   #水波中心点X
centreY = 0.5                                   #水波中心点Y
radius = min(h, w) / 2
icentreX = w*centreX                            #水波覆盖宽度
icentreY = h*centreY                            #水波覆盖高度
for i in range(0, h):
    for j in range(0, w):
        dx = j - icentreX
        dy = i - icentreY
        distance = dx * dx + dy * dy
        if distance > radius * radius:
            x = j
            y = i
        else:
            # 计算水波区域
            distance = math.sqrt(distance)
            amount = amplitude * math.sin(distance / wavelength * 2 * math.pi - phase)
            amount = amount * (radius - distance) / radius
            amount = amount * wavelength / (distance + 0.0001)
            x = j + dx * amount
            y = i + dy * amount
        # 边界判断
        if x < 0:
            x = 0
        if x >= w - 1:
            x = w - 2
        if y < 0:
            y = 0
        if y >= h - 1:
            y = h - 2
        p = x - int(x)
        q = y - int(y)
        # 图像水波赋值
        img_wave[i, j, :] = (1 - p) * (1 - q) * img[int(y), int(x), :] + p * (1 - q) * img[int(y), int(x), :]
        + (1 - p) * q * img[int(y), int(x), :] + p * q * img[int(y), int(x), :]
img_wave = cv2.cvtColor(img_wave, cv2.COLOR_BGR2RGB)

# ===============================卡通特效===============================
img_blur = cv2.medianBlur(gray, 7)                     # 中值滤波处理
img_edge = cv2.adaptiveThreshold(img_blur, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, blockSize = 5, C = 2) #边缘检测及自适应阈值化处理
img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2RGB)  # 转换回彩色图像
img_cartoon = cv2.bitwise_and(img, img_edge)          # 图像的与运算
img_cartoon = cv2.cvtColor(img_cartoon, cv2.COLOR_BGR2RGB)

# ===============================流年特效===============================
img_nian = np.zeros((h, w, 3), np.uint8)
for i in range(0, h):
    for j in range(0, w):
        B = math.sqrt(img[i, j][0]) *14       # B通道的数值开平方乘以参数14
        G = img[i, j][1]
        R = img[i, j][2]
        if B > 255:
            B = 255
        img_nian[i, j] = np.uint8((B, G, R))
img_nian = cv2.cvtColor(img_nian, cv2.COLOR_BGR2RGB)
# ===============================美颜===============================
img_bit = cv2.bilateralFilter(src=img, d=0, sigmaColor=30, sigmaSpace=15)
img_bit = cv2.cvtColor(img_bit, cv2.COLOR_BGR2RGB)

plt.figure(figsize=(16,9))
plt.subplot(331),plt.imshow(img_Org), plt.xticks([]), plt.yticks([]), plt.title('原图')
plt.subplot(332),plt.imshow(img_Fudiao, cmap='gray'), plt.xticks([]), plt.yticks([]), plt.title('浮雕')
plt.subplot(333),plt.imshow(img_Sumiao, cmap='gray'), plt.xticks([]), plt.yticks([]), plt.title('素描')
plt.subplot(334),plt.imshow(img_old), plt.xticks([]), plt.yticks([]), plt.title('怀旧')
plt.subplot(335),plt.imshow(img_color), plt.xticks([]), plt.yticks([]), plt.title('水彩')
plt.subplot(336),plt.imshow(img_wave), plt.xticks([]), plt.yticks([]), plt.title('水波')
plt.subplot(337),plt.imshow(img_cartoon), plt.xticks([]), plt.yticks([]), plt.title('卡通')
plt.subplot(338),plt.imshow(img_nian), plt.xticks([]), plt.yticks([]), plt.title('流年')
plt.subplot(339),plt.imshow(img_bit), plt.xticks([]), plt.yticks([]), plt.title('美颜')
plt.show()

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

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

相关文章

零门槛,不等待!立刻领取 Embedding API 密钥及 1 万免费 tokens!

2023 年 10 月 30 号&#xff0c;Jina AI 正式发布了 jina-embeddings-v2&#xff0c;是全球首个唯一支持 8K&#xff08;8192&#xff09;输入长度的开源向量大模型&#xff0c;今天&#xff0c;我们趁热打铁&#xff0c;为企业和开发者提供 Embedding API&#xff0c;即插即用…

Rabbit的高可用机制

RabbitMQ是一个消息中间件&#xff0c;提供了多种高可用机制来确保系统在出现故障时仍能保持可用性。以下是RabbitMQ的一些高可用机制&#xff1a; 镜像队列&#xff08;Mirrored Queues&#xff09;&#xff1a; 作用&#xff1a; 镜像队列可以在集群中复制队列的消息到多个节…

SpringBoot整合定时任务遇到的多实例问题

唠嗑部分 是这样&#xff0c;前几日完善了定时任务的日志记录&#xff0c;今日切换了服务器&#xff0c;多部署了一个节点&#xff0c;使用nginx负载均衡&#xff0c;但是查看日志却发现了如下情况 那糟糕了&#xff0c;传说中的多实例问题出现了&#xff0c;今天我们就来聊聊…

HTML5的语义元素

HTML5语义元素&#xff1a; HTML5提供新的语义元素来明确一个web页面的不同部分&#xff1a;<head>、<nav>、<section>、<article>、<aside>、<figcation>、<figure>、<footer>。 1&#xff09;、<section>元素&#x…

11、Python文件操作:文件读写、文件对象方法、with语句

文章目录 文件读写模式文件对象方法with语句在Python中,文件操作是一项基本技能,它允许你读写文件,并与文件系统进行交互。这篇文章将详细介绍如何使用Python进行文件读写,涉及不同的文件模式,文件对象的方法,以及如何使用with语句来管理文件资源。 文件读写模式 在Pyt…

10、Python列表深入:列表推导式、列表常用方法、多维列表

文章目录 列表推导式列表常用方法多维列表列表是Python中非常灵活的内置数据类型,它们可以包含任意类型的对象,从数字到字符串甚至是其他列表。在这篇文章中,我们将深入探讨列表推导式、列表的常用方法以及多维列表的使用。 列表推导式 列表推导式提供了一种简洁的方法来创…

Django初窥门径-自定义用户模型

前言 自定义用户模型在Django应用中是一个重要的话题&#xff0c;它涉及到如何根据您的项目需求以及特定的用户身份验证和授权需求来调整用户模型。在以下前言中&#xff0c;我将讲述为什么自定义用户模型是如此重要以及其潜在的优势&#xff1a; 随着Web应用的不断发展&…

只改一行语句,锁这么多?

&#x1f449;导读 这篇文章我想来聊聊 MySQL 的锁是怎么加上的&#xff0c;为啥想聊这个呢&#xff1f;主要是因为业务中我们或多或少都会使用到锁&#xff0c;毕竟锁是保障我们数据安全性的关键法宝。但是由于不了解原理&#xff0c;往往可能导致我们在”刻意“或者”无意“的…

JavaScript从入门到精通系列第三十篇:详解JavaScript中的正则表达式语法

文章目录 前言 1&#xff1a;概念回顾 2&#xff1a;正则表达式 一&#xff1a;正则表达式 1&#xff1a;正则表达式字面量 2&#xff1a;检查是否有a或者b 3&#xff1a;检查是否有字母 4&#xff1a;检查是否有abc/aec/afc 5&#xff1a;检查除了ab 大神链接&#x…

Python教程:打印自己的名字

要打印的名字是&#xff1a;PYTHON …######… …#…#… …######… …#… …#… …#…#… …#…#… …##… …##… …##… …######… …##… …##… …##… …##… …#…#… …#…#… …######… …#…#… …#…#… …######… …#…#… …#…#… …#…#… …######… ……

【Spring实战——构建Spring Web应用程序】1.10 处理表单

引言 Web应用功能 ○ 提供内容 ○ 用户填写表单 ○ 提交数据 Spring MVC的控制器提供了 ○ 处理表单展示 ○ 用户提交数据的支持 在Spittr应用中&#xff0c;需要一个注册表单供新用户使用。SpitterController是一个新的控制器&#xff0c;目前只有一个请求处理方法用于展示…

LInux-0.11

文章目录 前言学习资料正文 前言 B站视频链接 linux 0.11 内核代码 学习资料 正文 一个山区512字节

稀土/铜催化剂电催化CO2制C2+或CH4

在电化学CO2还原反应&#xff08;CO2RR&#xff09;中&#xff0c;合理调控反应途径以生成所需产物是最重要的挑战之一。基于此&#xff0c;中国科学院化学研究所韩布兴院士和朱庆宫研究员等人报道了一系列稀土-铜混合相催化剂&#xff0c;通过调整催化剂的组成和结构&#xff…

Nodejs的安装以及配置(node-v12.16.1-x64.msi)

Nodejs的安装以及配置 1、安装 node-v12.16.1-x64.msi点击安装&#xff0c;注意以下步骤 本文设置nodejs的安装的路径&#xff1a;D:\soft\nodejs 继续点击next&#xff0c;选中Add to PATH &#xff0c;旁边的英文告诉我们会把 环境变量 给我们配置好 当然也可以只选择 Nod…

工业自动化工厂PLC远程控制网关物联网应用

远程控制网关在工厂自动化领域中起到了至关重要的作用&#xff0c;特别是在工厂PLC数据通讯方面。它充当着数据传输的桥梁&#xff0c;连接了工厂中的各类设备和系统&#xff0c;实现了远程监控和控制的功能。本文将详细介绍远程控制网关在工厂PLC数据通讯中的应用。 远程控制网…

Hadoop知识点全面总结

文章目录 什么是HadoopHadoop发行版介绍Hadoop版本演变历史Hadoop3.x的细节优化Hadoop三大核心组件介绍HDFS体系结构NameNode介绍总结 SecondaryNameNode介绍DataNode介绍DataNode总结 MapReduce介绍分布式计算介绍MapReduce原理剖析MapReduce之Map阶段MapReduce之Reduce阶段 实…

Langchain-Chatchat-win10本地安装部署成功笔记(CPU)

Langchain-Chatchat&#xff08;原Langchain-ChatGLM&#xff09;基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM), local knowledge based LLM (like ChatGLM) QA app with langchain。 开源网址&#xff1a;https:…

leetcode周赛 第 370 场周赛

2923. 找到冠军 I 一场比赛中共有 n 支队伍&#xff0c;按从 0 到 n - 1 编号。 给你一个下标从 0 开始、大小为 n * n 的二维布尔矩阵 grid 。对于满足 0 < i, j < n - 1 且 i ! j 的所有 i, j &#xff1a;如果 grid[i][j] 1&#xff0c;那么 i 队比 j 队 强 &…

第五章:java构造方法与对象创建

系列文章目录 文章目录 系列文章目录前言一、构造方法&#xff08;构造器&#xff09;二、对象创建流程总结 前言 构造方法由程序自动调用&#xff0c;完成对象初始化。 一、构造方法&#xff08;构造器&#xff09; 构造方法又叫构造器(constructor)&#xff0c; 是类的一种…

将字符串转换为日期型对象date.fromisoformat(str)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为日期型对象 date.fromisoformat(str) 选择题 下列代码执行后&#xff0c;变量d的数据类型是? s 2023-11-01 d date.fromisoformat(s) print(f"【显示】s {s}") p…