Python----图像的手绘效果

图像的数组表示

图像是有规则的二维数据,可以用numpy 库将图像转换成数组对象 :

from PIL import Image
import numpy as np
im=np.array(Image.open("D://np.jpg"))
print(im.shape,im.dtype)

结果:

图像转换对应的ndarray 类型是3 维数据,如(569, 813, 3),其中,前两维表示图像的长度宽度,单位是像素,第三维表示每个像素点的RGB 值,每个RGB 值是一个单字节整数。

像素处理
一.convert()函数:

PIL 库包括图像转换函数,能够改变图像单个像素的表示形式。使用convert()函数

lmage.convert(mode) #使用不同的参数,转换图像为新的模式,返回新副本 

1.RGB模式("RGB"):RGB模式是最常见的彩色图像模式,它使用红色、绿色和蓝色三个通道来表示图像的颜色。

2.’L’模式表示将像素从RGB 的3 字节形式转变为单一数值形式,这个数值范围在0 到255,表示灰度色彩变化。

3.RGBA模式("RGBA"):RGBA模式也是一种彩色图像模式,与RGB模式类似,但多了一个Alpha通道。Alpha通道表示图像的透明度,取值范围为0到255,0代表完全透明,255代表完全不透明。

4.CMYK模式("CMYK"):CMYK模式主要用于印刷领域,使用青色、品红色、黄色和黑色四个通道来表示颜色。它与RGB模式的颜色表示方式不同。

5.HSV模式("HSV"):HSV模式是一种基于色调(Hue)、饱和度(Saturation)和亮度(Value)的颜色表示方式。它可以更直观地表示颜色的属性。

以"L"类型举例:

from PIL import Image
import numpy as np
im = np.array(Image.open("D://np.jpg").convert('L'))
print(im.shape, im.dtype)

结果:

此时,图像从彩色变为带有灰度的黑白色。转换后,图像的ndarray 类型变为二维数据,每个像素点色彩只由一个整数表示。

 

二.numpy访问像素值

通过对图像的数组转换,可以利用numpy 访问图像上任意像素值,例如,获取访问位于坐标(20, 300)像素的颜色值或获取图像中最大和最小的像素值。也可以采用切片方式获取指定行或列的元素值,甚至修改这些值。

>>> im[20][300]
28
>>> print(int(im.min()),int(im.max()))
0 255
>>> print(im[10,:])
[ 2  4  6  7  7  ... 13 12]

 

三.图像变换

将图像读入ndarray 数组对象后,可以通过任意数学操作来获取相应的图像变换。以灰度变换为例,分别对灰度变化后的图像进行反变换、区间变化和像素值平方处理。

注:有些数学变换会改变图像的数据类型,如变成浮点数等,所以在重新生成PIL 图像前要先将数据类型通过numpy.uint()变换成整数

>>>im0 = np.array(Image.open('np.jpg').convert('L'))

>>>im1 = 255 - im0 #反变换

>>>im2 = (100/255)*im0 + 150 #区间变换

>>>im3 = 255*(im1/255)**2 #像素平方处理

>>>pil_im = Image.fromarray(np.uint(im1)) #对im1,im2,im3执行

>>>pil_im.show()

原图:

 

处理过后:

四.手绘效果的实现

- 为了实现手绘风格,即黑白轮廓描绘,首先需要读取原图像的明暗变化,即灰度值。从直观视觉感受上定义,图像灰度值显著变化的地方就是梯度,它描述了图像灰度变化的强度。

- 通常可以使用梯度计算来提取图像轮廓,numpy 中提供了直接获取灰度图像梯度的函数gradient(),传入图像数组表示即可返回代表x 和y 各自方向上梯度变化的二维元组。

numpy.gradient(f, *varargs, axis=None, edge_order=1)

f,包含标量函数样本的n维数组

varargs:标量或数组列表,可选

edge_order:{1,2}, 可选。使用n阶精确的边界差来计算梯度。默认值:1。

axis:沿着给定的轴计算梯度

返回: f关于每一维的梯度

将光源定义为三个参数:方位角vec_az、俯视角vec_el 和深度权值depth。两个角度的设定和单位向量构成了基础的柱坐标系,体现物体相对于虚拟光源的位置。

通过np.gradient()函数计算图像梯度值作为新色彩计算的基础。为了更直观的进行计算,可以把角度对应的柱坐标转化为xyz 立体坐标系。dx、dy、dz 是像素点在施加模拟光源后在x、y、z 方向上明暗度变化的加权向量。

A 是梯度幅值,也是梯度大小。各个方向上总梯度除以幅值得到每个像素单元的梯度值。利用每个单元的梯度值和方向加权向量合成灰度值,clip 函数用预防溢出,并归一化到0‐255 区间。最后从数组中恢复图像并保存。

