项目要点
1. 人脸识别项目: 需要导入相关的分类器, 然后使用API与目标图进行对照, 返回四个值(X,Y, W, H).
- Haar级联器: facer = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
- 检测人脸: faces = facer.detectMultiScale(gray, scaleFactor = 1.2, minNeighbors = 4)
- CascadeClassifier() # 加载分类器
- facer.detectMultiScale(gray, 1.1, 3) # 分类对照
2.车牌检测: 方法类似, 使用分类器, 最后用tesseract进行识别, 为了保证识别效果, 中间用开操作去噪提升识别效果.
- CascadeClassifier() # 加载分类器
- car.detectMultiScale(gray) # 分类对照
- cv2.morphologyEx() # 开操作
- pytesseract.image_to_string(roi, lang='chi_sim+eng', config='--psm 8 --oem 3') # 识别车牌
3. 图片转文字: text = pytesseract.image_to_string(Image.open('1.png'), lang='chi_sim+eng')
4. 开运算: roi = cv2.morphologyEx(roi_bin, cv2.MORPH_OPEN, kernel, iterations = 1) # 开运算 = 腐蚀 + 膨胀 去除图像外部的噪点 .
1. 人脸检测
首先我们要搞清楚人脸检测中的一些概念.
人脸检测: 在一张图像中判断是否存在人脸并找出人脸所在的位置
人脸识别: 在人脸检测的基础上收集人脸数据集合进行处理保存信息,将输入人脸与保存的信息进行比对校验,得到是否为其中某个人脸
特征值: 以某种特定规则对输入源进行处理得到具有唯一性质量化的值,在人脸识别中特征值的提取有 HOG-方向梯度直方图 , HAAR-like特征 , LBP-局部二进制模式 三种方法.
分类器: 根据特征值界定输入事物是否属于已知某种类别的过滤条件组合,未知类别的算聚类器,弱分类器:分类器的正确率高于随机分类(50%),强分类器:能满足预期分类并且正确率很高的分类器.
Adaboost: 迭代算法,同一个训练集合下训练多个弱分类器,把弱分类器迭代组合成一个强分类器.
级联分类器: 将多个同类型的分类器联合起来进行推算整合以得到符合目标的最终分类器的方法.
1.1 分类器生成及使用
一个高准确率的级联分类器的主要生成步骤如下:
- 1.大量样本集合,特征值的提取
- 2.通过adaboost 训练多个弱分类器并迭代为强分类器
- 3.多层级联强分类器,得到最终的级联分类器 这些训练流程完成之后结果以xml的方式保存起来,就是分类器文件,opencv中包含了以上的实现,并且已经存放了许多已经训练好的不同类型的不同特征值提取生成的的级联分类器
Opencv中可以直接加载这些分类器文件,并且给出了便捷的API
-
CascadeClassifier()
-
参数1:image–待检测图片,一般为灰度图像加快检测速度;
-
参数2:objects–被检测物体的矩形框向量组;
-
参数3:scaleFactor–表示在前后两次相继的扫描中,图像被缩放的比例,1.1即每次缩放10% 用于检测
-
参数4:minNeighbors–表示构成检测目标的相邻矩形的最小个数(默认为3个)。 如果组成检测目标的小矩形的个数和小于 min_neighbors - 1 都会被排除。 如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框, 这种设定值一般用在用户自定义对检测结果的组合程序上(使用默认值即可)
-
参数5:flags–要么使用默认值,要么使用CV_HAAR_DO_CANNY_PRUNING,如果设置为 CV_HAAR_DO_CANNY_PRUNING,那么函数将会使用Canny边缘检测来排除边缘过多或过少的区域, 因为这些区域通常不会是人脸所在区域;
-
参数6、7:minSize和maxSize用来限制得到的目标区域的范围。
-
1.2 人脸检测
# 世界物理学家合照识别
import cv2
import numpy as np
#第一步,创建Haar级联器
facer = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
#第二步,导入人脸识别的图片并将其灰度化
img = cv2.imread('./322a1792fb4fd575aaf6fa809607aa82.jpg')
#第三步,进行人脸识别 [[x,y,w,h]]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(gray.shape, type(facer)) # (830, 1600) <class 'cv2.CascadeClassifier'>
# 检测人脸
faces = facer.detectMultiScale(gray, scaleFactor = 1.2, minNeighbors = 4)
# 画出检测出的人脸框
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
1.3 眼睛检测
# 眼睛检测
import cv2
import numpy as np
# 第一步,创建Haar级联器
facer = cv2.CascadeClassifier('./haarcascade_frontalface_alt2.xml')
eye = cv2.CascadeClassifier('./haarcascade_eye.xml')
# 第二步,导入人脸识别的图片并将其灰度化
img = cv2.imread('./p3.png')
# 第三步,进行人脸识别 [[x,y,w,h]]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print(gray.shape, type(facer)) # (598, 600) <class 'cv2.CascadeClassifier'>
#检测出的人脸上再检测眼睛
faces = facer.detectMultiScale(gray, scaleFactor = 1.2, minNeighbors = 4)
# 画出检测出的人脸框
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
roi_img = img[y: y+ h, x: x+ w]
eyes = eye.detectMultiScale(roi_img)
for (x, y, w, h) in eyes:
cv2.rectangle(roi_img, (x, y), (x + w, y + h), (0, 255, 0), 2)
roi_eye = roi_img[y: y+ h, x: x+ w]
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
2. 车牌识别
我们可以利用opencv提供的车牌检测功能把车牌检测出来, 然后进行形态学处理消除一些噪声, 最后使用tesseract进行车牌识别.
tesseract安装
-
苹果: brew install tesseract tesseract-lang
-
ubantu: apt install tesseract tesseract-lang
-
windows: 网上下载tesseract安装包.
-
安装完成后需要设置环境变量.
-
在系统path路径中添加tesseract的路径.
-
添加名为TESSDATA_PREFIX的系统变量
-
-
安装完tesseract之后, 需要在python环境安装pytesseract包.
pytesseract可以让大家在python环境中使用tesseract的功能.
2.1 文字识别
- pytesseract 文字识别
from PIL import Image
import pytesseract
text = pytesseract.image_to_string(Image.open('1.png'), lang='chi_sim+eng')
print(text)
'''e 苹果: brew install tesseract tesseract-lang
e ubantu: apt install tesseract tesseract-lang
e windows: 网上下载tesseract安装包.'''
2.2 车牌识别
import cv2
import numpy as np
import pytesseract
img = cv2.imread('./chinacar.jpeg')
# 黑白图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 创建级联器 # 识别数字区域, 减少范围
car = cv2.CascadeClassifier('./haarcascade_russian_plate_number.xml')
cars = car.detectMultiScale(gray)
print(cars) # [[183 239 128 43]]
# 画出识别区
for (x, y, w, h) in cars:
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
roi = gray[y: y + h, x: x + w]
print(roi.shape) # (43, 128)
# 进行形态学操作
# 二值化
ret, roi_bin = cv2.threshold(roi, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
print(roi_bin.shape) # (43, 128)
# 开操作
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
# kernel = np.ones(shape = (3, 3), dtype = np.uint8)
roi = cv2.morphologyEx(roi_bin, cv2.MORPH_OPEN, kernel, iterations = 1)
num = pytesseract.image_to_string(roi, lang = 'chi_sim+eng')
print(num) # 上5N555
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()