Python 数据可视化 -- pillow 处理图像
Python 图像库(Python Image Library,PIL)为 Python 提供了图像处理能力。
PIL 官网:http://www.pythonware.com/products/pil/
PIL 在线手册:http://www.pythonware.com/library/pil/handbook/index.htm
pillow 是 PIL 的一个派生分支,更加活跃。
pillow 的 github 主页:https://github.com/python-pillow/Pillow
pillow 的文档:https://pillow.readthedocs.io/en/latest/handbook/index.html
安装 pillow
pip install pillow
使用 pillow
from PIL import Image
im = Image.open("hopper.ppm")
PIL 坐标系统假定坐标(0,0)位于左上角。
一个对图片进行过滤的例子
import os
from PIL import Image, ImageFilter class DemoPIL(object):
def __init__(self, image_file=None): # 构造器
self.fixed_filters = [ff for ff in dir(ImageFilter) if ff.isupper()] # dir(ImageFilter)返回ImageFilter类的属性。 isupper()是str的方法,当所有字母大写返回True
assert image_file is not None
assert os.path.isfile(image_file) is True # 断言文件是否存在
self.image_file = image_file
self.image = Image.open(self.image_file) # 返回一个 Image 对象实例 def _make_temp_dir(self):
from tempfile import mkdtemp
self.ff_tempdir = mkdtemp(prefix="ff_demo_", dir="C:\\Users\\mail.simcere.com\\Desktop") # 创建临时路径 def _get_temp_name(self, filter_name):
name, ext = os.path.splitext(os.path.basename(self.image_file))
newimage_file = name + "-" + filter_name + ext
path = os.path.join(self.ff_tempdir, newimage_file)
return path def _get_filter(self, filter_name):
real_filter = eval("ImageFilter." + filter_name)
return real_filter def apply_filter(self, filter_name):
print('Applying filter:' + filter_name)
filter_callable = self._get_filter(filter_name)
if filter_name in self.fixed_filters:
temp_img = self.image.filter(filter_callable)
else:
print("Can't apply non-fixed filter now.")
return temp_img def run_fixed_filters_demo(self):
self._make_temp_dir()
for ffilter in self.fixed_filters:
temp_img = self.apply_filter(ffilter)
temp_img.save(self._get_temp_name(ffilter)) # 保存图像
print("Images are in: {0}".format((self.ff_tempdir),)) if __name__ == '__main__':
# assert len(sys.argv) == 2
demo_image = "sunset.jpg"
demo = DemoPIL(demo_image) # 获取 DemoPIL 实例对象
demo.run_fixed_filters_demo()
处理某一特定文件夹下的所有图像文件
指定一个目标路径,用程序读取目标路径下的所有图像,并按给定比例调整他们的大小,然后把每一个文件存储到另一个指令文件夹下。
import os
import sys
from PIL import Image class Thumbnailer(object): def __init__(self, src_folder=None):
self.src_folder = src_folder
self.ratio = 0.3
self.thumbnail_folder = "thumbnails" def _create_thumbnails_folder(self):
thumb_path = os.path.join(self.src_folder, self.thumbnail_folder)
if not os.path.isdir(thumb_path):
os.makedirs(thumb_path) def _build_thumb_path(self, image_path):
root = os.path.dirname(image_path)
name, ext = os.path.splitext(os.path.basename(image_path))
suffix = ".thumbnail"
return os.path.join(root, self.thumbnail_folder, name + suffix + ext) def _load_files(self):
files = set()
for each in os.listdir(self.src_folder):
each = os.path.abspath(self.src_folder + '/' + each)
if os.path.isfile(each):
files.add(each)
return files def _thumb_size(self, size):
return (int(size[0]*self.ratio), int(size[1]*self.ratio)) def create_thumbnails(self):
self._create_thumbnails_folder()
files = self._load_files()
for each in files:
print("Processing: " + each)
try:
img = Image.open(each) # 返回 Image对象实例
thumb_size = self._thumb_size(img.size)
resized = img.resize(thumb_size, Image.ANTIALIAS) # 重新设置大小
savepath = self._build_thumb_path(each)
resized.save(savepath)
except IOError as ex:
print("Error: " + str(ex))
if __name__ == "__main__":
# assert len(sys.argv) == 2
src_folder = "images" # 这里提供相对路径
if not os.path.isdir(src_folder):
print("Error: Path '{0}' does not exists.".format((src_folder)))
sys.exit(-1)
thumbs = Thumbnailer(src_folder) # 得到 Thumbnailer的实例对象
thumbs.thumbnail_folder = "THUMBS" # 直接修改了对象的属性,破坏了数据封装的原则
thumbs.ratio =0.1
thumbs.create_thumbnails()
绘制带图像的图表
import matplotlib.pyplot as plt
from matplotlib._png import read_png
from matplotlib.offsetbox import TextArea, OffsetImage, AnnotationBbox def load_data():
import csv
with open('pirates_temperature.csv', 'r') as f:
reader = csv.reader(f)
header = next(reader)
datarows = []
for row in reader:
datarows.append(row)
return header, datarows def format_data(datarows):
years, temps, pirates = [], [], []
for each in datarows:
years.append(each[0])
temps.append(each[1])
pirates.append(each[2])
return years, temps, pirates if __name__ == '__main__':
fig = plt.figure(figsize=(16, 8))
ax = plt.subplot(111)
header, datarows = load_data()
xlabel, ylabel, _ = header # 将列表中的元素赋值到三个变量中
years, temperature, pirates = format_data(datarows)
title = 'Golbal Average Temperature vs. Number of Pirates'
plt.plot([int(i) for i in years], [float(i) for i in temperature], lw=2)
plt.xlabel(xlabel)
plt.ylabel(ylabel)
for x in range(len(years)):
xy = int(years[x]), float(temperature[x])
ax.plot(int(xy[0]), float(xy[1]), "ok")
pirate = read_png('tall-ship.png')
zoomc = int(pirates[x])*(1/90000.0)
imagebox = OffsetImage(pirate, zoom=zoomc) #
ab = AnnotationBbox(imagebox, xy, xybox=(-200.0*zoomc, 200.0*zoomc), xycoords='data', boxcoords="offset points", pad=0.1, arrowprops=dict(arrowstyle="->", connectionstyle="angle, angleA=0, angleB=-30, rad=3"))
ax.add_artist(ab)
no_pirates = TextArea(pirates[x], minimumdescent=False)
ab = AnnotationBbox(no_pirates, xy, xybox=(50.0, -25.0), xycoords = 'data', boxcoords='offset points', pad=0.3, arrowprops=dict(arrowstyle="->", connectionstyle="angle, angleA=0, angleB=-30, rad=3"))
ax.add_artist(ab)
plt.grid()
plt.xlim(1800, 2020)
plt.ylim(14, 16.5)
plt.title(title)
plt.show()
pirates_temperature.csv 中的内容
在有其它图形的图表中显示图像
操作步骤:
1. 加载图像
2. 从图像矩阵中分离出RGB通道
3. 配置图表和坐标轴(自区)
4. 绘制通道直方图
5. 绘制图像
import matplotlib.pyplot as plt
import matplotlib.image as mplimage
import matplotlib as mpl
import os class ImageViewer(object):
def __init__(self, imfile):
self._load_image(imfile)
self._configure()
self.figure = plt.gcf()
t = "Image: {0}".format(os.path.basename(imfile))
self.figure.suptitle(t, fontsize=20)
self.shape=(3, 2)
def _load_image(self, imfile):
self.im = mplimage.imread(imfile) # 读取图像 read an image from a file into an array
def _configure(self):
mpl.rcParams['font.size'] = 10
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.figsize'] = (9, 6)
mpl.rcParams['figure.subplot.top'] = 0.9
@staticmethod
def _get_chno(ch):
chmap = {'R': 0, 'G': 1, 'B':2}
return chmap.get(ch, -1)
def show_channel(self, ch):
bins = 256
ec = 'none'
chno = self._get_chno(ch)
loc = (chno, 1)
ax = plt.subplot2grid(self.shape, loc)
ax.hist(self.im[:, :, chno].flatten(), bins, color=ch, ec=ec, label=ch, alpha=0.7)
ax.set_xlim(0, 255)
plt.setp(ax.get_xticklabels(), visible=True)
plt.setp(ax.get_yticklabels(), visible=False)
plt.setp(ax.get_xticklines(), visible=True)
plt.setp(ax.get_yticklines(), visible=False)
plt.legend()
plt.grid(True, axis='y')
return ax
def show(self):
loc = (0, 0)
axim = plt.subplot2grid(self.shape, loc, rowspan=3)
axim.imshow(self.im)
plt.setp(axim.get_xticklabels(), visible=False)
plt.setp(axim.get_yticklabels(), visible=False)
plt.setp(axim.get_xticklines(), visible=False)
plt.setp(axim.get_yticklines(), visible=False)
axr = self.show_channel('R')
axg = self.show_channel('G')
axg = self.show_channel('B')
plt.show() if __name__ == '__main__':
im = 'yellow_flowers.jpg'
try:
iv = ImageViewer(im)
iv.show()
except Exception as ex:
print(ex)
使用 Basemap 在地图上绘制数据
Basemap 本身不进行任何绘图工作,它只是把给定的地理坐标转换到地图投影,并把数据传给 matplotlib 进行绘图。
basemap文档:https://matplotlib.org/basemap/api/basemap_api.html
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np map = Basemap(projection='merc', resolution='h',area_thresh=0.1, llcrnrlon=-126.619875, llcrnrlat=31.354158, urcrnrlon=-59.647219, urcrnrlat=47.517613)
map.drawcoastlines()
map.drawcountries()
map.fillcontinents(color='coral', lake_color='aqua')
map.drawmapboundary(fill_color='aqua')
map.drawmeridians(np.arange(0, 360, 30))
map.drawparallels(np.arange(-90, 90, 30))
plt.show()
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np map = Basemap(projection='merc', resolution='h', area_thresh=100, llcrnrlon=-126.619875, llcrnrlat=25, urcrnrlon=-59.647219, urcrnrlat=55)
shapeinfo = map.readshapefile('cities', 'cities')
x, y = zip(*map.cities)
city_names = []
for each in map.cities_info:
if each['COUNTRY'] != 'US':
city_names.append("")
else:
city_names.append(each['NAME'])
map.drawcoastlines()
map.drawcountries()
map.fillcontinents(color='coral', lake_color='aqua')
map.drawmapboundary(fill_color='aqua')
map.drawmeridians(np.arange(0, 360, 30))
map.drawparallels(np.arange(-90, 90, 30))
map.scatter(x, y, 25, marker='o', zorder=10)
for city_label, city_x, city_y, in zip(city_names, x, y):
plt.text(city_x, city_y, city_label)
plt.title('Cities in USA')
plt.show()
生成验证码图像
from PIL import Image, ImageDraw, ImageFont
import random
import string class SimpleCaptchaException(Exception):
pass class SimpleCaptcha(object):
def __init__(self, length=5, size=(200, 100), fontsize=36, random_text=None, random_bgcolor=None):
self.size = size
self.text = 'CAPTCHA'
self.fontsize = fontsize
self.bgcolor = 255
self.length = length
self.image = None
if random_text:
self.text = self._random_text()
if not self.text:
raise SimpleCaptchaException("field text must not be empty.")
if not self.size:
raise SimpleCaptchaException('Size must not be empty.')
if not self.fontsize:
raise SimpleCaptchaException('Font size must be defined.')
if random_bgcolor:
self.bgcolor = self._random_color()
def _center_coords(self, draw, font):
width, height = draw.textsize(self.text, font)
xy = (self.size[0] - width)/2.0, (self.size[1] - height)/2.0
return xy
def _add_noise_dots(self, draw):
size = self.image.size
for _ in range(int(size[0]*size[1]*0.1)):
draw.point((random.randint(0, size[0]), random.randint(0, size[1])), fill='white')
return draw
def _add_noise_lines(self, draw):
size = self.image.size
for _ in range(8):
width = random.randint(1, 2)
start = (0, random.randint(0, size[1]-1))
end = (size[0], random.randint(0, size[1]-1))
draw.line([start, end], fill="white", width=width)
for _ in range(8):
start = (-50, 50)
end = (size[0] + 10, random.randint(0, size[1] + 10))
draw.arc(start + end, 0, 360, fill='white')
return draw
def _random_text(self):
letters = string.ascii_lowercase + string.ascii_uppercase
random_text = ""
for _ in range(self.length):
random_text += random.choice(letters)
return random_text
def _random_color(self):
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
return (r, g, b)
def get_captcha(self, size=None, text=None, bgcolor=None):
if text is not None:
self.text = text
if size is not None:
self.size = size
if bgcolor is not None:
self.bgcolor = bgcolor
self.image = Image.new('RGB', self.size, self.bgcolor) #
font = ImageFont.truetype('fonts/Vera.ttf', self.fontsize)
draw = ImageDraw.Draw(self.image)
xy = self._center_coords(draw, font)
draw.text(xy=xy, text=self.text, font=font)
draw = self._add_noise_dots(draw)
draw = self._add_noise_lines(draw)
self.image.show()
return self.image, self.text if __name__ == "__main__":
sc = SimpleCaptcha(length=7, fontsize=36, random_text=True, random_bgcolor=True)
sc.get_captcha()
Python 数据可视化 -- pillow 处理图像的更多相关文章
- Python数据可视化编程实战pdf
Python数据可视化编程实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1vAvKwCry4P4QeofW-RqZ_A 提取码:9pcd 复制这段内容后打开百度 ...
- 【数据科学】Python数据可视化概述
注:很早之前就打算专门写一篇与Python数据可视化相关的博客,对一些基本概念和常用技巧做一个小结.今天终于有时间来完成这个计划了! 0. Python中常用的可视化工具 Python在数据科学中的地 ...
- python 数据可视化
一.基本用法 import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1,1,50) # 生成-1到1 ,平分50个点 ...
- Python数据可视化基础讲解
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:爱数据学习社 首先,要知道我们用哪些库来画图? matplotlib ...
- 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化
<数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...
- python数据可视化编程实战PDF高清电子书
点击获取提取码:3l5m 内容简介 <Python数据可视化编程实战>是一本使用Python实现数据可视化编程的实战指南,介绍了如何使用Python最流行的库,通过60余种方法创建美观的数 ...
- Python数据可视化 -- Wordcloud
Python数据可视化 -- Wordcloud 安装 启动命令行,输入:pip install wordcloud word cloud 库介绍 及简单使用 wordcloud库,可以说是pytho ...
- Python数据可视化编程实战——导入数据
1.从csv文件导入数据 原理:with语句打开文件并绑定到对象f.不必担心在操作完资源后去关闭数据文件,with的上下文管理器会帮助处理.然后,csv.reader()方法返回reader对象,通过 ...
- Python数据可视化——使用Matplotlib创建散点图
Python数据可视化——使用Matplotlib创建散点图 2017-12-27 作者:淡水化合物 Matplotlib简述: Matplotlib是一个用于创建出高质量图表的桌面绘图包(主要是2D ...
随机推荐
- sentry的安装和使用以及各种问题处理
官方的git地址:https://github.com/getsentry/onpremise 需要先安装docker 1.10版本以上 假设你已经安装完docker,那么接下来 安装docker-c ...
- tornado架构分析3 options.py中基础类_Option
1 数据清洗 option里面最重要的方法就是parse,在这里,parse函数的一开始就调用了后面的子函数_parse_datetime,_parse_timedelta,_parse_bool,_ ...
- 201772020113李清华《面向对象程序设计(java)》第十周学习总结
1.实验目的与要求 (1) 理解泛型概念: (2) 掌握泛型类的定义与使用: (3) 掌握泛型方法的声明与使用: (4) 掌握泛型接口的定义与实现: (5)了解泛型程序设计,理解其用途. 2.实验内容 ...
- JUnit4源码学习笔记
先上一个在Spring-test下运行的调用栈 自底向上: JUnitStarter IDEA对JUnit的支持,调用JUnitCore.run(Runner),将注解@RunWith指定的Runne ...
- MAIL服务器搭建
一,邮件服务: 优 点 缺 点 应 用 sendmail 有点年代久远,稳定功能多 太过于臃肿,配置文件多且繁琐 6以前默认 postfix 优点更稳定,且交轻便 发布年限较短,市场占有率低 ...
- Django ORM queryset object 解释(子查询和join连表查询的结果)
#下面两种是基于QuerySet查询 也就是说SQL中用的jion连表的方式查询books = models.UserInfo.objects.all() print(type(books)) --- ...
- Jeecg-Boot 1.0版本发布,企业级快速开发平台
Jeecg-Boot 一款基于代码生成器的J2EE快速开发框架! 采用前后端分离技术: SpringBoot,Mybatis-plus,Shiro,JWT,Vue & Ant Design. ...
- Spark-shell错误:Missing Python executable 'python', defaulting to ...
最近博主因为学习<云计算导论>一课,需要在Windows上搭建Saprk,故在网上找了相关教程搭建,步骤如下: 1. Scala 2.Spark 3.Handoop 但是不管博主怎么修正, ...
- python中logging模块
1. 日志的等级 DEBUG.INFO.NOTICE.WARNING.ERROR.CRITICAL.ALERT.EMERGENCY 级别 何时使用 DEBUG 详细信息,典型地调试问题时会感兴趣. 详 ...
- python中的函数和变量
本节内容 函数的定义方法 函数功能 函数的返回值 函数的形参与实参 全局变量与局部变量 递归 函数的作用域 匿名函数lambda 函数式编程 常用内置函数 其他内置函数 函数 函数的定义方法 函数就相 ...