from PIL import Image
import numpy as npim = Image.open("D://np.jpg").convert('L')
a = np.asarray(im).astype('float')depth = 10.0  # 设置深度值(0-100)
grad = np.gradient(a)  # 取图像灰度的梯度值
grad_x, grad_y, *_ = grad  # 分别取横纵图像梯度值
grad_x = grad_x * depth / 100
grad_y = grad_y * depth / 100vec_el = np.pi / 2.2  # 光源的俯视角度,弧度值
vec_az = np.pi / 4  # 光源的方位角度,弧度值
dx = np.cos(vec_el) * np.cos(vec_az)  # 光源对x轴的影响
dy = np.cos(vec_el) * np.sin(vec_az)  # 光源对y轴的影响
dz = np.sin(vec_el)  # 光源对z轴的影响A = np.sqrt(grad_x**2 + grad_y**2 + 1.0)
uni_x = grad_x / A
uni_y = grad_y / A
uni_z = 1.0 / Aa2 = 255 * (dx * uni_x + dy * uni_y + dz * uni_z)  # 光源归一化
a2 = a2.clip(0, 255)im2 = Image.fromarray(a2.astype('uint8'))  # 重构图像
im2.save('D://npHandDraw2.jpg')  # 保存图像

原图:

结果:

 可以进入如下链接学习:

Python实现图像手绘效果的方法详解_python_脚本之家 (jb51.net)

手绘图像的基本思想是利用像素之间的梯度值(而不是像素本身)重构每个像素值。为了体现光照效果,设计一个光源,建立光源对各点梯度值的影响函数,进而运算出新的像素值,从而体现边界点灰度变化,形成手绘效果。

具体来说,为了更好体现立体感,增加一个z方向梯度值,并给x 和y 方向梯度值赋权值depth。这种坐标空间变化相当于给物体加上一个虚拟光源,根据灰度值大小模拟各部分相对于人视角的远近程度,使画面显得有“深度”。

在利用梯度重构图像时,对应不同梯度取0‐255 之间不同的灰度值,depth 的作用就在于调节这个对应关系。depth 较小时,背景区域接近白色,画面显示轮廓描绘;depth 较大时,整体画面灰度值较深,近似于浮雕效果。

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

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

相关文章

我的 2023 秋招总结,拿到了大厂offer

2023秋招小结 前言 & 介绍 作为2024年毕业的学生,在2023年也就是今年秋招。 现在秋招快结束了,人生可能没有几次秋招的机会(应该就一次,最多两次吧哈哈),也有一点感悟,所以小小总结一下。…

如何用继承和多态来打印个人信息

1 问题 在python中的数据类型中,我们常常运用继承和多态。合理地使用继承和多态可以增强程序的可扩展性使代码更简洁。那么如何使用继承和多态来打印个人信息? 2 方法 打印基本信息添加子类,再定义一个class,可以直接从Person类继…

网络规模与性能优化的一篇随笔

本周写篇轻松的话题,注意信息传输的尺度和缩放比例,写篇随笔。 控制面和数据面随规模缩放的影响,举几个例子就能说明白。 CSMA/CD,控制面和数据面在一起,控制信息交互时延和数据面时延在同一尺度时,就到了…

ASP.NET限流器的简单实现

一、滑动时间窗口 我为RateLimiter定义了如下这个简单的IRateLimiter接口,唯一的无参方法TryAcquire利用返回的布尔值确定当前是否超出设定的速率限制。我只提供的两种基于时间窗口的实现,如下所示的基于“滑动时间窗口”的实现类型SliddingWindowRateL…

Java编程中,异步操作流程中,最终一致性以及重试补偿的设计与实现

一、背景 微服务设计中,跨服务的调用,由于网络或程序故障等各种原因,经常会出现调用失败而需要重试。另外,在异步操作中,我们提供接口让外部服务回调。回调过程中,也可能出现故障。 这就要求我们主动向外…

vim批量多行缩进调整

网上其他教程&#xff1a; ctrl v 或者 v进行visual模式按方向键<&#xff0c;>调整光标位置选中缩进的行Shift > &#xff08;或者 Shift < &#xff09;进行左右缩进。 我只想说&#xff0c;乱七八糟&#xff0c;根本不管用 本文教程&#xff1a; 增加缩进…

物联网网关在工业行业的应用案例

物联网网关在工业行业的应用案例 随着物联网技术的不断发展&#xff0c;物联网网关在工业行业的应用越来越广泛。本文将介绍一个物联网网关在工业行业的应用案例&#xff0c;以期为相关领域的研究和实践提供借鉴和启示。 一、案例背景 某大型制造企业是一家全球知名的汽车制…

高防IP是什么,高防IP有什么作用?

