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 ...
随机推荐
- QT 二维图形 原理、发展及应用
转载自 网易博客:sun的博客 http://zhouyang340.blog.163.com/blog/static/3024095920126710504178/ 2D绘图 Qt4中的2D绘图部分 ...
- 每日一练之排序算法(P1097 统计数字)
某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5×10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. ...
- 【396】python 递归练习题(COMP9021)
Merging two strings into a third one Say that two strings s1 and s2 can be merged into a third strin ...
- django restfulwork 源码剖析
概要: 1.restful 规范(建议); 2. django rest framework框架 内容回顾: 1.开发模式; - 普通开发模式(前后端放在一起写) - 前后端分离 好处: 后端一套,前 ...
- KeyValuePair 和 Dictionary 的关系和区别
KeyValuePair 和 Dictionary 的关系 1.KeyValuePair a.KeyValuePair 是一个结构体(struct): b.KeyValuePair ...
- 【C++】纯C++实现http打开网页下载内容的功能
#include "stdafx.h" #include <windows.h> #include <iostream> #include "Wi ...
- pyton 模块之 pysmb 文件上传(windows)
#!/usr/bin/env python #coding:utf-8 from smb.SMBConnection import SMBConnection from nmb.NetBIOS imp ...
- 通过.ibd和.frm恢复mysql数据
背景:因为机器损坏,数据库的索引文件什么的都损坏了.只留下了一个mysql的data目录… 此方法恢复数据的前提:建表用的innodb索引 备注:如果mysql的目录还都在,可以先尝试,将mysq ...
- 第一次博客作业 <西北师范大学| 周安伟>
1.助教博客链接:https://home.cnblogs.com/u/zaw-315/ 2.本周点评的作业数:3份,有留言互动. 3.本周点评有困难的地方: https://www.cnblogs ...
- Polar Code(1)极化码SC译码迭代公式的理解
采用对数似然比求解的迭代公式推导: 考虑 如上图,将L的部分看为一个整体,用 exp(a)和exp(b)代替,并对式子左右都取对数,则公式变为如下所示: 对数似然比 上述公式等效一下公式: 进一步可等 ...