python3--利用百度智能平台实现目标人物跟踪标记

本文介绍了如何使用Python3结合百度智能平台进行目标人物跟踪标记。通过视频读入、人脸检测、人脸对比和目标标注四个步骤,详细阐述了从图片Base64编码到调用人脸对比API,再到结果标注的全过程。

一、事件描述

  事件目的是为了在实时监控中发现、追踪目标人物。在进行具体项目实验前利用百度智能平台进行测试。
 版本信息:python3.7 、opencv-python 4.1

二、过程解析

总览

整体结构包括:1.视频读入、2.人脸检测、3.人脸对比、4目标标注

1.视频读入

    cap=cv.VideoCapture(0)#0为调用本机摄像头,调用其他摄像头序号应该对应。如果读取视频,改为视频地址
    while(1):  
        ret, frame = cap.read()
        if not ret:
            print("打开摄像头失败")
            break
        """对每一帧的其他操作..."""
        c=cv.waitKey(20)
        if c==27:#esc键的键盘输入值为27,该段意为当按下esc键时退出
            cap.release()
            cv.destroyAllWindows() 
            break   


2.人脸检测

人脸检测利用的是opencv包中已经训练好的分类器haarcascade_frontalface_default,该分类器是保存在opencv包目录下的.xml文件,调用过程如下:

