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

  1. from PIL import Image
  2. im = Image.open("hopper.ppm")

PIL 坐标系统假定坐标(0,0)位于左上角。

一个对图片进行过滤的例子

  1. import os
  2. from PIL import Image, ImageFilter
  3.  
  4. class DemoPIL(object):
  5. def __init__(self, image_file=None): # 构造器
  6. self.fixed_filters = [ff for ff in dir(ImageFilter) if ff.isupper()] # dir(ImageFilter)返回ImageFilter类的属性。 isupper()是str的方法,当所有字母大写返回True
  7. assert image_file is not None
  8. assert os.path.isfile(image_file) is True # 断言文件是否存在
  9. self.image_file = image_file
  10. self.image = Image.open(self.image_file) # 返回一个 Image 对象实例
  11.  
  12. def _make_temp_dir(self):
  13. from tempfile import mkdtemp
  14. self.ff_tempdir = mkdtemp(prefix="ff_demo_", dir="C:\\Users\\mail.simcere.com\\Desktop") # 创建临时路径
  15.  
  16. def _get_temp_name(self, filter_name):
  17. name, ext = os.path.splitext(os.path.basename(self.image_file))
  18. newimage_file = name + "-" + filter_name + ext
  19. path = os.path.join(self.ff_tempdir, newimage_file)
  20. return path
  21.  
  22. def _get_filter(self, filter_name):
  23. real_filter = eval("ImageFilter." + filter_name)
  24. return real_filter
  25.  
  26. def apply_filter(self, filter_name):
  27. print('Applying filter:' + filter_name)
  28. filter_callable = self._get_filter(filter_name)
  29. if filter_name in self.fixed_filters:
  30. temp_img = self.image.filter(filter_callable)
  31. else:
  32. print("Can't apply non-fixed filter now.")
  33. return temp_img
  34.  
  35. def run_fixed_filters_demo(self):
  36. self._make_temp_dir()
  37. for ffilter in self.fixed_filters:
  38. temp_img = self.apply_filter(ffilter)
  39. temp_img.save(self._get_temp_name(ffilter)) # 保存图像
  40. print("Images are in: {0}".format((self.ff_tempdir),))
  41.  
  42. if __name__ == '__main__':
  43. # assert len(sys.argv) == 2
  44. demo_image = "sunset.jpg"
  45. demo = DemoPIL(demo_image) # 获取 DemoPIL 实例对象
  46. demo.run_fixed_filters_demo()

处理某一特定文件夹下的所有图像文件

指定一个目标路径,用程序读取目标路径下的所有图像,并按给定比例调整他们的大小,然后把每一个文件存储到另一个指令文件夹下。

  1. import os
  2. import sys
  3. from PIL import Image
  4.  
  5. class Thumbnailer(object):
  6.  
  7. def __init__(self, src_folder=None):
  8. self.src_folder = src_folder
  9. self.ratio = 0.3
  10. self.thumbnail_folder = "thumbnails"
  11.  
  12. def _create_thumbnails_folder(self):
  13. thumb_path = os.path.join(self.src_folder, self.thumbnail_folder)
  14. if not os.path.isdir(thumb_path):
  15. os.makedirs(thumb_path)
  16.  
  17. def _build_thumb_path(self, image_path):
  18. root = os.path.dirname(image_path)
  19. name, ext = os.path.splitext(os.path.basename(image_path))
  20. suffix = ".thumbnail"
  21. return os.path.join(root, self.thumbnail_folder, name + suffix + ext)
  22.  
  23. def _load_files(self):
  24. files = set()
  25. for each in os.listdir(self.src_folder):
  26. each = os.path.abspath(self.src_folder + '/' + each)
  27. if os.path.isfile(each):
  28. files.add(each)
  29. return files
  30.  
  31. def _thumb_size(self, size):
  32. return (int(size[0]*self.ratio), int(size[1]*self.ratio))
  33.  
  34. def create_thumbnails(self):
  35. self._create_thumbnails_folder()
  36. files = self._load_files()
  37. for each in files:
  38. print("Processing: " + each)
  39. try:
  40. img = Image.open(each) # 返回 Image对象实例
  41. thumb_size = self._thumb_size(img.size)
  42. resized = img.resize(thumb_size, Image.ANTIALIAS) # 重新设置大小
  43. savepath = self._build_thumb_path(each)
  44. resized.save(savepath)
  45. except IOError as ex:
  46. print("Error: " + str(ex))
  47. if __name__ == "__main__":
  48. # assert len(sys.argv) == 2
  49. src_folder = "images" # 这里提供相对路径
  50. if not os.path.isdir(src_folder):
  51. print("Error: Path '{0}' does not exists.".format((src_folder)))
  52. sys.exit(-1)
  53. thumbs = Thumbnailer(src_folder) # 得到 Thumbnailer的实例对象
  54. thumbs.thumbnail_folder = "THUMBS" # 直接修改了对象的属性,破坏了数据封装的原则
  55. thumbs.ratio =0.1
  56. thumbs.create_thumbnails()

