python 处理 图像和视频

图像入门

使用PLT读取图像

Pillow -> Python Imaging Library

Image模块
打开和新建

Image.open(fp,mode) 打开图像,执行返回Image类的实例。如果文件不存在,会引发IOError错误

  • fp:打开文件的路径
  • mode:打开文件的方式,通常使用默认值r

Image.new(mode,size,color=0) 新建图像

  • mode:图像模式
  • size:图片尺寸,是使用宽和高两个元素构成的元祖
  • color:默认颜色(黑色)
mode(模式)bands(通道)说明
“1”1黑白二值图像,每个像素用0或者1共1位二进制代码表示
“RGB”324位真彩图,每个像素用3个字符的二进制代码表示
“RGBA”4“RGB”+透明通道表示,每个像素用4字符的二进制代码表示
“CMYK”4印刷模式图像,每个像素用4字符的二进制代码表示
“LAB”3lab颜色空间,每个像素用3字符的二进制代码表示
“HSV”3每个像素用3字符的二进制代码表示
from PIL import Image
#打开图片
img=Image.open('bjsxt.png')
#显示图片
# img.show()
print('图片的格式:',img.format) # PNG
print('图片的大小:',img.size) # (437, 196)
print('图片的高度:',img.height,'图片的宽度:',img.width) # 图片的高度: 196 图片的宽度: 437
print('获取(100,100)处像素值:',img.getpixel((100,100))) # 获取(100,100)处像素值: (188, 193, 133)
混合

Image.blend(im,im2,alpha) 透明度混合处理

Image.composite(im1,im2,mask) 遮罩混合处理

from PIL import Image
img1=Image.open('bjsxt.png').convert(mode='RGB')
img2=Image.new('RGB',img1.size,'red')
Image.blend(img1,img2,alpha=0.5).show()

img1=Image.open('blend1.jpg')
img2=Image.open('blend2.jpg')
img2=img2.resize(img1.size)
r,g,b=img2.split()
Image.composite(img2,img1,b).show()
复制和缩放

copy() 复制指定的图片

Image.eval(img,fun) 像素值缩放处理

Image.thmbnail(size,resample=3) 原生地缩放指定的图像

Image.resize(size, Image.ANTIALIAS) antialias抗锯齿

from PIL import Image
#按像素缩放图片
img1= Image.open('bjsxt.png')
#.将每个像素值都扩大2倍
Image.eval(img1,lambda x:x*2).show()
img2=img1.copy()
#按尺寸进行缩放图片
img2.thumbnail((200,160)).show()
粘贴和裁剪

Image.paste(im,box=None,mask=None) 粘贴

  • im 是源图像或像素值
  • box 粘贴区域
    • (x1,y1):将源图像左上角对齐(x1,y1)点,其余超出被粘贴图像的区域被抛弃
    • (x1,y1,x2,y2):源图像与次区域必须一致
    • None:源图像与粘贴的图像大小必须一致
  • mask 遮罩

Image.crop(box) box=(int(left),int(top),int(right),int(bottom)) 裁剪图像

这个元组参数包含四个值,分别代表矩形四条边的距离X轴或者Y轴的距离。顺序是(左,顶,右,底)

from PIL import Image
img=Image.open('bjsxt.png')
#复制
imgb=img.copy()
imgc=img.copy()
#剪切
img_crop=imgb.crop((10,10,120,120))
#粘贴
imgc.paste(img_crop,(30,30))
imgc.show()
图像旋转和转换位置

Image.rotate(angle,resample=0,expand=0,center=None,translate=None,fillcoloor=None) 旋转图像

Image.covert(mode=None,matrix=None,dither=None,palette=0,colors=256) 图像转换

Image.transpose(method) 转换位置

  • PIL.Image.FLIP_LEFT_RIGHT:左右镜像
  • PIL.Image.FLIP_TOP_BOTTOM :上下镜像
  • PIL.Image.ROTATE_90:旋转 90
  • PIL.Image.ROTATE_180:旋转 180
  • PIL.Image.TRANSPOSE :颠倒顺序
from PIL import Image
img=Image.open('bjsxt.png')
#图像的旋转
# img.rotate(180).show()

#格式转换
# img.transpose(Image.FLIP_TOP_BOTTOM).show() # 上下滤镜
# img.transpose(Image.FLIP_LEFT_RIGHT).show() # 左右滤镜
# img.transpose(Image.ROTATE_90).show() # 90滤镜
# img.transpose(Image.ROTATE_180).show() # 180滤镜
img.transpose(Image.TRANSPOSE).show() # 颠倒滤镜
分离和合并

