Opencv中的深度学习(人脸检测、车牌检测、DNN)

首先,无论是做检测还是DNN图像分类,所有的模型或配置文件都需要从以下三个网站中下载IT大牛们帮我们创建的各种分类器:

# 人脸检测
''' https://github.com/opencv/opencv/tree/master/data/haarcascades '''
# googlenet caffemodel权重文件
''' http://dl.caffe.berkeleyvision.org/ ''' 
# googlenet caffemodel配置文件
''' https://github.com/opencv/opencv_extra/tree/master/testdata/dnn ''' 

下面将会围绕三个主要例子进行讲解,代码可直接copy:


1. 人脸检测之哈尔(Haar)级联法:对完整脸部的有较好的检测效果,但对于不完整脸部识别效果差,这是传统算法的缺陷所在,泛化能力比较差。

函数参数:detectMultiScale(img,scaleFactor,minNeighbors)

  • scaleFactor:缩放尺寸

  • minNeighbors:最小像素值

代码案例(以视频流为例):

import cv2
# 创建Haar级联器
facer = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
cap = cv2.VideoCapture(0)
while (1):
    # get a frame
    ret, frame = cap.read()
    # 调用接口
    faces = facer.detectMultiScale(frame, 1.1, 5)
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.imshow('img', frame)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()

Haar级联器还可以对脸部中细节特征进行识别,比如对眼睛进行检测(以图像为例):

import cv2
# 创建Haar级联器
facer = cv2.CascadeClassifier('./haarcascades/haarcascade_frontalface_default.xml')
eyer = cv2.CascadeClassifier('./haarcascades/haarcascade_eye.xml')
img = cv2.imread('p3.png')
# 调用接口
faces = facer.detectMultiScale(img , 1.1, 5)
i = 0
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 = eyer.detectMultiScale(ROI_img, 1.1, 5)
    for (x,y,w,h) in eyes:
        cv2.rectangle(ROI_img, (x,y), (x+w, y+h), (0,255,0), 2)
    i += 1
    name = 'img'+str(i)
    cv2.imshow(name, ROI_img)
cv2.waitKey()

 2. Haar+Tesseract 车牌检测:

  • Haar级联器仅用于定位车牌的位置。精度还是很不错的。
  • Tesseract用于提取其中的内容,但其精度要逊色与OCR。tesseract是Python的一个OCR(光学字符识别)库。tesseract的exe下载路径为:https://github.com/UB-Mannheim/tesseract/wiki 安装成功后会在相应磁盘下有Tesseract-OCR文件夹。
  • 代码案例(以图像流为例):
    import pytesseract
    # 创建Haar级联器
    carer = cv2.CascadeClassifier('./haarcascades/haarcascade_russian_plate_number.xml')
    img = cv2.imread('chinacar.jpeg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 调用接口 
    cars = carer.detectMultiScale(gray, 1.1, 3)
    for (x,y,w,h) in cars:
        cv2.rectangle(img, (x,y), (x+w, y+h), (0,0,255), 2)
    # 提取ROI
    roi = gray[y:y+h, x:x+w]
    # 二值化
    ret, roi_bin = cv2.threshold(roi, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
    # 文字识别
    pytesseract.pytesseract.tesseract_cmd = r"E:\Tesseract_OCR\tesseract.exe"
    text = pytesseract.image_to_string(roi, lang='chi_sim+eng',config='--psm 8 --oem 3')
    print(text)
    cv2.putText(img, text, (20,100), cv2.FONT_HERSHEY_SIMPLEX, 2, (0,255,255), 3)
    cv2.imshow('img', img)
    cv2.waitKey()

 3. DNN图像分类

  • Opencv中的DNN尽可以支持检测,但不能训练。

  • DNN使用步骤:

    • 读取模型,得到网络结构:readNet(model,[config])

    • 读取数据(图片或视频)。

    • 将图片转成张量:blobFromImage(image,scalefactor,size,mean,swapRB,crop)

    • 送入网络:net.setInput(blob)

    • 模型输出结果:net.forward()

  • 使用案例:

    # 导入模型
    config = "./model/bvlc_googlenet.prototxt"
    model = "./model/bvlc_googlenet.caffemodel"
    net = dnn.readNetFromCaffe(config, model)
    
    # 加载图片,转成张量
    img = cv2.imread('./smallcat.jpeg')
    blob = dnn.blobFromImage(img, 1.0, (224,224), (104,117,123))
    
    # 模型推理
    net.setInput(blob)
    r = net.forward()
    idxs = np.argsort(r[0])[::-1][:5]
    
    # 分类结果展示
    path = './model/synset_words.txt'
    with open(path, 'rt') as f:
        classes = [x[x.find(" ")+1:]for x in f]
    for (i, idx) in enumerate(idxs):
    # 将结果展示在图像上
        if i == 0:
            text = "Label: {}, {:.2f}%".format(classes[idx],
                r[0][idx] * 100)
            cv2.putText(img, text, (5, 25),  cv2.FONT_HERSHEY_SIMPLEX,
                0.7, (0, 0, 255), 2)
    # 显示图像
    cv2.imshow("Image", img)
    cv2.waitKey(0)

猜你喜欢

转载自blog.csdn.net/qq_42308217/article/details/123247496