【注意读取路径差异】
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()