您的位置:首页 > 编程语言 > Python开发

python PIL图像操作

2016-05-05 20:24 696 查看



http://effbot.org/imagingbook/image.htm
使用PIL完成

import Image
#打开图像
img=Image.open('per00001.jpg')
#显示
img.show()
#灰度化
greyimg=img.convert('L')
greyimg.show()

import numpy as np

#得到图像矩阵
gimg_ndarr=np.asarray(greyimg,dtype='float64')/256
#也可以这样
#gimg_ndarr=np.array(greyimg,dtype='float64')
print np.shape(gimg_ndarr)

#下面对矩阵做一些变换
gimg_ndarr=gimg_ndarr-0.5

print gimg_ndarr
gimg_ndarr=gimg_ndarr+0.5
gimg_ndarr=gimg_ndarr*255
print gimg_ndarr

print gimg_ndarr.dtype

#将gimg_ndarr数据类型由float64转化为int8,否则无法显示
gimg_ndarr.astype(np.uint8)

import pylab

pylab.show(gimg_ndarr)
#若以上操作都没问题,由gimg_ndarr将显示原图
pylab.show()


如下代码实现对文件夹里图像文件的遍历,然后随机截取一些图片,然后存入另一个文件夹里

crop() : 从图像中提取出某个矩形大小的图像。它接收一个四元素的元组作为参数,各元素为(left, upper, right, lower),坐标系统的原点(0, 0)是左上角。

#coding:utf-8
from PIL import Image
import os
import random

root='/home/geo_linux/dataset/no_bike_no_person'
def func(args,dire,fis): #回调函数的定义
for f in fis:
args[0].append(os.path.join(root, f))
filelist=[]
os.path.walk(root,func,(filelist,)) #遍历

cropnum=10

save_path='/home/geo_linux/dataset/neg_samples'
for i in range(len(filelist)):
img=Image.open(filelist[i])
for j in range(cropnum):
leftupx=random.randint(0,img.size[0]-64-1)
leftupy= random.randint(0,img.size[1]-128-1)
img1=img.crop((leftupx,leftupy,leftupx+64,leftupy+128))
img1.save(os.path.join(save_path,str(i*cropnum+j)+'.png'))


下面的代码实现对文件夹里所有图像的模糊与左右镜像翻转操作,结果存为图片

#coding:utf-8
from PIL import Image
import ImageFilter
import os
import random

root='/home/geo_linux/dataset/MIT_persons_jpg'
def func(args,dire,fis): #回调函数的定义
for f in fis:
args[0].append(os.path.join(root, f))
filelist=[]
os.path.walk(root,func,(filelist,)) #遍历

cnt=0

save_path='/home/geo_linux/dataset/pos_samples'
for i in range(len(filelist)):
img=Image.open(filelist[i])
img1=img.filter(ImageFilter.BLUR)
img1.save(os.path.join(save_path,str(cnt)+'.png'))
cnt+=1
img2=img.transpose(Image.FLIP_LEFT_RIGHT)
img2.save(os.path.join(save_path,str(cnt)+'.png'))
cnt+=1


下面的代码实现对目录下所有图像文件的处理,提取数据存入本地文件

#coding:utf-8
import os
import random
import Image
import numpy as np
root='/home/geo_linux/dataset/pos_samples'
pos_sample_list=[]
def func(args,dire,fis): #回调函数的定义
for f in fis:
args[0].append(os.path.join(root, f))
os.path.walk(root,func,(pos_sample_list,)) #遍历

root='/home/geo_linux/dataset/neg_samples'

neg_sample_list=[]
os.path.walk(root,func,(neg_sample_list,)) #遍历

train_pos_num=2200
train_neg_num=2200

def img2arr(imgname):
#图像转化为一维numpy数组
#imgname,string类型,文件绝对路径
img=Image.open(imgname)
grey=img.convert('L')
data=np.array(grey,dtype='uint8')
return data.flatten()
#生成训练数据
cnt1=0
cnt2=0
train_data=img2arr(pos_sample_list[0])
del pos_sample_list[0]
cnt1=1
train_label=np.array(1,dtype='uint8')

for i in range(train_pos_num+train_neg_num-1):
if cnt1<train_pos_num and cnt2<train_pos_num:
rng=random.randint(0,100)
if rng%2==0:
index=random.randint(0,len(pos_sample_list)-1)
train_data=np.hstack((train_data,img2arr(pos_sample_list[index])))
train_label=np.hstack((train_label,np.array(1,dtype='uint8')))
del pos_sample_list[index]
cnt1+=1
else:
index=random.randint(0,len(neg_sample_list)-1)
train_data=np.hstack((train_data,img2arr(neg_sample_list[index])))
train_label=np.hstack((train_label,np.array(0,dtype='uint8')))
del neg_sample_list[index]
cnt2+=1
elif cnt1<train_pos_num:
index=random.randint(0,len(pos_sample_list)-1)
train_data=np.hstack((train_data,img2arr(pos_sample_list[index])))
train_label=np.hstack((train_label,np.array(1,dtype='uint8')))
del pos_sample_list[index]
cnt1+=1
else:
index=random.randint(0,len(neg_sample_list)-1)
train_data=np.hstack((train_data,img2arr(neg_sample_list[index])))
train_label=np.hstack((train_label,np.array(0,dtype='uint8')))
del neg_sample_list[index]
cnt2+=1

