目录
一、os模块
常用函数:
二、视频处理
1、视频逐帧导出图片(OpenCV)
操作步骤:
完整代码:
运行结果:
2、图片逐帧合成视频(FFMpeg)
合成视频:
播放视频:
三、图像处理
1、图像处理类型
①打开图像文件
②复制并粘贴图像区域(简单换眼)
③图像轮廓和直方图
④高斯模糊
⑤Sobel算子
⑥图像分割
⑦负片效果
2、图像处理与人脸识别(熊猫头表情包)
操作步骤:
运行结果:
完整代码:
一、os模块
常用函数:
os.listdir():
os.listdir(path) #返回指定的文件夹包含的文件或文件夹的名字的列表
for file in dirs:
print(file)
os.getcwd():
print(os.getcwd()) #获取当前路径
os.chdir():
os.chdir(path) #改变当前目录到指定目录中
os.mkdir(dir_name):
dir_name = "./images" #新建文件夹
if not os.path.exists(dir_name): #判断文件夹是否存在
os.mkdir(dir_name)
os.makedirs(dir_name2,exist_ok=True):
dir_name2 = "./images2/imgs2" #可以递归的创建多个文件夹
os.makedirs(dir_name2, exist_ok=True) #当文件夹已经存在就不创建
二、视频处理
1、视频逐帧导出图片(OpenCV)
操作步骤:
- cv2.VideoCapture()打开视频,.get(cv2.CAP_PROP_FRAME_COUNT)获取帧数信息
- 逐帧打印(灰度)图片,cv2.imwrite()保存图像
完整代码:
import cv2
video_path='ghz.mp4'
image_save='./pic' #os.mkdir()或手动创建文件夹
cap=cv2.VideoCapture(video_path)
video_frame_count=cap.get(cv2.CAP_PROP_FRAME_COUNT) #获取视频帧数信息
for i in range(int(video_frame_count)):
_, img = cap.read() #不需要第一个参数,所有标“_”
img=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #转换成灰度图片
cv2.imwrite('./pic/image{}.jpg'.format(i),img)
运行结果:
2、图片逐帧合成视频(FFMpeg)
FFMpeg主要参数
-i——设置输入档名 | -f——设置输出格式 |
-y——若输出文件已存在时则覆盖文件 | -fs——超过指定的文件大小时则结束转换 |
-t——指定输出文件的持续时间,以秒为单位 | -ss——从指定时间开始转换,以秒为单位 |
-title——设置标题 | -timestamp——设置时间戳 |
-vsync——增减Frame使影音同步 | -c——指定输出文件的编码 |
-metadata——更改输出文件的元数据 | -help——查看帮助信息 |
-t从-ss时间开始转换(如-ss 00:00:01.00 -t 00:00:10.00即从00:00:01.00开始到00:00:11.00) |
FFMpeg命令分类
合成视频:
D:\python learning\opencv>"./ffmpeg/bin/ffmpeg.exe" -f image2 -i ./pic/image%d.jpg -r 24 output.mp4
播放视频:
ffplay output.mp4(ffplay.exe与视频放在同一目录下)
三、图像处理
1、图像处理类型
①打开图像文件
问题记录:
生成的灰度图呈绿色,解决方法:为plt.imshow()添加参数cmap=“gray”
完整代码:
from PIL import Image
from pylab import *
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
figure()
im1=Image.open('girl.png')
print(im1.format,im1.size,im1.mode)
plt.title(u'原图',fontproperties=font)
plt.imshow(im1)
plt.axis('off')
plt.show()
im2= Image.open('girl.png').convert('L') #转换成灰度图
print(im2.format,im2.size,im2.mode)
title(u'灰度图',fontproperties=font)
plt.imshow(im2,cmap='gray')
plt.axis('off')
plt.show()
运行结果:
函数使用:
convert()函数用于不同模式图像之间的转换:
PIL中有九种不同模式,分别为1,L,P,RGB,RGBA,CMYK,YCbCr,I,F。
模式“1” 二值图像,非黑即白;每个像素用1个bit表示,0表示黑,255表示白
模式“L” 灰色图像,每个像素用8个bit表示,数字表示不同的灰度
模式“P” 彩色图像,每个像素用8个bit表示,其对应的彩色值是按照调色板查询出来的
模式“RGBA” 彩色图像,每个像素用32个bit表示,其中24bit表示红色、绿色和蓝色三个通道,另外8bit表示alpha通道(透明通道)
模式“CMYK” 彩色图像,每个像素用32个bit表示,印刷四分色模式
②复制并粘贴图像区域(简单换眼)
操作步骤:
- 使用detector进行人脸检测,打印人脸的5个标定点坐标
- 显示原图,判断人眼的区域
- 复制原图1的眼睛区域,粘贴到原图2的眼睛区域
部分代码:
from PIL import Image
from pylab import *
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14) #添加中文字体支持
figure()
pil_im = Image.open('yyqx.jpg')
print(pil_im.mode, pil_im.size, pil_im.format)
title(u'原图1', fontproperties=font)
axis('off')
imshow(pil_im)
show()
pil_im2 = Image.open('Emma.jpg')
print(pil_im2.mode, pil_im2.size, pil_im2.format)
title(u'原图2', fontproperties=font)
axis('off')
imshow(pil_im2)
show()
pil_im = Image.open('yyqx.jpg')
box = (180, 255, 225, 270) #数值通过人脸五个标定点的坐标获取
region = pil_im.crop(box)
box2=(192,234,237,249) #数值通过人脸五个标定点的坐标获取
pil_im2.paste(region, box2) #复制并粘贴区域
title(u'换眼后', fontproperties=font)
axis('off')
imshow(pil_im2)
运行结果:
函数使用:
使用 crop() 方法可以从一幅图像中裁剪指定区域:
box = (100,100,400,400)
region = pil_im.crop(box)
该区域使用四元组来指定。四元组的坐标依次是(左,上,右,下)。PIL 中指定坐标系的左上角坐标为(0,0)。
可以旋转上面代码中获取的区域,然后使用paste() 方法将该区域放回去:
region = region.transpose(Image.ROTATE_180)
pil_im.paste(region,box)
③图像轮廓和直方图
完整代码:
from PIL import Image
from pylab import *
import matplotlib.pyplot as plt
im=array(Image.open('girl.png').convert('L')) #读取图像到数组中
figure() #新建一个图像
gray() #不使用颜色信息
contour(im,origin='image') #在原点的左上角显示轮廓图像
axis('equal')
axis('off')
figure()
hist(im.flatten(),128)
show()
运行结果:
参数含义:
hist(x[, bins, range, normed, weights, cumulative, bottom, histtype, align, orientation, rwidth, log, color, label, stacked, hold, **kwargs])
x 作直方图所要用的数据,必须是一维数组(多维数组可以先进行扁平化再作图)
bins 直方图的柱数,可选项,默认为10
④高斯模糊
完整代码:
from numpy import *
from scipy.ndimage import filters
from PIL import Image
import matplotlib.pyplot as plt
im=array(Image.open('girl.png').convert('L'))
im2=filters.gaussian_filter(im,5) #第二个参数sigma值越大,滤波之后的图像越模糊
plt.figure()
plt.imshow(im2)
plt.show()
运行结果:
⑤Sobel算子
sobel算子是图像边缘检测的最重要的算子之一
完整代码:
from PIL import Image
from numpy import *
from scipy.ndimage import filters
import matplotlib.pyplot as plt
from pylab import *
from matplotlib.font_manager import FontProperties
font = FontProperties(fname=r"c:\windows\fonts\SimSun.ttc", size=14)
figure()
im=array(Image.open('girl.png').convert('L'))
imx=zeros(im.shape)
filters.sobel(im,1,imx) #sobel()第二个参数表示选择x或者y方向导数,第三个参数保存输出的变量
subplot(1,4,2)
plt.imshow(imx,cmap='gray')
axis("off")
title(u'x导数图像', FontProperties=font)
imy=zeros(im.shape)
filters.sobel(im,0,imy)
subplot(1,4,3)
plt.imshow(imy,cmap='gray')
axis("off")
title(u'y导数图像', FontProperties=font)
magnitude=sqrt(imx**2+imy**2)
subplot(1,4,4)
plt.imshow(magnitude,cmap='gray')
axis("off")
title(u'梯度大小图像', FontProperties=font)
show()
运行结果:
(正导数显示为亮的像素,负导数显示为暗的像素,灰色区域表示导数的值接近于零)
⑥图像分割
完整代码:
from PIL import Image
from numpy import *
from scipy.ndimage import measurements
import matplotlib.pyplot as plt
im=array(Image.open('girl.png').convert('L')) #载入图像,使用阈值化操作,以保证处理的图像为二值图像
im=1*(im<128) #通过和1相乘,将布尔数组转换成二进制表示
labels,nbrobjects=measurements.label(im) #用label()函数寻找单个的物体,并按照它们属于哪个对象将整数标签给像素赋值
print("对象个数=",nbrobjects)
plt.figure()
plt.imshow(im)
plt.show()
运行结果:
⑦负片效果
完整代码:
from PIL import Image
import matplotlib.pyplot as plt
im=array(Image.open('girl.png'))
im2=255-im #逐像素修改
plt.figure()
plt.imshow(im2)
plt.show()
运行结果:
2、图像处理与人脸识别(熊猫头表情包)
操作步骤:
- 使用face_recognition.face_landmarks()获取脸部轮廓信息,并在人脸上描绘出来
- 新建原图大小的全白图片,用ImageDraw在上面勾出人脸轮廓
- 使用cv2重新读入原图,用膨胀腐蚀来消除噪声、强化表情,截取表情
- 使用paste()函数将表情贴入背景图
- 对图片进行二值化处理,输出表情包
运行结果:
完整代码:
import face_recognition
import numpy as np
import cv2
from PIL import Image, ImageDraw, ImageFont
face_line = list()#用于记录脸部轮廓信息,之后做掩膜要用
image = face_recognition.load_image_file("hp.jpg")
face_landmarks_list = face_recognition.face_landmarks(image)
#打印此图像中眉毛和脸型组成的轮廓
for face_landmarks in face_landmarks_list:
facial_features = ['chin','left_eyebrow','right_eyebrow']
for facial_feature in facial_features:
print("{} points: {}".format(facial_feature, face_landmarks[facial_feature]))
#图像中描绘出每个人脸特征
pil_image = Image.fromarray(image)
d = ImageDraw.Draw(pil_image)
chin = face_landmarks['chin']
left_eyebrow = face_landmarks['left_eyebrow']
right_eyebrow = face_landmarks['right_eyebrow']
chin.reverse()
list_all = left_eyebrow + right_eyebrow + chin + [left_eyebrow[0]]
face_line.append(list_all)
d.line(list_all, width=5)
pil_image.save("Facial_contour.jpg")
#新建一个和原图一样大小的全白图片,用ImageDraw在上面勾出人脸轮廓,作为掩膜的模板
mask = np.ones(image.shape, dtype=np.uint8)*255
mask = Image.fromarray(mask)
q = ImageDraw.Draw(mask)
q.line(face_line[0], width=5, fill=(0, 0, 0))
mask.save("mask.jpg")#将图片写出,交给OpenCV处理
#生成掩膜
mask = cv2.imread('mask.jpg')
h, w = mask.shape[:2] #读取图像的宽和高
mask_flood = np.zeros([h + 2, w + 2], np.uint8) #新建图像矩阵(+2是官方函数要求)
cv2.floodFill(mask, mask_flood, (75, 75), (0, 0, 0))#使用OpenCV的水漫填充,把轮廓外部涂成黑色,内部为白色
kernel = np.ones((2, 2), np.uint8)#用一个2*2的卷积核对掩膜进行闭运算,去掉噪声
erosion = cv2.erode(mask, kernel, iterations=1)
dilation = cv2.dilate(erosion, kernel, iterations=1)
mask = dilation
#重新读入原图,框出RIO,交给OpenCV处理
image = cv2.imread("hp.jpg")
image[mask == 0] = 0
GrayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)#将处理过的图片变为灰度图
ret, image = cv2.threshold(GrayImage, 80, 255, cv2.THRESH_BINARY)#二值化处理
#再来一次水漫填充,把轮廓之外的地方变成白色
h, w = image.shape[:2]
mask_flood = np.zeros([h + 2, w + 2], np.uint8)
cv2.floodFill(image, mask_flood, (1, 1), (255, 255, 255))
#输入表情需要截取的部分,不同图的参数不同
image = image[140:250, 90:230]
cv2.imwrite("last.png",image)#输出图片,给Image做处理
box = (100, 100, 300, 250)#背景图要被替换的部分
base_img = Image.open('background.jpg')
image = Image.open('last.png')
image = image.resize((box[2] - box[0], box[3] - box[1]))#缩放表情,贴入的表情必须和背景被替换的地方大小相同
base_img.paste(image, box)
base_img.show()
base_img.save('out.png')#输出图片,给cv2做处理
#对图片再进行一次二值化处理
image = cv2.imread(r'out.png')
GrayImage = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
ret,image = cv2.threshold(GrayImage,85,255,cv2.THRESH_BINARY)
cv2.imwrite("last_out.jpg", image)
cv2.waitKey(0)