标人脸图太累?来用百度云计算的人脸检测接口自动标图啊~(一)

有的时候人脸检测的需求没办法用市面上现成的训练结果,人脸更细致的分类就需要自己手动标记了,但是找到人脸位置自动生成标记文件还是交给电脑做就可以了,只要人工复核一遍就可以了。

主要情况:

  • 使用yolov3做这件事
  • 分类人脸更细致的情况
  • 做PascalVOC格式xml标注数据
  • 28W原始数据,手动标注不知道要标到猴年马月

一、过滤完全检测不到人脸的

# -*- coding: utf-8 -*-
import requests
import cv2
import os
import shutil

def get_face_location(file_path ,file_name):
    import base64
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=你的AK&client_secret=你的SK'
    header={'Content-Type': 'application/json; charset=UTF-8'}
    response1=requests.post(url=host,headers=header)#<class 'requests.models.Response'>
    json1 = response1.json()#<class 'dict'>
    access_token=json1['access_token']
    filepath=file_path+file_name
    f = open(r'%s' % filepath, 'rb')
    pic = base64.b64encode(f.read())
    f.close()
    base64=str(pic,'utf-8')
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
    params = {"image":base64,"image_type":"BASE64","face_field":"faceshape,facetype,beauty,"}
    header={'Content-Type': 'application/json'}
    request_url = request_url + "?access_token=" + access_token
    response1=requests.post(url=request_url,data=params,headers=header)#<class 'requests.models.Response'>
    json1 = response1.json()#<class 'dict'>
    # print(json1)
    if(json1["error_code"]==222202):
        print("Not found face. Move to NoFace floder")
        pass
    # print(json1["result"]["face_list"][0]["location"])
    if(json1["error_code"]==0):
        print("Processing image :",file_name)
        img = cv2.imread(filepath)
        h,w,_ = img.shape
        left = int(json1["result"]["face_list"][0]["location"]["left"])
        top = int(json1["result"]["face_list"][0]["location"]["top"])
        width = int(json1["result"]["face_list"][0]["location"]["width"])
        height = int(json1["result"]["face_list"][0]["location"]["height"])
        # 
        if(left<0):
            left=0
        if(top<0):
            top=0
        if(left+width>w):
            width = w-left
        if(top+height>h):
            height=h-top
        print(left,top,width,height,w,h)
        pass
        # cv2.rectangle(img,(left,top),(left+width,top+height),(0,255,0),5)
        # cv2.imwrite("res.jpg",img)



pre_list = "30001-40000"
lists = ["30001-31000","31001-32000","32001-33000","33001-34000","34001-35000","35001-36000","36001-37000","37001-38000","38001-39000","39001-40000"]

for aaaa in lists:
    bbbb = aaaa
    path = "/media/nvidia/WD-2T/RawData/"+pre_list+"/"+aaaa+"/"
    dirs = os.listdir(path)

    pass

    lens = len(dirs)
    i=1
    for file in dirs:
        print("["+str(i)+"/"+str(lens)+"]")
        get_face_location(path,file)
        i=i+1

部分关键逻辑代码由于保密原因已经被我换成pass了,其实就是分拣的处理过程。

这一步会自动检测人脸和非人脸,你拿到他的检测结果以后可以把它分别移动到不同的文件夹下面准备下一步操作

二、自动标注

# -*- coding: utf-8 -*-
import requests
import cv2
import os
import shutil
import sys