#生成测试数据
test_data=img2arr(pos_sample_list[0])
del pos_sample_list[0]
test_label=np.array(1,dtype='uint8')
for i in range(len(pos_sample_list)):
test_data=np.hstack((test_data,img2arr(pos_sample_list[i])))
test_label=np.hstack((test_label,np.array(1,dtype='uint8')))
for i in range(len(neg_sample_list)):
test_data=np.hstack((test_data,img2arr(neg_sample_list[i])))
test_label=np.hstack((test_label,np.array(0,dtype='uint8')))
#以二进制写入本地文件
train_data.tofile('train_data.bin')
train_label.tofile('train_label.bin')
test_data.tofile('test_data.bin')
test_label.tofile('test_label.bin')


然后来看看我们存到本地的文件是不是预想的那样

import numpy as np
from PIL import Image
data=np.fromfile('train_data.bin',dtype='uint8')
data.shape=4400,128,64
img=Image.frombuffer('L',(64,128),data[0],'raw','L',0,1)
img.show()


OK,成功显示图像

获取图片某一像素点的 (R,G,B)值

from PIL import Image

imagepath='/media/dell/Projects/test/US08621824-20140107-M00004-1-1.jpg'
img = Image.open(imagepath)
if img.mode not in ('L', 'RGB'):
img = img.convert('RGB')
r, g, b = img.getpixel((10, 10))


PIL中的Image和numpy中的数组array相互转换

1. PIL image转换成array

img = np.asarray(image)



img=np.array(image)

需要注意的是,如果出现read-only错误,并不是转换的错误,一般是你读取的图片的时候,默认选择的是"r","rb"模式有关。

修正的办法: 手动修改图片的读取状态

  img.flags.writeable = True  # 将数组改为读写模式

或者

    im = Image.open("lena.jpg")

    # 显示图片

    im.show() 

    

    im = im.convert("L") 

    data = im.getdata()

    data = np.matrix(data)

或者

  im = np.array(pil_im)

2. array转换成image

方法1

from PIL import Image

Image.fromarray(np.uint8(img))

注意img如果是uint16的矩阵而不转为uint8的话,Image.fromarray这句会报错

File "/usr/local/lib/python2.7/site-packages/PIL/Image.py", line 1884, in fromarray

    raise TypeError("Cannot handle this data type")

TypeError: Cannot handle this data type

类似这个问题

PIL weird error after resizing image in skimage

方法2

import cv2

cv2.imwrite("output.png", out)

out可以是uint16类型数据

16位深度图像转8位灰度

matlab

img=imread('output.png')

img1=im2uint8(img)

imwrite(img1,'result.jpg')

或者python

from PIL import Image

import numpy as np

import math

img=Image.fromarray(np.uint8(img_array/float(math.pow(2,16)-1)*255))

img.save('22.png')

Image.resize()

im.resize(size, filter) ⇒ image

Returns a resized copy of an image. The size argument gives the requested size in pixels, as a 2-tuple: (width, height).

The filter argument can be one of NEAREST (use nearest neighbour), BILINEAR (linear interpolation in a 2x2 environment), BICUBIC (cubic spline interpolation in a 4x4 environment), or ANTIALIAS (a high-quality downsampling filter). If omitted, or if the image
has mode “1” or “P”, it is set to NEAREST.

Note that the bilinear and bicubic filters in the current version of PIL are not well-suited for large downsampling ratios (e.g. when creating thumbnails). You should use ANTIALIAS unless speed is much more important than quality.

Python图片转换成矩阵,矩阵数据转换成图片

Python实现图片与数组的转化

通道转换

注意linux的convert命令会使得三通道的灰度图像变为单通道

Python图像处理库PIL中图像格式转换(二)

python的PIL图像处理

Image.copy()

Image.paste()

Python图像处理库PIL的ImageDraw模块介绍
http://blog.csdn.net/icamera0/article/category/6069814
PIL doc

Polyline和Polygon的区别是什么

1)polygon 元素在连线的时候,会把所有的点连接起来,包括第一个点和最后一个点。

2)polyline 元素是不连接最后一个点和第一个点的。

这是polygon和polyline常见的区别

python,使用PIL库对图片进行操作

python计算机视觉编程
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: