用python画素描画方式有多种,这里给大家分享常见的且操作简单的两种实现方式,一种用pillow库,一种用opencv库,这两个库的具体使用可百度,网上很多教程,这里不再赘述。
一、pillow实现方法
1. 先在cmd上安装pillow库:
pip install pillow
2. 首先用convert('L')方法将彩色RGB图转换为灰度图
img = Image.open(pth)
out_img = img.convert('L') # 图片转换为灰度模式
width, height = img.size
pixel = img.load()
3. 设定一个阈值,当(x,y)与(x+1,y+1)点灰度值差值大于设定的阈值,即可判定(x,y)的像素点为轮廓。可通过设置阈值的大小,来改变素描的呈现效果。
threshold = 16 #设定阈值
for w in range(width):
for h in range(height):
if w == width - 1 or h == height - 1:
continue
xy = pixel[w, h]
x1y1 = pixel[w + 1, h + 1]
diff = abs(xy - x1y1)
if diff >= threshold:
pixel[w, h] = 0 #灰度越大越白,代表是轮廓
else:
pixel[w, h] = 255 #灰度越大越白,代表是轮廓
4. 保存图片
img.save(out_name)
5. 源代码
from PIL import Image
import easygui as eg
import os
def analyze(img, threshold):
if threshold < 0:
threshold = 0
if threshold > 100:
threshold = 100
width, height = img.size
img = img.convert('L') # 转为灰度图
pixel = img.load() # 获取灰度值
for w in range(width):
for h in range(height):
if w == width - 1 or h == height - 1:
continue
xy = pix[w, h]
x1y1 = pix[w + 1, h + 1]
diff = abs(xy - x1y1)
if diff >= threshold:
pixel[w, h] = 0 #灰度越大越白,代表是轮廓
else:
pixel[w, h] = 255 #灰度越大越白,代表是轮廓
return img
def main():
threshold = 16
pth = eg.fileopenbox(title='请打开要转换的图片') # 打开图片
dir = os.path.dirname(pth) # 返回图片所在的路径
ori_name = os.path.basename(pth) # 返回图片名称及扩展名
name = os.path.splitext(ori_name)[0] # 返回图片名称
geshi = os.path.splitext(ori_name)[1] # 返回图片的扩展名
out_name = os.path.join(dir, name +'(素描版)' + geshi) # 输出的名字及路径
img = Image.open(pth)
img = analyze(img,threshold)
img.save(out_name)
if __name__=='__main__':
main()
二、opencv实现方法
1. 先在cmd上安装opencv-python库:
pip install opencv-python
2. 打开图片
img = cv2.imread(pth)
3. 将图片转换成为灰度图
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
4. 使用高斯滤波函数对灰度图进行模糊化操作,参数ksize表示高斯核的大小,sigmaX和sigmaY分别表示高斯核在 X 和 Y 方向上的标准差。可以通过调整ksize来呈现不同效果。
img_blur = cv2.GaussianBlur(img_gray, ksize=(81, 81),sigmaX=0, sigmaY=0)
5. 使用cv2.divide()方法对原图和模糊图像进行融合,找到两幅图之间有明显差异的部分,即为图片轮廓。
img_out=cv2.divide(img_gray, img_blur, scale=255)
6. 保存图片
cv2.imwrite(out_name, img_out)
7. 源代码
import easygui as eg
import os
import cv2
def main():
pth = eg.fileopenbox(title='请打开要转换的图片') # 打开图片
dir = os.path.dirname(pth) # 返回图片所在的路径
ori_name = os.path.basename(pth) # 返回图片名称及扩展名
name = os.path.splitext(ori_name)[0] # 返回图片名称
geshi = os.path.splitext(ori_name)[1] # 返回图片的扩展名
out_name = os.path.join(dir, name +'(sumiao)' + geshi) # 输出的名字及路径
img = cv2.imread(pth)
img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
img_blur = cv2.GaussianBlur(img_gray, ksize=(11, 11),sigmaX=0, sigmaY=0)
img_out=cv2.divide(img_gray, img_blur, scale=255)
cv2.imwrite(out_name, img_out)
if __name__=='__main__':
main()
两种方法的素描图的呈现效果不同,opencv相比显示的柔和写,图形显示更加柔和细腻。