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 处理图像的更多相关文章

  1. Python数据可视化编程实战pdf

    Python数据可视化编程实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1vAvKwCry4P4QeofW-RqZ_A 提取码:9pcd 复制这段内容后打开百度 ...

  2. 【数据科学】Python数据可视化概述

    注:很早之前就打算专门写一篇与Python数据可视化相关的博客,对一些基本概念和常用技巧做一个小结.今天终于有时间来完成这个计划了! 0. Python中常用的可视化工具 Python在数据科学中的地 ...

  3. python 数据可视化

    一.基本用法 import numpy as np import matplotlib.pyplot as plt x = np.linspace(-1,1,50) # 生成-1到1 ,平分50个点 ...

  4. Python数据可视化基础讲解

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:爱数据学习社 首先,要知道我们用哪些库来画图? matplotlib ...

  5. 《数据可视化之美》高清PDF全彩版|百度网盘免费下载|Python数据可视化

    <数据可视化之美>高清PDF全彩版|百度网盘免费下载|Python数据可视化 提取码:i0il 内容简介 <数据可视化之美>内容简介:可视化是数据描述的图形表示,旨在一目了然地 ...

  6. python数据可视化编程实战PDF高清电子书

    点击获取提取码:3l5m 内容简介 <Python数据可视化编程实战>是一本使用Python实现数据可视化编程的实战指南,介绍了如何使用Python最流行的库,通过60余种方法创建美观的数 ...

  7. Python数据可视化 -- Wordcloud

    Python数据可视化 -- Wordcloud 安装 启动命令行,输入:pip install wordcloud word cloud 库介绍 及简单使用 wordcloud库,可以说是pytho ...

  8. Python数据可视化编程实战——导入数据

    1.从csv文件导入数据 原理:with语句打开文件并绑定到对象f.不必担心在操作完资源后去关闭数据文件,with的上下文管理器会帮助处理.然后,csv.reader()方法返回reader对象,通过 ...

  9. Python数据可视化——使用Matplotlib创建散点图

    Python数据可视化——使用Matplotlib创建散点图 2017-12-27 作者:淡水化合物 Matplotlib简述: Matplotlib是一个用于创建出高质量图表的桌面绘图包(主要是2D ...

随机推荐

  1. Java Design Patterr

    Factory: ●简介: 工厂模式同单例模式一样,也是Java中最常用的设计模式之一,属于创建型模式,它提供了一种创建对象的最佳方式.能够根据要求调用者提供的信息为接口指定不同的实现类,降低耦合. ...

  2. fibonacci数列-斐波那契数列-python编程

    未完待续~ 了解fibonacci数列: 斐波纳契数列(Fibonacci Sequence),又称黄金分割数列. 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610 ...

  3. Java开发体系

    蓦然回首自己做开发已经十年了,这十年中我获得了很多,技术能力.培训.出国.大公司的经历,还有很多很好的朋友.但再仔细一想,这十年中我至少浪费了五年时间,这五年可以足够让自己成长为一个优秀的程序员,可惜 ...

  4. 记录小白实习生的HashMap源码 put元素 的学习和一些疑问

    首先看HashMap存储结构 transient Node<K,V>[] table; static class Node<K,V> implements Map.Entry& ...

  5. Must practice programming questions in all languages

    To master any programming languages, you need to definitely solve/practice the below-listed problems ...

  6. EasyUI 1.3.2 中 Combobox自动检索 键盘上下选择Bug问题

    EasyUI 自带的Combobox控件,提供了下拉列值自动检索功能. 在用到的EasyUI 1.3.2版本中还是有点问题,在键盘上下键移动选择过程中只能定位在第一个,不能正常向下移动 问题解决方式: ...

  7. C++文档补充

    string s("100010"); bitset<5>  b(s,2,2); 只有上图这样写,下图这样是错的.记住.http://www.cppblog.com/k ...

  8. DOM对象与jquery对象相互转换

  9. 《Go程序设计语言》读书笔记-函数

    函数包含连续执行的语句,可以使用代码中通过调用函数来执行他们,函数能够将一个复杂的工作切分成多个更小的模块,使多人写作变得容易.另外,函数对他的使用者隐藏了实现细节.这几方面的特性使得函数成为多数编程 ...

  10. 一段自适应的CSS代码

    一段自适应HTML5的CSS代码,该代码在陕西特产使用过,手机端效果还好,就是PC端看起来没那么大气,比较窄屏 * { transition-property: all; -ms-transition ...