def gen(file_path,file_name,write_xml_file_path,label_set):
    filepath=file_path+file_name
    import base64
    host = 'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=你的AK&client_secret=你的SK'
    header={'Content-Type': 'application/json; charset=UTF-8'}
    response1=requests.post(url=host,headers=header)#<class 'requests.models.Response'>
    json1 = response1.json()#<class 'dict'>
    access_token=json1['access_token']

    f = open(r'%s' % filepath, 'rb')
    pic = base64.b64encode(f.read())
    f.close()
    base64=str(pic,'utf-8')
    request_url = "https://aip.baidubce.com/rest/2.0/face/v3/detect"
    params = {"image":base64,"image_type":"BASE64","face_field":"faceshape,facetype,beauty,"}
    header={'Content-Type': 'application/json'}
    request_url = request_url + "?access_token=" + access_token
    response1=requests.post(url=request_url,data=params,headers=header)#<class 'requests.models.Response'>
    json1 = response1.json()#<class 'dict'>
    # print(json1)
    # if(json1["error_code"]==222202):
    #     print("Not found face. Move to NoFace floder")
    #     shutil.move(file_path+file_name, "3/"+file_name)
    # # print(json1["result"]["face_list"][0]["location"])
    if(json1["error_code"]==0):
        print("Processing image :",file_name)
        img = cv2.imread(filepath)
        h,w,_ = img.shape
        left = int(json1["result"]["face_list"][0]["location"]["left"])
        top = int(json1["result"]["face_list"][0]["location"]["top"])
        width = int(json1["result"]["face_list"][0]["location"]["width"])
        height = int(json1["result"]["face_list"][0]["location"]["height"])
        # 
        if(left<0):
            left=0
        if(top<0):
            top=0
        if(left+width>w):
            width = w-left
        if(top+height>h):
            height=h-top
        print(left,top,width,height,w,h)

        res_str = ""
        part1 = "<annotation><folder>jiaobaba</folder><filename>"
        part2 = "</filename><path>"
        part3 = "</path><source><database>Unknown</database></source><size><width>"
        part4 = "</width><height>"
        part5 = "</height><depth>"
        part6 = "</depth></size><segmented>0</segmented>"
        t1 = "<object><name>"
        t2 = "</name><pose>Unspecified</pose><truncated>1</truncated><difficult>0</difficult><bndbox><xmin>"
        t3 = "</xmin><ymin>"
        t4 = "</ymin><xmax>"
        t5 = "</xmax><ymax>"
        t6 = "</ymax></bndbox></object>"
        res_str = part1+file_name+part2+file_path+file_name+part3+str(w)+part4+str(h)+part5+str("3")+part6
        tmp_v3 = ""
        tmp_v3 = tmp_v3 + t1+label_set+t2+str(left)+t3+str(top)+t4+str(left+width)+t5+str(top+height)+t6
        res_str = res_str + tmp_v3 + "</annotation>"

        every_line_xml_path = write_xml_file_path+file_name.split(".")[0]+".xml"
        file_xml = open(every_line_xml_path,'w')
        file_xml.write(res_str)
        file_xml.close()


pre_list = "20001-30000"
lists = ["20001-21000" ,"21001-22000"  ,"22001-23000","23001-24000","24001-25000","25001-26000","26001-27000","27001-28000","28001-29000","29001-30000"]


for aaaas in lists:
    aaaa = "/media/nvidia/WD-2T/RawData/"+pre_list+"/"+aaaas+"/"

    floder_path = aaaa+"normal"+"/"
    write_xml_file_path = floder_path
    dirs = os.listdir(floder_path)
    lens = len(dirs)
    i = 1
    for file in dirs:
        print("["+str(i)+"/"+str(lens)+"]")
        gen(floder_path,file,floder_path,"normal_label")
        i = i + 1
    print("done.")

其中有几点需要注意:

  • 用到的接口还是上面那个,他会返回人脸坐标的位置,x,y,w,h,但是是那种溢出图片尺寸的坐标,需要手动修正到图片范围内
  • xml标注文件的本质就是一个字符串,只不过是里面的内容需要换成变量的形式
  • 我们仿照xml标注的内容把我们自己的值给换进去然后写出来就行了
  • 上一步分文件夹的原因就是到这一步的时候会把一个文件夹内的图片label都给写死,减少因为标记错误需要修改的文件数量
  • 最后使用labelimg复查一遍就可以了

补充:

  • labelimg有些东西其实不是特别方便,比如更改标签的快捷键是Ctrl+E,比如预定义的类别
  • 快捷键可以直接在源码里面改,我直接改成了E,方便的不得了
  • 预定义类别全删了,改成自己的爽歪歪
  • 哦,我说的是Ubuntu下面的labelimg,Windows的好像被打包成exe了改不了

三、最后

百度这个接口需要到百度云计算里面创建应用的,这样你就有了AK和SK,就是一串随机码了。

目前单线程和双线程是免费的,但是不知道为啥双线程我用的时候有问题~

免费的哎,就算是收费的也不贵,人像分割那个接口简直白菜价

百度打钱!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值