绘制带图像的图表

  1. import matplotlib.pyplot as plt
  2. from matplotlib._png import read_png
  3. from matplotlib.offsetbox import TextArea, OffsetImage, AnnotationBbox
  4.  
  5. def load_data():
  6. import csv
  7. with open('pirates_temperature.csv', 'r') as f:
  8. reader = csv.reader(f)
  9. header = next(reader)
  10. datarows = []
  11. for row in reader:
  12. datarows.append(row)
  13. return header, datarows
  14.  
  15. def format_data(datarows):
  16. years, temps, pirates = [], [], []
  17. for each in datarows:
  18. years.append(each[0])
  19. temps.append(each[1])
  20. pirates.append(each[2])
  21. return years, temps, pirates
  22.  
  23. if __name__ == '__main__':
  24. fig = plt.figure(figsize=(16, 8))
  25. ax = plt.subplot(111)
  26. header, datarows = load_data()
  27. xlabel, ylabel, _ = header # 将列表中的元素赋值到三个变量中
  28. years, temperature, pirates = format_data(datarows)
  29. title = 'Golbal Average Temperature vs. Number of Pirates'
  30. plt.plot([int(i) for i in years], [float(i) for i in temperature], lw=2)
  31. plt.xlabel(xlabel)
  32. plt.ylabel(ylabel)
  33. for x in range(len(years)):
  34. xy = int(years[x]), float(temperature[x])
  35. ax.plot(int(xy[0]), float(xy[1]), "ok")
  36. pirate = read_png('tall-ship.png')
  37. zoomc = int(pirates[x])*(1/90000.0)
  38. imagebox = OffsetImage(pirate, zoom=zoomc) #
  39. 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"))
  40. ax.add_artist(ab)
  41. no_pirates = TextArea(pirates[x], minimumdescent=False)
  42. 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"))
  43. ax.add_artist(ab)
  44. plt.grid()
  45. plt.xlim(1800, 2020)
  46. plt.ylim(14, 16.5)
  47. plt.title(title)
  48. plt.show()

pirates_temperature.csv 中的内容

在有其它图形的图表中显示图像

操作步骤:

1. 加载图像

2. 从图像矩阵中分离出RGB通道

3. 配置图表和坐标轴(自区)

4. 绘制通道直方图

5. 绘制图像

  1. import matplotlib.pyplot as plt
  2. import matplotlib.image as mplimage
  3. import matplotlib as mpl
  4. import os
  5.  
  6. class ImageViewer(object):
  7. def __init__(self, imfile):
  8. self._load_image(imfile)
  9. self._configure()
  10. self.figure = plt.gcf()
  11. t = "Image: {0}".format(os.path.basename(imfile))
  12. self.figure.suptitle(t, fontsize=20)
  13. self.shape=(3, 2)
  14. def _load_image(self, imfile):
  15. self.im = mplimage.imread(imfile) # 读取图像 read an image from a file into an array
  16. def _configure(self):
  17. mpl.rcParams['font.size'] = 10
  18. mpl.rcParams['figure.autolayout'] = False
  19. mpl.rcParams['figure.figsize'] = (9, 6)
  20. mpl.rcParams['figure.subplot.top'] = 0.9
  21. @staticmethod
  22. def _get_chno(ch):
  23. chmap = {'R': 0, 'G': 1, 'B':2}
  24. return chmap.get(ch, -1)
  25. def show_channel(self, ch):
  26. bins = 256
  27. ec = 'none'
  28. chno = self._get_chno(ch)
  29. loc = (chno, 1)
  30. ax = plt.subplot2grid(self.shape, loc)
  31. ax.hist(self.im[:, :, chno].flatten(), bins, color=ch, ec=ec, label=ch, alpha=0.7)
  32. ax.set_xlim(0, 255)
  33. plt.setp(ax.get_xticklabels(), visible=True)
  34. plt.setp(ax.get_yticklabels(), visible=False)
  35. plt.setp(ax.get_xticklines(), visible=True)
  36. plt.setp(ax.get_yticklines(), visible=False)
  37. plt.legend()
  38. plt.grid(True, axis='y')
  39. return ax
  40. def show(self):
  41. loc = (0, 0)
  42. axim = plt.subplot2grid(self.shape, loc, rowspan=3)
  43. axim.imshow(self.im)
  44. plt.setp(axim.get_xticklabels(), visible=False)
  45. plt.setp(axim.get_yticklabels(), visible=False)
  46. plt.setp(axim.get_xticklines(), visible=False)
  47. plt.setp(axim.get_yticklines(), visible=False)
  48. axr = self.show_channel('R')
  49. axg = self.show_channel('G')
  50. axg = self.show_channel('B')
  51. plt.show()
  52.  
  53. if __name__ == '__main__':
  54. im = 'yellow_flowers.jpg'
  55. try:
  56. iv = ImageViewer(im)
  57. iv.show()
  58. except Exception as ex:
  59. print(ex)

