用python进行人脸识别(四)

  • OpenCV基本操作
  • 读取、保存图片
  • 改变大小、灰度转换
  • 矩形、文本
  • 调用摄像头


上一节已经成功的安装 OpneCV库,这节介绍一下OpneCV的基本用法。

OpenCV基本操作

读取、保存图片

对图片进行读取、复制、保存,在设计中需要提取图片进行分类的训练,或者调用库对图片进行识别处理,以及人脸注册时需要保存相对应人物的图片。

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功能中的冰山一角,不过足够本次设计的使用了。