Iamage.split() 分割多个通道列表

Image.merge(mode,bands) 合并到更多通道图像中

from PIL import Image
img1=Image.open('blend1.jpg')
img2=Image.open('blend2.jpg')
img2=img2.resize(img1.size)
#分隔
r1,g1,b1=img1.split()
r2,g2,b2=img2.split()
temp=[r1,g2,b1]
img=Image.merge('RGB',temp)
img.show()
其他内置参数

常用属性

  1. Image.format 源图像格式
  2. Image.mode 图像模式字符串
  3. Image.size 图像尺寸

内置函数

使用Python PIL进行图像压缩

  1. Image.gethands() 获取图像每个通道的名称列表,例如RGB图像返回[‘R’,'G,'B]

  2. Image.getextrema() 获取图像最大、最小像素的值

  3. Image.crop(int(left),int(top),int(right),int(bottom)) 图片裁剪

    region=im.crop((100,100,500,500))

  4. Image.getpixel(x,y) 获取像素点值

    im.getpixel((4,4))

  5. Image.putpixel((x,y),(r,g,b)) 写入像素点值

    img.putpixel((4,4),(255,0,0))

  6. Image.point(function) 使用函数修改图像的每个像素

    out=img.point(lambda i:i*1.5) 对每个点进行50%的加强

  7. Image.histogram(mask=None,extrema=None) 获取图像直方图,返回像素计数的列表

  8. Image.putalpha(alpha) 添加或替换图像的alpha层

  9. Image.blend(img1,img2,alpha) 两张图片相加

  10. Image.save(fp,format=None,**params) 保存图片

  11. Image.show(title=None,command=None) 显示图片

  12. Image.transform(size,method,data=None,resample=0,fill=1) 变换图像

  13. Image.verify() 检验文件是否损坏

  14. Image.close() 关闭文件

其它模块
  • ImageFilter模块

    image.filter(滤镜效果)

    • ImageFilter.EMBOSS 浮雕效果
    • ImageFilter.CONTOUR 铅画笔
    • ImageFilter.BLUR 模糊效果
    • ImageFilter.EDGE_ENHANCE 边界增强
  • ImageDraw模块

    draw.point(坐标, 颜色)

    • 坐标:两个元组的序列 [(x, y), (x, y), ...] 或类似的数值 [x, y, x, y, ...]

    draw.line(起始坐标+终点坐标, 颜色, 宽度)

    • 坐标:两个元组的序列 [(x, y), (x, y), ...] 或类似的数值 [x, y, x, y, ...]

    draw.rectangle(坐标,填充颜色,轮廓颜色,宽度)

    • 坐标: 任何一个的序列 [(x0, y0), (x1, y1)][x0, y0, x1, y1]

    draw.textsize(要测量的文本,font)

  • ImageFont模块

    ImageFont.truetype(字体文件, 字号)

    draw.text(坐标, 文字内容, fill=文字颜色, font=字体对象 )

随机验证码
from PIL import Image, ImageDraw, ImageFont, ImageFilter
from random import randint

class L_BLUR(ImageFilter.BuiltinFilter):
    name = "l_blur"
    filterargs = (5, 5), 16, 0, (
        1, 1, 1, 1, 1,
        1, 0, 0, 0, 1,
        1, 0, 0, 0, 1,
        1, 0, 0, 0, 1,
        1, 1, 1, 1, 1,
    )

# random.randint(M, N) 产生一个M到N的随机整数
def rand_img_color():
    return randint(0,255), randint(0,255), randint(0,255)
def rand_num_color():
    return randint(0,127), randint(0,127), randint(0,127)
def rand_zh():
    return chr(randint(0x4E00,0x9FBF))
def rand_char():
    # 小写字母
    return chr(randint(97,122))
    # 大写字母
    # return chr(randint(65,90))
def rand_num():
    return str(randint(0,9))

# 1.创建空图片
image = Image.new('RGB',(120,60),(255,255,255))
draw = ImageDraw.Draw(image)

# 2.渲染背景
for x in range(0,120):
    for y in range(0,60):
        draw.point((x, y), rand_img_color())
w, h = (image.size)
draw.line((w/4,0) + (w/4,h), fill=rand_img_color(), width=3)
draw.line((w/2,0) + (w/2,h), fill=rand_img_color(), width=3)
draw.line((w/4*3,0) + (w/4*3,h), fill=rand_img_color(), width=3)
draw.line((0,h/2) + (w,h/2), fill=rand_img_color(), width=3)
image = image.filter(L_BLUR)

