pillow python histogram_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 importImage

im= Image.open("hopper.ppm")

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

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

importosfrom PIL importImage, ImageFilterclassDemoPIL(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 notNoneassert 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 importmkdtemp

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)returnpathdef_get_filter(self, filter_name):

real_filter= eval("ImageFilter." +filter_name)returnreal_filterdefapply_filter(self, filter_name):print('Applying filter:' +filter_name)

filter_callable=self._get_filter(filter_name)if filter_name inself.fixed_filters:

temp_img=self.image.filter(filter_callable)else:print("Can't apply non-fixed filter now.")returntemp_imgdefrun_fixed_filters_demo(self):

self._make_temp_dir()for ffilter inself.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()

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

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

importosimportsysfrom PIL importImageclassThumbnailer(object):def __init__(self, src_folder=None):

self.src_folder=src_folder

self.ratio= 0.3self.thumbnail_folder= "thumbnails"

def_create_thumbnails_folder(self):

thumb_path=os.path.join(self.src_folder, self.thumbnail_folder)if notos.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 inos.listdir(self.src_folder):

each= os.path.abspath(self.src_folder + '/' +each)ifos.path.isfile(each):

files.add(each)returnfilesdef_thumb_size(self, size):return (int(size[0]*self.ratio), int(size[1]*self.ratio))defcreate_thumbnails(self):

self._create_thumbnails_folder()

files=self._load_files()for each infiles: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)exceptIOError as ex:print("Error:" +str(ex))if __name__ == "__main__":#assert len(sys.argv) == 2

src_folder = "images" #这里提供相对路径

if notos.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.1thumbs.create_thumbnails()

绘制带图像的图表

importmatplotlib.pyplot as pltfrom matplotlib._png importread_pngfrom matplotlib.offsetbox importTextArea, OffsetImage, AnnotationBboxdefload_data():importcsv

with open('pirates_temperature.csv', 'r') as f:

reader=csv.reader(f)

header=next(reader)

datarows=[]for row inreader:

datarows.append(row)returnheader, datarowsdefformat_data(datarows):

years, temps, pirates=[], [], []for each indatarows:

years.append(each[0])

temps.append(each[1])

pirates.append(each[2])returnyears, temps, piratesif __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 inrange(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. 绘制图像

importmatplotlib.pyplot as pltimportmatplotlib.image as mplimageimportmatplotlib as mplimportosclassImageViewer(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'] = 10mpl.rcParams['figure.autolayout'] =False

mpl.rcParams['figure.figsize'] = (9, 6)

mpl.rcParams['figure.subplot.top'] = 0.9@staticmethoddef_get_chno(ch):

chmap= {'R': 0, 'G': 1, 'B':2}return chmap.get(ch, -1)defshow_channel(self, ch):

bins= 256ec= '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')returnaxdefshow(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()exceptException as ex:print(ex)

使用 Basemap 在地图上绘制数据

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

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

from mpl_toolkits.basemap importBasemapimportmatplotlib.pyplot as pltimportnumpy 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 importBasemapimportmatplotlib.pyplot as pltimportnumpy 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 inmap.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, inzip(city_names, x, y):

plt.text(city_x, city_y, city_label)

plt.title('Cities in USA')

plt.show()

生成验证码图像

from PIL importImage, ImageDraw, ImageFontimportrandomimportstringclassSimpleCaptchaException(Exception):pass

classSimpleCaptcha(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= 255self.length=length

self.image=Noneifrandom_text:

self.text=self._random_text()if notself.text:raise SimpleCaptchaException("field text must not be empty.")if notself.size:raise SimpleCaptchaException('Size must not be empty.')if notself.fontsize:raise SimpleCaptchaException('Font size must be defined.')ifrandom_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

returnxydef_add_noise_dots(self, draw):

size=self.image.sizefor _ in range(int(size[0]*size[1]*0.1)):

draw.point((random.randint(0, size[0]), random.randint(0, size[1])), fill='white')returndrawdef_add_noise_lines(self, draw):

size=self.image.sizefor _ 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')returndrawdef_random_text(self):

letters= string.ascii_lowercase +string.ascii_uppercase

random_text= ""

for _ inrange(self.length):

random_text+=random.choice(letters)returnrandom_textdef_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 notNone:

self.text=textif size is notNone:

self.size=sizeif bgcolor is notNone:

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()returnself.image, self.textif __name__ == "__main__":

sc= SimpleCaptcha(length=7, fontsize=36, random_text=True, random_bgcolor=True)

sc.get_captcha()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值