上一节已经成功的安装 OpneCV库,这节介绍一下OpneCV的基本用法。
对图片进行读取、复制、保存,在设计中需要提取图片进行分类的训练,或者调用库对图片进行识别处理,以及人脸注册时需要保存相对应人物的图片。
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
#PIL(Python Imaging Library)是python内置的图像处理标准库
img = cv2.imread('test.jpg')#读取图片
cv2.imshow('test',img) #显示图片
new_img = img.copy() #拷贝图片
cv2.imshow('newimage', new_img)
cv2.imwrite('new_image.jpg', new_img)
#存储图片 第一个参数为保存的名称 第二个参数为要保存的图片
cv2.imwrite('new_image1.jpg', new_img, (cv2.IMWRITE_JPEG_QUALITY, 20))
#保存图片 第三个参数是图片的清晰度参数
#cv2.IMWRITE_JPEG_QUALITY 设置jpg格式0-100的值域 数字越高清晰度越好 默认95
#cv2.IMWRITE_PNG_COMPRESSION设置png 值域0-9 默认3 数字越高清晰度越差
在人脸识别中,经常需要将原图转化为灰度图。因为识别人脸是根据特征法来的,而此方法不通过色彩进行。而将有色图转化为灰度图,降低了图片的复杂度,可以减少识别需要的时间。
gary_image = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
#转化为灰度图 第一参数为原图 第二个参数命令RGB TO GARY 转化为灰度
cv2.imshow('gary', gary_image)
gary_image[...] = 0 #转化为黑色的图片 三个色度都为0
cv2.imshow('black', gary_image)
cv2.waitKey(0)
在处理图片时,将图片先缩小,处理完成后再进行放大,可以极大的提高工作效率。因为图片缩小后,所含的数组量会相应的缩小,相当于数组规模的减小,计算量就减少。
print(img.shape)
#返回图片的的尺寸(行,列)及维数 3表示RGB 即有色图
print(gary_image.shape)
#返回尺寸 没有维度 默认为灰度图 维度为2
#改变图片的大小
change_img = cv2.resize(img, (0,0), fx=0.5, fy=0.5)
#第一个参数为改变的图片 第二个参数如果为(0,0)
#则第三 第四个参数为图片原横、纵长度的倍数
#fx=0.5 即新图片的横坐标为原图片的0.5倍 fy同理
#0.5*0.5=0.25 新图片为原图片的四分之一大小
cv2.imshow('change_img', change_img)
change_img1 = cv2.resize(img, (0,0), fx=1.5, fy=1.2)
#第五个参数为差值方法 共有五种 此处采用默认 有兴趣的可以自行了解
#横为原来的1.5倍 纵为原来的1.2倍
cv2.imshow('change_img1', change_img1)
change_img2 = cv2.resize(img, (400,500), interpolation=cv2.INTER_CUBIC)
#若第二个参数不为(0,0) 则图片大小变为第二个参数所设定的值 此处为(400,500) 与原图片的大小无关
#此处的第三个参数为差值方法 可默认 也可自行设置
cv2.imshow('change_image2', change_img2)
cv2.waitKey(0)
OpenCV支持在图片上画圆、矩形等图案。在人脸识别中,经常用圆或者矩形来标识人脸的区域,检测系统的运行效果。同时,利用OpenCV还可以在图片上输入字符串,但是OpenCV没有内置输入汉字功能,但使用PIL库辅助OpenCV,编写相对应的函数,就可以实现显示汉字的功能。
#定义显示中文的函数 注意调用本文开头的那三个库
def change_cv2_draw(image, strs, local, size, color):
''' 在图片上显示汉字 输入为 图片,汉字字符,左上角坐标, 字体大小, 字体颜色
返回处理后的图片'''
cv2img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg)
font = ImageFont.truetype("simhei.ttf", size, encoding="utf-8")
draw.text(local, strs, color, font=font)
image = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
return image
cv2.rectangle(img, (0,0), (100,100), (0,0,255), 2)
#现在颜色的编码模式为 BGR (0,0,255)为红色
#手册上说第一个参数为图片 第二个参设矩阵左上角坐标 第三个参数为矩阵右下角坐标
#第四位矩阵颜色 第五位矩阵线宽大小
#实际操作发现 第二 第三个参数只要是矩阵的两个对角就可以
cv2.putText(img, 'test', (50,50), cv2.FONT_HERSHEY_DUPLEX, 1.0, (255,0,0), 2)
#参数为 图片、待显示字符串、左上角坐标、字体格式、字体大小、字体颜色、字体的粗细
#网上说第三个参数为左上角 但我总感觉是左下角 不需要太精确的显示就无所谓
img = change_cv2_draw(img, '文本', (100,200), 50, (0,255,0))
#调用上面的函数 显示汉字
cv2.imshow('change', img)
cv2.waitKey(0)
实时进行处理,一定需要用到摄像头,好在OpenCV可以直接调用电脑自身的摄像头,可以调用外设摄像头。
cap = cv2.VideoCapture(0)
#调用摄像头 编号0代表计算自身的摄像头
while True: #不停的刷新 实时显示摄像头图片
ret,image = cap.read()
#ret为True或Flase 表示是否读取到图片
#image为当前一帧的图片
cv2.imshow('cap',image)
#如果案件按下且为字母q 则退出循环
#waitkey上一节已将将了 选择刷新的时间为1ms
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release() #释放摄像头
cv2.destroyAllWindows() #关闭所有窗口
一定要有最后的if语句,否则一帧一帧之间没有间隔缓冲,所造成的效果就是灰屏。计算器显示图片也需要一定的时间,帧与帧之间必须留有一定的时间。当然,如果时间太长最终的结果会呈现卡顿。同理,在后期需要对图片进行对应处理的时候,也要留有一定的时间来保证图片处理完成。否则,程序会直接卡死,因为逻辑没问题,但是物理实现需要一定时间。
这些只是OpenCV功能中的冰山一角,不过足够本次设计的使用了。