使用 Basemap 在地图上绘制数据

Basemap 本身不进行任何绘图工作,它只是把给定的地理坐标转换到地图投影,并把数据传给 matplotlib 进行绘图。

basemap文档:https://matplotlib.org/basemap/api/basemap_api.html

  1. from mpl_toolkits.basemap import Basemap
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4.  
  5. map = Basemap(projection='merc', resolution='h',area_thresh=0.1, llcrnrlon=-126.619875, llcrnrlat=31.354158, urcrnrlon=-59.647219, urcrnrlat=47.517613)
  6. map.drawcoastlines()
  7. map.drawcountries()
  8. map.fillcontinents(color='coral', lake_color='aqua')
  9. map.drawmapboundary(fill_color='aqua')
  10. map.drawmeridians(np.arange(0, 360, 30))
  11. map.drawparallels(np.arange(-90, 90, 30))
  12. plt.show()

  1. from mpl_toolkits.basemap import Basemap
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4.  
  5. map = Basemap(projection='merc', resolution='h', area_thresh=100, llcrnrlon=-126.619875, llcrnrlat=25, urcrnrlon=-59.647219, urcrnrlat=55)
  6. shapeinfo = map.readshapefile('cities', 'cities')
  7. x, y = zip(*map.cities)
  8. city_names = []
  9. for each in map.cities_info:
  10. if each['COUNTRY'] != 'US':
  11. city_names.append("")
  12. else:
  13. city_names.append(each['NAME'])
  14. map.drawcoastlines()
  15. map.drawcountries()
  16. map.fillcontinents(color='coral', lake_color='aqua')
  17. map.drawmapboundary(fill_color='aqua')
  18. map.drawmeridians(np.arange(0, 360, 30))
  19. map.drawparallels(np.arange(-90, 90, 30))
  20. map.scatter(x, y, 25, marker='o', zorder=10)
  21. for city_label, city_x, city_y, in zip(city_names, x, y):
  22. plt.text(city_x, city_y, city_label)
  23. plt.title('Cities in USA')
  24. plt.show()