# 3.渲染文字
font = ImageFont.truetype('simhei.ttf', 30)
draw = ImageDraw.Draw(image)
for x in range(4):
    y = randint(10,30)
    draw.text((30*x,y), rand_num(), rand_num_color(), font)

image.show()

使用OpenCV读取图像

OpenCV中文官方文档

  1. cv.imread() 读取图像

    第一个参数是路径

    第二个参数是一个标志,指定读取图像的方式,如下:

    • cv.IMREAD_COLOR :可以传递整数1,加载彩色图像。任何图像的透明度都会忽视。默认
    • cv.IMREAD_GRAYSCALE :可以传递整数0,以灰度模式加载图像
    • cv.IMREAD_UNCHANGED :可以传递整数-1,加载图像,包括alpha通道

    即使图像路径错误,它也不会引发任何错误,但是 print(img) -> None

  2. cv.imshow() 显示图像

    第一个参数是窗口名称,字符串类型

    第二个参数是我们的读取的图片

    cv.namedWindow 调整指定窗口大小

    • cv.WINDOW_NORMAL 默认
    • cv.WINDOW_NORMAL 可以调整窗口大小

    cv.waitKey() 键盘绑定函数,其参数以毫秒为单位的时间

    cv.destoryAllWindows() 破坏我们创建的所有窗口

  3. cv.imwrite() 保存图像

    第一个参数是文件名

    第二个参数是要保存的图像

import cv2 as cv
import numpy as np
#加载灰度图像
img = cv.imread('messi5.jpg',0)

#cv.namedWindow('image', cv.WINDOW_NORMAL)
cv.imshow('image', img)
k = cv.waitKey(0)
if k == 27; # 等待ESC退出 KeyCode
	cv.destoryAllWindows()
elif k == ord('s'): # 等待关键字,保存和退出
    cv.imwrite('messigray.png', img)
    cv.destoryAllWindows()

切割图片

先用np.fromfile()读取为np.uint8格式,再使用cv2.imdecode()解码

import cv2
import numpy as np
# cv2.imread路径为中文时返回None
# 读取图像,解决imread不能读取中文路径的问题
img = cv2.imdecode(np.fromfile(image_path,dtype=np.uint8),-1)
cropped = img[coor_y1:coor_y2,coor_x1:coor_x2]
cv2.imencode('.jpg', cropped)[1].tofile(save_path)

各种图像转换

OpenCv使用BGR格式,PIL使用的是RGB格式

img.reshape(2,-1) 转换成两行

img.reshape(-1,2) 转换成两列

img.resize((width, height),Image.ANTIALIAS)

  • Image.NEAREST :低质量
  • Image.BILINEAR:双线性
  • Image.BICUBIC :三次样条插值
  • Image.ANTIALIAS:高质量
img = cv2.imdecode(np.fromfile(image_path,dtype=np.uint8),-1)
# 输出图像每个BGR像素值,转换成列表可一一遍历出来
img.reshape(-1,3)
# 更改图片大小
img_small = cv2.resize(img (320,180), interpolation=cv2.INTER_NEAREST)
img_height, img_width = img.shape
# 转RGB图
img_rgb = np.zeros((img_height, img_width), dtype=np.uint8)

图片信息

img.shape 它返回一组行、列和通道的元组 (如果图像是彩色的)

img.dtype 获得图像数据类型

# img.shape: (480, 640, 3)
img.shape[0] = height: 480
img.shape[1] = width: 640
img.shape[2] = channel: 3

print(img.dtype) # uint8

# 由于图片格式是BGR格式,需要把RGB转换成BGR
file = codecs.open(file_path, 'r', 'utf-8')
color_dict = {}
for line in file:
    label_id, scene, color = line.strip().split('\t')
    color_dict[(int(color.split(',')[2]), int(color.split(',')[1]), int(color.split(',')[0]))] = int(label_id)

# 读取每一个像素点色值
color_set = {}
for img_color in list(img.reshape(-1,3)):
    if  tuple(list(img_color)) not in color_set:
        color_set[tuple(list(img_color))] = 1
    # print(img_color)

# 获取颜色近似值
def get_similar_color(color, color_list):
    dist_min = 3
    for c in color_list:
        sim_color = color
        distance = (c[0]-color[0])**2 + (c[1]-color[1])**2 + (c[2]-color[2])**2
        if distance <= dist_min:
            sim_color = c
            print(sim_color)
    return sim_color