什么是高防IP&#xff1f; 高防IP是一款专业解决大流量攻击的安全防护产品&#xff0c;支持网站和非网站类业务的DDoS、CC防护&#xff0c;用户通过配置转发规则&#xff0c;将攻击流量引至高防IP并清洗&#xff0c;保障业务稳定可用&#xff0c;具有灾备能力&#xff0c;线路…

剑指offer --- 用两个栈实现队列的先进先出特性

目录 前言 一、读懂题目 二、思路分析 三、代码呈现 总结 前言 当我们需要实现队列的先进先出特性时&#xff0c;可以使用栈来模拟队列的行为。本文将介绍如何使用两个栈来实现队列&#xff0c;并给出具体的思路和代码实现。 一、读懂题目 题目&#xff1a;用两个栈实现一…

[ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧

文章目录 一、Amazon CodeWhisperer 简介1.1 CodeWhisperer 是什么1.2 Amazon CodeWhisperer 是如何工作的 二、Amazon CodeWhisperer 的优势和功能2.1 Amazon CodeWhisperer 的优势2.2 Amazon CodeWhisperer 的代码功能 三、Amazon CodeWhisperer 安装3.1 安装到 IntelliJ IDE…

计算数组中每个元素的立方根numpy.cbrt()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 计算数组中每个元素的立方根 numpy.cbrt() [太阳]选择题 请问以下代码中执行语句输出结果是&#xff1f; import numpy as np a np.array([1, 8, 27]) print("【显示】a ",a) pr…

synchronized jvm实现思考

底层实现时&#xff0c;为什么使用了cxq队列和entryList双向链表&#xff1f;这里为什么不跟AQS中使用一个队列就行了&#xff0c;加了一个entryList的目的是为了什么&#xff1f; 个人理解这里多一个entryList&#xff0c;可能是用于减少频繁的cas操作。假设存在很多锁竞争时&…

【Linux】gcc/g++ gdb 使用

目录 1&#xff0c;背景知识 2&#xff0c;gcc 如何完成 1&#xff0c;预处理(进行宏替换) 2&#xff0c;编译&#xff08;生成汇编&#xff09; 3&#xff0c;汇编&#xff08;生成机器可识别代码&#xff09; 4&#xff0c;连接&#xff08;生成可执行文件或库文件&…

rk3588 usb网络共享连接

出门在外总会遇到傻 X 地方 没有能连接公网的 网口给香橙派连网 而我的香橙派5plus 没有wifi模块。。。话不多说 在手机上看一眼手机的mac地址&#xff0c; 在rk3588 上执行以下命令&#xff1a; sudo ifconfig usb0 down sudo ifconfig usb0 hw ether 58:F2:FC:5D:D4:7A //该m…

浅谈基于云计算的环境智能监控系统

随着经济的飞速发展&#xff0c;环境污染也越来越严重&#xff0c;环境监控成为了政府与社会关注的焦点。本文提出了一种基于云计算的环境智能监控系统——EasyCVR&#xff0c;该系统综合应用了传感器、云计算、大数据、人工智能等技术&#xff0c;具有实时、准确、高效的监控能…

ChatGPT简介及基本概念

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列点击跳转>ChatGPT和AIGC &#x1f449;关于作者 专…

HarmonyOS开发:动态共享包的依赖问题

一、共享包的依赖方式 在需要依赖的模块包目录下oh-package.json5文件中添加依赖&#xff1a; "dependencies": {"ohos/srpaasUI": "file:../../srpaasUI","ohos/srbusiness": "file:../../feature/srbusiness"} 引入之后…

Java源码分析:Guava之不可变集合ImmutableMap的源码分析

原创/朱季谦 一、案例场景 遇到过这样的场景&#xff0c;在定义一个static修饰的Map时&#xff0c;使用了大量的put()方法赋值&#xff0c;就类似这样—— public static final Map<String,String> dayMap new HashMap<>(); static {dayMap.put("Monday&q…

音频类型转换工具-可执行文件exe/dmg制作

朋友车载音乐需要MP3格式&#xff0c;想要个批量转换工具 准备工作 brew install ffmpeg --HEAD或者官网下载安装ffmpeg并配置环境conda install ffmpeg 或者pip install ffmpeg-python 音频类型转换程序.py文件 exe文件在windows下打包&#xff0c;dmg在macos下打包&#…

2023_“数维杯”问题B:棉秸秆热解的催化反应-详细解析含代码

题目翻译&#xff1a; 随着全球对可再生能源需求的不断增加&#xff0c;生物质能作为一种成熟的可再生能源得到了广泛的关注。棉花秸秆作为一种农业废弃物&#xff0c;因其丰富的纤维素、木质素等生物质成分而被视为重要的生物质资源。虽然棉花秸秆的热解可以产生各种形式的可…