生成验证码图像

  1. from PIL import Image, ImageDraw, ImageFont
  2. import random
  3. import string
  4.  
  5. class SimpleCaptchaException(Exception):
  6. pass
  7.  
  8. class SimpleCaptcha(object):
  9. def __init__(self, length=5, size=(200, 100), fontsize=36, random_text=None, random_bgcolor=None):
  10. self.size = size
  11. self.text = 'CAPTCHA'
  12. self.fontsize = fontsize
  13. self.bgcolor = 255
  14. self.length = length
  15. self.image = None
  16. if random_text:
  17. self.text = self._random_text()
  18. if not self.text:
  19. raise SimpleCaptchaException("field text must not be empty.")
  20. if not self.size:
  21. raise SimpleCaptchaException('Size must not be empty.')
  22. if not self.fontsize:
  23. raise SimpleCaptchaException('Font size must be defined.')
  24. if random_bgcolor:
  25. self.bgcolor = self._random_color()
  26. def _center_coords(self, draw, font):
  27. width, height = draw.textsize(self.text, font)
  28. xy = (self.size[0] - width)/2.0, (self.size[1] - height)/2.0
  29. return xy
  30. def _add_noise_dots(self, draw):
  31. size = self.image.size
  32. for _ in range(int(size[0]*size[1]*0.1)):
  33. draw.point((random.randint(0, size[0]), random.randint(0, size[1])), fill='white')
  34. return draw
  35. def _add_noise_lines(self, draw):
  36. size = self.image.size
  37. for _ in range(8):
  38. width = random.randint(1, 2)
  39. start = (0, random.randint(0, size[1]-1))
  40. end = (size[0], random.randint(0, size[1]-1))
  41. draw.line([start, end], fill="white", width=width)
  42. for _ in range(8):
  43. start = (-50, 50)
  44. end = (size[0] + 10, random.randint(0, size[1] + 10))
  45. draw.arc(start + end, 0, 360, fill='white')
  46. return draw
  47. def _random_text(self):
  48. letters = string.ascii_lowercase + string.ascii_uppercase
  49. random_text = ""
  50. for _ in range(self.length):
  51. random_text += random.choice(letters)
  52. return random_text
  53. def _random_color(self):
  54. r = random.randint(0, 255)
  55. g = random.randint(0, 255)
  56. b = random.randint(0, 255)
  57. return (r, g, b)
  58. def get_captcha(self, size=None, text=None, bgcolor=None):
  59. if text is not None:
  60. self.text = text
  61. if size is not None:
  62. self.size = size
  63. if bgcolor is not None:
  64. self.bgcolor = bgcolor
  65. self.image = Image.new('RGB', self.size, self.bgcolor) #
  66. font = ImageFont.truetype('fonts/Vera.ttf', self.fontsize)
  67. draw = ImageDraw.Draw(self.image)
  68. xy = self._center_coords(draw, font)
  69. draw.text(xy=xy, text=self.text, font=font)
  70. draw = self._add_noise_dots(draw)
  71. draw = self._add_noise_lines(draw)
  72. self.image.show()
  73. return self.image, self.text
  74.  
  75. if __name__ == "__main__":
  76. sc = SimpleCaptcha(length=7, fontsize=36, random_text=True, random_bgcolor=True)
  77. 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. QT 二维图形 原理、发展及应用

    转载自 网易博客:sun的博客 http://zhouyang340.blog.163.com/blog/static/3024095920126710504178/ 2D绘图 Qt4中的2D绘图部分 ...

  2. 每日一练之排序算法(P1097 统计数字)

    某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5×10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照自然数从小到大的顺序输出统计结果. ...

  3. 【396】python 递归练习题(COMP9021)

    Merging two strings into a third one Say that two strings s1 and s2 can be merged into a third strin ...

  4. django restfulwork 源码剖析

    概要: 1.restful 规范(建议); 2. django rest framework框架 内容回顾: 1.开发模式; - 普通开发模式(前后端放在一起写) - 前后端分离 好处: 后端一套,前 ...

  5. KeyValuePair 和 Dictionary 的关系和区别

    KeyValuePair 和 Dictionary 的关系 1.KeyValuePair      a.KeyValuePair 是一个结构体(struct):     b.KeyValuePair  ...

  6. 【C++】纯C++实现http打开网页下载内容的功能

    #include "stdafx.h" #include <windows.h> #include <iostream> #include "Wi ...

  7. pyton 模块之 pysmb 文件上传(windows)

    #!/usr/bin/env python #coding:utf-8 from smb.SMBConnection import SMBConnection from nmb.NetBIOS imp ...

  8. 通过.ibd和.frm恢复mysql数据

    背景:因为机器损坏,数据库的索引文件什么的都损坏了.只留下了一个mysql的data目录… 此方法恢复数据的前提:建表用的innodb索引   备注:如果mysql的目录还都在,可以先尝试,将mysq ...

  9. 第一次博客作业 <西北师范大学| 周安伟>

     1.助教博客链接:https://home.cnblogs.com/u/zaw-315/ 2.本周点评的作业数:3份,有留言互动. 3.本周点评有困难的地方: https://www.cnblogs ...

  10. Polar Code(1)极化码SC译码迭代公式的理解

    采用对数似然比求解的迭代公式推导: 考虑 如上图,将L的部分看为一个整体,用 exp(a)和exp(b)代替,并对式子左右都取对数,则公式变为如下所示: 对数似然比 上述公式等效一下公式: 进一步可等 ...