get_similar_color((1, 1, 1), color_dict)

使用Matplotlib 读取图像

Matplotlib绘图样式和功能

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt

img = cv.imread('messo5.jpg', 0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
# 隐藏 x 轴和 y 轴的刻度值
plt.xticks([]),plt.yticks([])
plt.show()

使用OpenCV读取视频

  1. 要捕获视频,需要创建一个 VideoCapture 对象,它的参数可以是设备索引(哪个摄像头的名字)或视频文件的名称

    FourCC 全称 Four-Character Codes ,代表四字符代码, 它是一个32位的标示符,其实就是 typedef unsigned int FOURCC ;是一种独立标示视频数据流格式的四字符代码。 cv2.VideoWriter_fourcc() 函数的作用是输入四个字符代码即可得到对应的视频编码器

  2. cap.read() 返回布尔值(True/False),如果帧读取的是正确的,就是True。所以可以通过检查他的返回值来查看视频文件是否已经到了结尾

  3. cap.isOpened() ,来检查是否成功初始化,如果返回值是True,那就没有问题。否则就要使用函数 cap.open()。你可以使用函数 cap.get(propId) 来获得视频的一些参数信息。这里propId可以是0到18的任何整数。每一个数代表视频的一个属性

  4. 你要想设置新值,例如:可以使用 cap.get(3)cap.get(4) 来查看每一帧的宽和高。默认情况下得到的值是 640×480。但是我们可以使用 ret=cap.set(3,320)ret=cap.set(4,240) 来把宽和高改成 320×240

import numpy as np
import cv2 as cv

cap = cv.VideoCapture('vtest.avi')
# 使用XVID编码器 
fourcc = cv.VideoWriter_fourcc(*'XVID')
# 保存文件名	编码器	帧率	视频宽高
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640,480))
while cap.isOpened():
    # 逐帧捕获
    ret, frame = cap.read()
    # 如果正确读取帧, ret为True
    if not ret:
        print("Can't receive frame (stream end?). Exiting ...")
        break
    frame = cv.flip(frame, 0)
    out.imshow('frame', frame)
    # gray = cv.cvtColor(frame, cv_COLOR_BGR2GRAY)
    # 显示结果帧
    cv.imshow('frame', gray)
    if cv.waitKey(1) == ord('q'):
        break
# 完成所有操作后,释放捕获器
cap.release()
out.release()
cv.destroyAllWindows()
获取视频、帧率、分辨率等属性
参数propld功能
cv2.CAP_PROP_POS_MSEC0视频文件的当前位置(以毫秒为单位)或视频捕获时间戳
cv2.CAP_PROP_POS_FRAMES1基于0的索引将被解码/捕获下一帧
cv2.CAP_PROP_POS_AVI_RATIO2视频文件的相对位置:0 - 视频的开始,1 - 视频的结束
cv2.CAP_PROP_FRAME_WIDTH3帧的宽度
cv2.CAP_PROP_FRAME_HEIGHT4帧的高度
cv2.CAP_PROP_FPS5帧速
cv2.CAP_PROP_FOURCC64个字符表示的视频编码器格式
cv2.CAP_PROP_FRAME_COUNT7帧数
cv2.CAP_PROP_FORMAT8byretrieve()返回的Mat对象的格式
cv2.CAP_PROP_MODE9指示当前捕获模式的后端特定值
cv2.CAP_PROP_BRIGHTNESS10图像的亮度(仅适用于相机)
cv2.CAP_PROP_CONTRAST11图像对比度(仅适用于相机)
cv2.CAP_PROP_SATURATION12图像的饱和度(仅适用于相机)
cv2.CAP_PROP_HUE13图像的色相(仅适用于相机)
cv2.CAP_PROP_GAIN14图像的增益(仅适用于相机)
cv2.CAP_PROP_EXPOSURE15曝光(仅适用于相机)
cv2.CAP_PROP_CONVERT_RGB16表示图像是否应转换为RGB的布尔标志
cv2.CAP_PROP_WHITE_BALANCE17目前不支持
cv2.CAP_PROP_RECTIFICATION18立体摄像机的整流标志
cap = cv2.VideoCapture(video_path)
fps = int(cap.get(cv2.CAP_PROP_FPS))
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
frame_all = cap.get(cv2.CAP_PROP_FRAME_COUNT)
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值