def face_detect_demo(image):
    """脸部检测"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    face_detector = cv.CascadeClassifier(r"C:\ProgramData\Anaconda3\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml")#haarcascade_frontalface_default.xml
    faces = face_detector.detectMultiScale(gray, 1.1, 2)
    return(faces)

输入:待检测的图片(已通过cv2.imread读取为数组格式)
输出:检测到的人脸位置
调用示例
待测图片(C:\Users\Administrator\Desktop\lyf.jpg)

src=cv2.imread('C:\\Users\\Administrator\\Desktop\\lyf.jpg')
id_face=face_detect_demo(src)

在这里插入图片描述
输出结果

array([[ 43,  88, 334, 334]], dtype=int32)

结果解释:43,88 为检测到的人脸左上角位置,334,334是检测到的人脸范围(宽度和高度),因此可以构造出人脸的四个顶点位置为:

(43,88)(43+334,88)
(43,88+334)(43+334,88+334)

显示结果

src=cv2.imread('C:\\Users\\Administrator\\Desktop\\刘亦菲.jpg')
cv2.rectangle(src, (43, 88,334,334), (0, 0, 255), 1)
#cv2.rectangle绘制矩形cv2.rectangle(原图,矩形位置大小,颜色,宽度)
cv2.imwrite('C:\\Users\\Administrator\\Desktop\\lyf_face.jpg',src)
cv2.waitKey(0)

在这里插入图片描述

3.人脸对比与目标标注

这里使用的是百度智能平台的人脸对比API,使用规则如下:
注意事项
请求体格式化:Content-Type为application/json,通过json格式化请求体。
Base64编码:请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。您可以首先得到图片的二进制,然后用Base64格式编码即可。需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64,
图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片

3.1图片转码

因为后期需要对两张图片对比,因此同时将两张图片转码
输入
img1:待对比图片ID
img2:目标图片ID

import base64
import json
def get_img(img1,img2):
    """读取图片并转码"""
    with open(img1, "rb") as f:
        pic1 = f.read()
    with open(img2, "rb") as f:
        pic2 = f.read()
    params = json.dumps([
        {"image": str(base64.b64encode(pic1), "utf-8"), "image_type": "BASE64", "face_type": "LIVE", "quality_control": "LOW"},
        {"image": str(base64.b64encode(pic2), "utf-8"), "image_type": "BASE64", "face_type": "LIVE", "quality_control": "LOW"}
    ])
    return params
3.2获取token值,拼接api
import requests
api1 = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=lVfov6E1oaWZR9f4qIhd9Hjy&client_secret=Gubrc6RnMTdA3Eb8WumHIGrz4vHgCTdy"
api2 = "https://aip.baidubce.com/rest/2.0/face/v3/match?access_token="

def get_token():
    response = requests.get(api1)
    access_token = eval(response.text)['access_token']
    api_url = api2 + access_token
    return api_url
3.3请求API结果

输入
img1: 待对比图片ID
img2:目标图片ID,命名方式为目标名称
输出:相似度大于80%,判定待测图片为目标人物,返回目标名称,否则返回’’

def than_img(img1, img2):
    name=''
    api_url = token
    params = get_img(img1, img2)
    try:
        content = requests.post(api_url, params).text#获得原始
        print('content:\n',content)
        score = eval(content)['result']['score']#原始结果中提取相似度值
        print('score:\n',score)
        if score > 80:
            name=img2.split('\\')[-1][:-4]
    except:
        Exception
    return name

示例
目标图片:C:\Users\Administrator\Desktop\刘亦菲.jpg
待测图片1:C:\Users\Administrator\Desktop\l_2.jpg
待测图片2:C:\Users\Administrator\Desktop\h_2.jpg

在这里插入图片描述

#对比图片'l_2'与图片'刘亦菲'
than_img('C:\\Users\\Administrator\\Desktop\\l_2.jpg','C:\\Users\\Administrator\\Desktop\\刘亦菲.jpg')
content:
 {"error_code":0,
  "error_msg":"SUCCESS",
  "log_id":8984156510115,
  "timestamp":1573535665,
  "cached":0,
  "result":{"score":94.68978119,
            "face_list":[{"face_token":"9ab23808650d8bcf1a5a4bb143e16e7c"},
                         {"face_token":"4223d599df69a544553536a777b6f301"}
                         ]
            }
  }
score:
 94.68978119
Out[76]: '刘亦菲'

#对比图片'h_2'与图片'刘亦菲'
than_img('C:\\Users\\Administrator\\Desktop\\h_2.jpg','C:\\Users\\Administrator\\Desktop\\刘亦菲.jpg')
content:
 {"error_code":0,
  "error_msg":"SUCCESS",
  "log_id":9945940012012,
  "timestamp":1573535858,
  "cached":0,
  "result":{"score":11.75086212,
            "face_list":[{"face_token":"ca6fd4e1f1ea82c0ad21962c6392ff3e"},
                         {"face_token":"4223d599df69a544553536a777b6f301"}
                        ]
            }
 }
score:
 11.75086212
Out[77]: ''
3.4 目标标注

opencv中图片指定位置直接标注中文会显示为‘’如下:

src=cv.imread(r'C:\Users\Administrator\Desktop\fff\lyf_face.jpg')
cv.putText(src, '刘亦菲', (45,90), cv.FONT_HERSHEY_COMPLEX, 1, (0,255,0), 1, 4, 1)
cv.imwrite(r'C:\Users\Administrator\Desktop\fff\lyf_chinese.jpg',src)

在这里插入图片描述
利用PIL 模块构建图像中文显示函数

from PIL import Image, ImageDraw, ImageFont
def add_chinese(img, text, left, top, textColor, textSize):
    """图片中的中文显示"""
    if (isinstance(img, np.ndarray)): 
        img = Image.fromarray(cv.cvtColor(img, cv.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(img)
    fontText = ImageFont.truetype(
        "font/simsun.ttc", textSize, encoding="utf-8")
    draw.text((left, top), text, textColor, font=fontText)
    return cv.cvtColor(np.asarray(img), cv.COLOR_RGB2BGR)

示例

src=cv.imread(r'C:\Users\Administrator\Desktop\fff\lyf_face.jpg')
res=add_chinese(src, '刘亦菲', 45, 90, (0,255,0), 20)
cv.imshow('l_4_face',res)
cv.waitKey(0)

在这里插入图片描述

三、 结束语

到这里,我们已经完成了对单一目标人物的识别和标记,通过调用摄像头或者读入视频文件,可以对目标人物进行实时标记跟踪,对于多目标的情况,仅仅需要添加多个目标人模即可,详细的介绍下一篇会补充。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值