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 较大时,整体画面灰度值较深,近似于浮雕效果。
相关文章:
Python----图像的手绘效果
图像的数组表示 图像是有规则的二维数据,可以用numpy 库将图像转换成数组对象 : from PIL import Image import numpy as np imnp.array(Image.open("D://np.jpg")) print(im.shape,im.dtype)结果: 图像转换对应的ndarray 类型是3 维数据&am…...
Android13集成paho.mqtt.android启动异常
项目中原依赖是: implementation(org.eclipse.paho:org.eclipse.paho.android.service:1.1.1) {exclude module: support-v4transitive true } implementation org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5在Android10系统运行正常,能够连接…...
STM框架之按键扫描新思路
STM框架之按键扫描新思路 引入代码展示思路分析 我们学习了定时器实现毫秒级/秒级任务框架,这期我们基于任务框架学习按键扫描新思路。 引入 在按键扫描的过程中,最重要的一步就是按键消抖,解决的方法最简单粗暴的就是先扫描一次按键状态&am…...
Linux服务器挂载另一台服务器的文件夹(mount)
我们实际应用中,会常遇到多个Linux服务器之间需要频繁共享文件,或者是一台服务器需要使用另一台服务器的闲置磁盘空间。最方便的方法就是挂载另一台linux文件夹(文件服务器),通俗理解为:当前服务器远程连接…...
剑指offer --- 用两个栈实现队列的先进先出特性
目录 前言 一、读懂题目 二、思路分析 三、代码呈现 总结 前言 当我们需要实现队列的先进先出特性时,可以使用栈来模拟队列的行为。本文将介绍如何使用两个栈来实现队列,并给出具体的思路和代码实现。 一、读懂题目 题目:用两个栈实现一…...
流媒体协议
◆ RTP(Real-time Transport Protocol),实时传输协议。 ◆ RTCP(Real-time Transport Control Protocol),实时传输控制协议。 ◆ RTSP(Real Time Streaming Protocol),实时流协议。 ◆ RTMP(Real Time Messaging Protocol),实时…...
ClickHouse的分片和副本
1.副本 副本的目的主要是保障数据的高可用性,即使一台ClickHouse节点宕机,那么也可以从其他服务器获得相同的数据。 Data Replication | ClickHouse Docs 1.1 副本写入流程 1.2 配置步骤 (1)启动zookeeper集群 (2&…...
C语言编程陷阱(五)
陷阱21:不要使用逗号运算符代替分号 C语言中,我们可以使用分号来结束一个语句,比如a = b;,这样可以让编译器知道语句的边界,以及执行的顺序。但是,如果我们想要在一个语句中执行多个表达式,就可以使用逗号运算符,比如a = (b = c, c + 1);,这样可以让编译器按照从左到右…...
chardet检测文件编码,使用生成器逐行读取文件
detect_encoding 函数使用 chardet 来检测文件的编码。然后,在 process_large_file 函数中,根据检测到的编码方式打开文件。这样,你就能够更准确地处理不同编码的文件。 import chardetdef detect_encoding(file_path):with open(file_path,…...
html所有标签和DOCTYPE的总结
一、DOCTYPE 1. 意义 DOCTYPE是一种标准通用标记语言的文档类型声明,告诉标准通用标记语言解析器它应该使用什么样的文档类型定义来解析文档。 2. 应用 现在,我们需要告诉标准通用标记语言解析器,我们接下去要用html来编写代码了。 <…...
2023年11月15号期中测验判断题(Java)
1-1 局部变量可以与成员变量重名。 正确答案:T 解释: 局部变量可以和成员变量重名,通常,为了区分局部变量和成员变量,会使用this关键字(C称this指针,python是self关键字)来特别声…...
基于 selenium 实现网站图片采集
写在前面 有小伙伴选题,简单整理理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对…...
vue3相关内容
ref声明/赋值 操作基本类型数据 string number // 引入方法 import {ref} from vue // 声明变量 const name ref(A) // 修改值 name.value Breactive声明/赋值 操作引用类型数据 array object proxy不能直接赋值,会破坏响应式对象 // 引入方法 import {reacti…...
AWTK实现汽车仪表Cluster/DashBoard嵌入式GUI开发(七):FreeRTOS移植
前言: 一般的GUI工程都需要一个操作系统,可能是linux,重量级的,也可能是FreeRTOS,轻量级的。 一句话理解那就是工程就是FreeRTOS task任务的集合。 一个main函数可以看到大框架: 很显然,除了第一个是硬件配置的初始化,中间最重要的部分就是要创建任务,把AWTK的应用…...
《洛谷深入浅出进阶篇》P1995 程序自动分析——并查集,离散化
上链接:P1955 [NOI2015] 程序自动分析 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/problem/P1955 上题干: 首先给你一个整数t,代表t次操作。 每一次操作包含以下内容: 1.给你一个整数n,让…...
基于单片机的自动循迹小车(论文+源码)
1.系统设计 此次基于单片机的自动循迹小车的设计系统,结合循迹模块来共同完成本次设计,实现小车的循迹功能,其其整体框架如图2.1所示。其中,采用STC89C52单片机来作为核心控制器,负责将各个传感器等模块链接起来&…...
linux系统中安装python到指定目录
Linux系统中安装python 下载Python源码包 根据服务器系统和需要的Python版本,在Python官网下载对应的Python源码包。 安装依赖(需要权限) yum install gcc gcc-c patch libffi-devel python-devel zlib-devel bzip2-devel openssl-devel…...
分布式事务 - seata安装
分布式事务 - seata 一、本地事务与分布式事务 1.1、本地事务 本地事务,也就是传统的单机事务。在传统数据库事务中,必须要满足四个原则(ACID)。 1.2、分布式事务 分布式事务,就是指不是在单个服务或单个数据库架构…...
CentOS to 浪潮信息 KeyarchOS 迁移体验与优化建议
浪潮信息KeyarchOS简介 KeyarchOS即云峦操作系统(简称KOS), 是浪潮信息研发的一款面向政企、金融等企业级用户的 Linux 服务器操作系统。它基于Linux内核、龙蜥等开源技术,支持x86、ARM 等主流架构处理器,其稳定性、安全性、兼容性和性能等核心能力均已…...
Go解析soap数据和修改其中数据
一、解析soap数据 package main import ("fmt" "encoding/xml" ) type Envelope struct { XMLName xml.Name Header Header } type Header struct { XMLName xml.Name xml:"Header" Security Security xml:"Security" } type Secu…...
别再傻傻分不清了!IM和RTC到底差在哪?从微信聊天到腾讯会议的技术选择
IM与RTC技术选型指南:从协议栈到商业场景的深度解析 当你的产品经理在白板上画出一个"消息气泡"和一个"视频通话图标"时,技术团队首先需要面对的灵魂拷问是:这到底该用IM架构还是RTC架构?2019年某在线教育初创…...
高分辨率路面缺陷检测数据集:道路健康状态自动监测的关键资源
路面缺陷检测数据集yolo掌握道路健康状态对于维护和规划都至关重要。 本数据集精选6100张高清图像,专门标注了道路表面的四种常见缺陷,包括鳄鱼状裂纹、横向裂纹、纵向裂纹和坑洞,旨在为道路维护和自动化检测提供强有力的数据支持。 图像集已…...
陀螺匠企业助手-产品
1. 功能说明维护出售产品的基本信息数据,支持在添加商机/合同中进行选择。2. 进入产品页面路径:客户>产品管理>产品3. 新增产品功能说明:维护产品信息,添加完成的产品信息,可以在添加商机/合同中进行选择。新增产…...
Linux DRM子系统深度解析:如何为240x240 SPI屏编写自定义KMS驱动?
Linux DRM子系统实战:为240x240 SPI屏构建原子化KMS驱动 当一块小巧的240x240 SPI屏幕遇上Linux DRM显示框架,开发者面临的不仅是硬件接口的适配,更是一场关于现代显示架构的深度对话。本文将带您穿透DRM子系统的抽象层,从KMS核心…...
LangGraph实战:5分钟给你的AI助手装上‘对话记忆’,告别每轮都是新朋友
LangGraph实战:5分钟为AI助手构建对话记忆系统 每次和AI对话都像初次见面?这个问题困扰着许多开发者。想象一下,你告诉助手"我叫Alex",下一句问"你知道我的名字吗?",它却一脸茫然地回答…...
ente/auth缓存机制详解:提高系统响应速度
ente/auth缓存机制详解:提高系统响应速度 【免费下载链接】ente 完全开源,端到端加密的Google Photos和Apple Photos的替代品 项目地址: https://gitcode.com/GitHub_Trending/en/ente ente/auth作为专注于移动设备的两步验证(2FA&…...
从‘调不出来’到‘一次过流片’:折叠共源共栅放大器设计中那些没人告诉你的‘坑’与调试技巧
从‘调不出来’到‘一次过流片’:折叠共源共栅放大器设计中那些没人告诉你的‘坑’与调试技巧 在模拟电路设计的江湖里,折叠共源共栅(Folded Cascode)放大器就像一位身怀绝技却性格古怪的武林高手——性能强悍但极难驯服。许多工…...
Qwen3-32B-Chat API优化:降低OpenClaw任务Token消耗的5个技巧
Qwen3-32B-Chat API优化:降低OpenClaw任务Token消耗的5个技巧 1. 为什么需要关注Token消耗? 当我第一次在本地部署OpenClaw对接Qwen3-32B-Chat模型时,最让我震惊的不是它的推理能力,而是执行简单自动化任务后Token消耗的速度。一…...
文明降级运动:回归纸笔抵抗AI监控
在AI技术席卷软件测试领域的浪潮中,一个看似“倒退”却极具战略意义的趋势正在兴起——文明降级运动。这场运动的核心是主动回归纸笔工具,以抵抗AI监控带来的系统性风险。作为软件测试从业者,我们身处技术前沿,见证了AI在缺陷预测…...
基于扩散模型的歌声合成技术:DiffSinger架构解析与实践应用
基于扩散模型的歌声合成技术:DiffSinger架构解析与实践应用 【免费下载链接】DiffSinger 项目地址: https://gitcode.com/gh_mirrors/dif/DiffSinger DiffSinger作为开源歌声合成领域的创新解决方案,通过扩散模型与深度学习技术的深度融合&#…...
