【注意读取路径差异】
1读取图片
import cv2 as cv
img=cv.imread('gh.png')#读取图片路径不能有中文
cv.imshow('show_img',img)#窗口名称在前面(用中文会乱码),读取的对象在后面
cv.waitKey(0)#等待键盘输入,单位毫秒
#最后记住释放内存
cv.destroyAllWindows()
2 图片转换灰度
import cv2 as cv
img=cv.imread('gh.png')
cv.imshow('old_BGR_img',img)
gary_img=cv.cvtColor(img,cv.COLOR_RGB2GRAY)
cv.imshow('gary_img',gary_img)
#想要保存变化之后的图片的话,使用imwrite(多次运行只会保存一张,因为名字不重复)
cv.imwrite('gary_gh.jpg',gary_img)
cv.waitKey(0)
cv.destroyAllWindows()
3 修改图片大小
import cv2 as cv
img=cv.imread('gh.png')
cv.imshow('old_size_img',img)
#读取原来图片的像素大小
print('原来图片的参数:',img.shape)
######
resize_img=cv.resize(img,dsize=(400,400))#记住使用一个变量接收会很方便
cv.imshow('new_size_img',resize_img)
cv.imwrite('new_size_gh.jpg',resize_img)
#修改后图片的大小
print('修改后图片参数:',resize_img.shape)
######
#cv.waitKey(0)#这个是任意键退出,可以指定一个按键之类的退出(虽然感觉没啥用)
while True:
if ord('Q')==cv.waitKey(0): #注意这里waitKey的K必须是大写。而且ord()只能识别一个字母,并且这个字母也区分大小写。
break
cv.destroyAllWindows()
4 绘制矩形
import cv2 as cv
img=cv.imread('gh.png')
cv.imshow('not_edge_img',img)
#左上角坐标x,y;w和h为长和高
x,y,w,h=50,50,100,100
####
#绘制矩形的命令
#第二个的括号里填写的元组,写的是矩形左上角和右下角的坐标
#这里使用了BGR的G通道,所以显示的是绿色
cv.rectangle(img,(x,y,w+x,h+y),color=(0,255,0),thickness=2)
#绘制圆圈的命令
#从左到右分别是:读出的图片代称,原点,半径,颜色,粗细
x,y,r=50,50,40
cv.circle(img,center=(x,y),radius=r,color=(0,0,255),thickness=2)
cv.imshow('have_edge_img',img)
#可以同时画的,xy几个参数的定义不会互相影响
cv.waitKey(0)
cv.destroyAllWindows()
5 人脸检测
import cv2 as cv
#img=cv.imread('gh.png')
def face_det():
#将图像降维
gary=cv.cvtColor(img,cv.COLOR_RGB2GRAY)
#图像特征数据加载
#粘贴路径之后 要把 斜杠 反过来,而且最后也要加具体数据
face_det_a=cv.CascadeClassifier('D:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
#输入需要检测的图像
faces=face_det_a.detectMultiScale(gary,scaleFactor=1.05,minNeighbors=7)
'''
detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None)
image: 待检测图像,一般为灰度图
scaleFactor: 表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1,即每次搜索窗口依次扩大10 %。而且必须大于1
minNeighbors: 表示构成检测目标的相邻矩形的最小个数(默认为3个)。我们可以通过设置矩形个数调整检测准确率,如果检测到的错误目标比较多,我们增大相邻矩形个数,如果检测不到目标,或者很少,我们可以减少相邻矩形的个数,放大尺度。
flags: 一般不设置,如果使用,只能设置为CV_HAAR_DO_CANNY_PRUNING, 函数将会使用Canny边缘检测来排除边缘过多或者过少的区域,因此这些区域通常不会是人脸所在区域。
minSize、maxSize: 用来限制得到的目标区域范围。
'''
for x,y,w,h in faces:
#画方框
cv.rectangle(img,(x,y),(x+w,y+h),color=(120,255,214),thickness=2)
#画圆
cv.circle(img,center=(x+w//2,y+h//2),radius=w//2,color=(120,130,0),thickness=2)
'''注意这里画圆的时候必须使用//来整除'''
cv.imshow('result',img)
#上面是编写模块
img=cv.imread('gh.png') #这句上面或者下面写都没问题
face_det() #运行这个定义的函数,因为这个函数里面已经定义了img为对象了,所以直接运行
cv.waitKey(0)
#cv.imshow('face_img',img)
cv.destroyAllWindows()
6 检测视频人脸
import cv2 as cv
def face_det(img):
# 将图像降维
gary = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
# 图像特征数据加载
# 粘贴路径之后 要把 斜杠 反过来,而且最后也要加具体数据
face_det_a = cv.CascadeClassifier('D:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
# 输入需要检测的图像
faces = face_det_a.detectMultiScale(gary)
for x, y, w, h in faces:
cv.rectangle(img, (x, y), (x + w, y + h), color=(120, 255, 214), thickness=2)
cv.circle(img, center=(x+w//2, y+h//2), radius=w//2, color=(120, 130, 0), thickness=2)
cv.imshow('result', img)
#读取video
cap=cv.VideoCapture('video.mp4')
while True:
flag,frame=cap.read()
#flag是一个标记的意思,frame读出一帧一帧的
if not flag:
break
face_det(frame)
if ord('q')==cv.waitKey(1):
break
cv.destroyAllWindows()
cap.release()
7 训练数据
import os #路径的
import cv2 as cv
import sys
import numpy as np
from PIL import Image
'''写完faces,ids=getImgAndLabls(path)之后可以回来编写方法'''
def getImgAndLabs(path):
facesSamples=[]
ids=[]
imgPaths=[os.path.join(path,f) for f in os.listdir(path)] #'''这里列了一个列表,存放的是每一张图的路径精确到每张图的名称。'''
#print(imgPaths)
face_det_a = cv.CascadeClassifier('D:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
# 输入需要检测的图像
for imgPath in imgPaths:
#打开图片
PIL_img=Image.open(imgPath).convert('L') #'''这里的L模式是转换成8bit灰度图'''
img_numpy=np.array(PIL_img,'uint8') #'''numpy还没学'''#转换成数组
faces = face_det_a.detectMultiScale(img_numpy)
id=int(os.path.split(imgPath)[1].split('.')[0]) #因为图片名字用的是数字,所以要将str转换成int整数。如果有英文则可以hash转换成数字?
'''这里的[1]的作用是自动分割路径和文件名后,只输出分割的第二部分东西也就是文件名,因为计数是从0开始的,所以1是第二个部分。
[0]的作用是将分割出来的文件名以.为分割符号分开后,只输出第一部分东西'''
for x,y,w,h in faces:
facesSamples.append(img_numpy[y:y+h,x:x+w])
ids.append(id)
return facesSamples,ids
if __name__ == '__main__': #这行命令能帮助你让这句代码只在这个py模块里执行
path='./train/jam/'
faces,ids=getImgAndLabs(path)
recognizer=cv.face.LBPHFaceRecognizer_create()
recognizer.train(faces,np.array(ids))
recognizer.write('trainer/trainer.yml')
8 人脸识别
import cv2 as cv
import numpy as np
import os
recogizer=cv.face.LBPHFaceRecognizer_create()
recogizer.read('trainer/trainer.yml')
img=cv.imread('./train/test/888.png') #这里我是用的是我的路径的图片
gary=cv.cvtColor(img, cv.COLOR_RGB2GRAY)
face_det_a = cv.CascadeClassifier('D:\opencv\sources\data\haarcascades\haarcascade_frontalface_default.xml')
# 输入需要检测的图像
faces = face_det_a.detectMultiScale(gary)
for x, y, w, h in faces:
cv.rectangle(img, (x, y), (x + w, y + h), (120, 255, 214), 2)
id, confidence = recogizer.predict(gary[y:y + h, x:x + w]) # 这个函数会返回俩值一个id,一个置信度
print('id是:',id,'置信度是:',confidence)
cv.imshow('result', img)
cv.waitKey(0)
cv.destroyAllWindows()