TP5 结合百度 AI 人脸识别技术教程

2019-06-22    标签:AI    阅读:325    评论:0


百度AI开放平台:http://ai.baidu.com/

百度API文档-v3-人脸检测:https://ai.baidu.com/docs#/Face-Detect-V3/top

人脸识别接口分为V2和V3两个版本,本文档为V3版本接口的说明文档,请确认您在百度云后台获得的是V3版本接口权限

辨别接口版本的方法是:在百度云后台进入【应用列表】,点击【应用名称】,在【API列表】中可以看到【请求地址】,若请求地址中带有【v3】标识,则您具有的是v3权限;若请求地址中带有【v2】标识,则您具有的是v2权限

能力介绍

接口能力

● 人脸检测:检测图片中的人脸并标记出位置信息;

● 人脸关键点:展示人脸的核心关键点信息,及150个关键点信息。

● 人脸属性值:展示人脸属性信息,如年龄、性别等。

● 人脸质量信息:返回人脸各部分的遮挡、光照、模糊、完整度、置信度等信息。


业务应用

典型应用场景:如人脸属性分析,基于人脸关键点的加工分析,人脸营销活动等。


鉴权认证机制

针对HTTP API调用者,百度AIP开放平台使用OAuth2.0授权调用开放API,调用API时必须在URL中带上accesss_token参数,获取Access Token的流程如下:


获取Access Token

请求URL数据格式

向授权服务地址https://aip.baidubce.com/oauth/2.0/token发送请求(推荐使用POST),并在URL中带上以下参数:


● grant_type: 必须参数,固定为client_credentials;

● client_id: 必须参数,应用的API Key;

● client_secret: 必须参数,应用的Secret Key;

例如:

<?php
function request_post($url = '', $param = '') {
        if (empty($url) || empty($param)) {
            return false;
        }
        
        $postUrl = $url;
        $curlPost = $param;
        $curl = curl_init();//初始化curl
        curl_setopt($curl, CURLOPT_URL,$postUrl);//抓取指定网页
        curl_setopt($curl, CURLOPT_HEADER, 0);//设置header
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        curl_setopt($curl, CURLOPT_POST, 1);//post提交方式
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        $data = curl_exec($curl);//运行curl
        curl_close($curl);
        
        return $data;
    }

	$url = 'https://aip.baidubce.com/oauth/2.0/token';
    $post_data['grant_type']       = 'client_credentials';
    $post_data['client_id']      = '你的 Api Key';
    $post_data['client_secret'] = '你的 Secret Key';
    $o = "";
    foreach ( $post_data as $k => $v ) 
    {
    	$o.= "$k=" . urlencode( $v ). "&" ;
    }
    $post_data = substr($o,0,-1);
    
    $res = request_post($url, $post_data);

    var_dump($res);

?>

● 服务器返回的JSON文本参数如下:

● access_token: 要获取的Access Token;

● expires_in: Access Token的有效期(秒为单位,一般为1个月);

其他参数忽略,暂时不用;

例如:

{
  "refresh_token": "25.b55fe1d287227ca97aab219bb249b8ab.315360000.1798284651.282335-8574074",
  "expires_in": 2592000,
  "scope": "public wise_adapt",
  "session_key": "9mzdDZXu3dENdFZQurfg0Vz8slgSgvvOAUebNFzyzcpQ5EnbxbF+hfG9DQkpUVQdh4p6HbQcAiz5RmuBAja1JJGgIdJI",
  "access_token": "24.6c5e1ff107f0e8bcef8c46d3424a0e78.2592000.1485516651.282335-8574074",
  "session_secret": "dfac94a3489fe9fca7c3221cbf7525ff"
}

若请求错误,服务器将返回的JSON文本包含以下参数:

● error: 错误码;关于错误码的详细信息请参考下方鉴权认证错误码。

● error_description: 错误描述信息,帮助理解和解决发生的错误。

例如认证失败返回:

{
    "error": "invalid_client",
    "error_description": "unknown client id"
}

鉴权认证错误码

● errorerror_description解释

● invalid_clientunknown client idAPI Key不正确

● invalid_clientClient authentication failedSecret Key不正确


获取 access_token  后,使用HTTPS POST发送:

https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=24.f9ba9c5341b67688ab5added8bc91dec.2592000.1485570332.282335-8574074

请求说明

注意事项:

● 请求体格式化:Content-Type为application/json,通过json格式化请求体。

● Base64编码:请求的图片需经过Base64编码,图片的base64编码指将图片数据编码成一串字符串,使用该字符串代替图像地址。您可以首先得到图片的二进制,然后用Base64格式编码即可。需要注意的是,图片的base64编码是不包含图片头的,如data:image/jpg;base64,

● 图片格式:现支持PNG、JPG、JPEG、BMP,不支持GIF图片

● 人脸识别接口分为V2和V3两个版本

请求示例

HTTP方法:POST

请求URL: https://aip.baidubce.com/rest/2.0/face/v3/detect

URL参数:

参数
access_token通过API Key和Secret Key获取的access_token,参考“Access Token获取

Header:

参数
Content-Typeapplication/json

Body中放置请求参数,参数详情如下:

请求参数

参数必选类型说明
imagestring图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断
image_typestring图片类型
BASE64:图片的base64值,base64编码后的图片数据,编码后的图片大小不超过2M;
URL:图片的 URL地址( 可能由于网络等原因导致下载图片时间过长);
FACE_TOKEN: 人脸图片的唯一标识,调用人脸检测接口时,会为每个人脸图片赋予一个唯一的FACE_TOKEN,同一张图片多次检测得到的FACE_TOKEN是同一个。
face_fieldstring包括age,beauty,expression,face_shape,gender,glasses,landmark,landmark150,race,quality,eye_status,emotion,face_type信息
逗号分隔. 默认只返回face_token、人脸框、概率和旋转角度
max_face_numuint32最多处理人脸的数目,默认值为1,仅检测图片中面积最大的那个人脸;最大值10,检测图片中面积最大的几张人脸。
face_typestring人脸的类型
LIVE表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等
IDCARD表示身份证芯片照:二代身份证内置芯片中的人像照片
WATERMARK表示带水印证件照:一般为带水印的小图,如公安网小图
CERT表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片
默认LIVE
liveness_controlstring活体控制 检测结果中不符合要求的人脸会被过滤
NONE: 不进行控制
LOW:较低的活体要求(高通过率 低攻击拒绝率)
NORMAL: 一般的活体要求(平衡的攻击拒绝率, 通过率)
HIGH: 较高的活体要求(高攻击拒绝率 低通过率)
默认NONE

说明:face_field参数,默认只返回人脸框、概率和旋转角度,age等更多属性,请在此参数中添加。

请求示例代码

提示一:使用示例代码前,请记得替换其中的示例Token、图片地址或Base64信息。

提示二:部分语言依赖的类或库,请在代码注释中查看下载地址。

PHP代码:

<?php
/**
 * 发起http post请求(REST API), 并获取REST请求的结果
 * @param string $url
 * @param string $param
 * @return - http response body if succeeds, else false.
 */
function request_post($url = '', $param = '')
{
    if (empty($url) || empty($param)) {
        return false;
    }

    $postUrl = $url;
    $curlPost = $param;
    // 初始化curl
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $postUrl);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    // 要求结果为字符串且输出到屏幕上
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    // post提交方式
    curl_setopt($curl, CURLOPT_POST, 1);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
    // 运行curl
    $data = curl_exec($curl);
    curl_close($curl);

    return $data;
}

$token = '[调用鉴权接口获取的token]';
$url = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' . $token;
$bodys = "{\"image\":\"027d8308a2ec665acb1bdf63e513bcb9\",\"image_type\":\"FACE_TOKEN\",\"face_field\":\"faceshape,facetype\"}"
$res = request_post($url, $bodys);

var_dump($res);


说明

● 返回参数

  • 返回结果

字段必选类型说明
face_numint检测到的图片中的人脸数量
face_listarray人脸信息列表,具体包含的参数参考下面的列表。
+face_tokenstring人脸图片的唯一标识
+locationarray人脸在图片中的位置
++leftdouble人脸区域离左边界的距离
++topdouble人脸区域离上边界的距离
++widthdouble人脸区域的宽度
++heightdouble人脸区域的高度
++rotationint64人脸框相对于竖直方向的顺时针旋转角,[-180,180]
+face_probabilitydouble人脸置信度,范围【0~1】,代表这是一张人脸的概率,0最小、1最大。
+angelarray人脸旋转角度参数
++yawdouble三维旋转之左右旋转角[-90(左), 90(右)]
++pitchdouble三维旋转之俯仰角度[-90(上), 90(下)]
++rolldouble平面内旋转角[-180(逆时针), 180(顺时针)]
+agedouble年龄 ,当face_field包含age时返回
+beautyint64美丑打分,范围0-100,越大表示越美。当face_fields包含beauty时返回
+expressionarray表情,当 face_field包含expression时返回
++typestringnone:不笑;smile:微笑;laugh:大笑
++probabilitydouble表情置信度,范围【0~1】,0最小、1最大。
+face_shapearray脸型,当face_field包含face_shape时返回
++typedoublesquare: 正方形 triangle:三角形 oval: 椭圆 heart: 心形 round: 圆形
++probabilitydouble置信度,范围【0~1】,代表这是人脸形状判断正确的概率,0最小、1最大。
+genderarray性别,face_field包含gender时返回
++typestringmale:男性 female:女性
++probabilitydouble性别置信度,范围【0~1】,0代表概率最小、1代表最大。
+glassesarray是否带眼镜,face_field包含glasses时返回
++typestringnone:无眼镜,common:普通眼镜,sun:墨镜
++probabilitydouble眼镜置信度,范围【0~1】,0代表概率最小、1代表最大。
+eye_statusarray双眼状态(睁开/闭合) face_field包含eye_status时返回
++left_eyedouble左眼状态 [0,1]取值,越接近0闭合的可能性越大
++right_eyedouble右眼状态 [0,1]取值,越接近0闭合的可能性越大
+emotionarray情绪 face_field包含emotion时返回
++typestringangry:愤怒 disgust:厌恶 fear:恐惧 happy:高兴
sad:伤心 surprise:惊讶 neutral:无情绪
++probabilitydouble情绪置信度,范围0~1
+racearray人种 face_field包含race时返回
++typestringyellow: 黄种人 white: 白种人 black:黑种人 arabs阿拉伯人
++probabilitydouble人种置信度,范围【0~1】,0代表概率最小、1代表最大。
+face_typearray真实人脸/卡通人脸 face_field包含face_type时返回
++typestringhuman: 真实人脸 cartoon: 卡通人脸
++probabilitydouble人脸类型判断正确的置信度,范围【0~1】,0代表概率最小、1代表最大。
+landmarkarray4个关键点位置,左眼中心、右眼中心、鼻尖、嘴中心。face_field包含landmark时返回
+landmark72array72个特征点位置 face_field包含landmark72时返回
+landmark150array150个特征点位置 face_field包含landmark150时返回
+qualityarray人脸质量信息。face_field包含quality时返回
++occlusionarray人脸各部分遮挡的概率,范围[0~1],0表示完整,1表示不完整
+++left_eyedouble左眼遮挡比例,[0-1] ,1表示完全遮挡
+++right_eyedouble右眼遮挡比例,[0-1] , 1表示完全遮挡
+++nosedouble鼻子遮挡比例,[0-1] , 1表示完全遮挡
+++mouthdouble嘴巴遮挡比例,[0-1] , 1表示完全遮挡
+++left_cheekdouble左脸颊遮挡比例,[0-1] , 1表示完全遮挡
+++right_cheekdouble右脸颊遮挡比例,[0-1] , 1表示完全遮挡
+++chindouble下巴遮挡比例,,[0-1] , 1表示完全遮挡
++blurdouble人脸模糊程度,范围[0~1],0表示清晰,1表示模糊
++illuminationdouble取值范围在[0~255], 表示脸部区域的光照程度 越大表示光照越好
++completenessint64人脸完整度,0或1, 0为人脸溢出图像边界,1为人脸都在图像边界内

● 返回示例

{	
  "face_num": 1,
  "face_list": [
        {
            "face_token": "35235asfas21421fakghktyfdgh68bio",
            "location": { 
                "left": 117,
                "top": 131,
                "width": 172,
                "height": 170,
                "rotation": 4
            },
            "face_probability": 1,
            "angle" :{
                 "yaw" : -0.34859421849251
                 "pitch" 1.9135693311691  
                 "roll" :2.3033397197723  
            }
            "landmark": [  
                {
                    "x": 161.74819946289,
                    "y": 163.30244445801
                },
                ...
            ],
            "landmark72": [ 
                {
                    "x": 115.86531066895,
                    "y": 170.0546875
                },
                ...
            ],
            "age": 29.298097610474,
            "beauty": 55.128883361816,
            "expression": {
                "type": "smile",
                "probability" : 0.5543018579483
            },
            "gender": {
                "type": "male",
                "probability": 0.99979132413864
            },
            "glasses": {
    			"type": "sun",
                "probability": 0.99999964237213
            },
            "race": {
                "type": "yellow",
                "probability": 0.99999976158142
            },
            "face_shape": {
                "type": "triangle",
                "probability": 0.5543018579483
            }
            "quality": {
                "occlusion": {
                    "left_eye": 0,
                    "right_eye": 0,
                    "nose": 0,
                    "mouth": 0,
                    "left_cheek": 0.0064102564938366,
                    "right_cheek": 0.0057411273010075,
                    "chin": 0
                },
                "blur": 1.1886881756684e-10,
                "illumination": 141,
                "completeness": 1
            }
        }
    ]
}

72个关键点分布图(对应landmark72个点的顺序,序号从0-71):

 

150个关键点分布图,红色关键点为在72关键点基础上增加的关键点(对应landmark150个点的顺序,序号从0-149,且每个关键点有对应的英文命名作为参数名,请参考图片下方表格): 

关键点名称如下图, 

tp5 + 百度AI人脸识别示例代码:

// AI人工智能
    public function getAIimg(){
        $file = request()->file('urlimg');
        $info = $file->move(ROOT_PATH . 'public' . DS . 'static/uploads/AI');
        if($info){
           $img=ROOT_PATH.'/public/static/uploads/AI/'.date('Ymd').'/'.$info->getFilename();
           $image = \think\Image::open(ROOT_PATH.'/public/static/uploads/AI/'.date('Ymd').'/'.$info->getFilename());
            // 按照原图的比例生成一个最大为150*150的缩略图并保存为thumb.png
           $image->thumb(300, 300)->save(ROOT_PATH.'/public/static/uploads/AI/'.date('Ymd').'/'.$info->getFilename());
            // $img=ROOT_PATH.'/public/static/uploads/AI/20190612/d866f443451579cbd1d5da557348b4f2.jpg';
           $url = 'https://aip.baidubce.com/oauth/2.0/token';
            $post_data['grant_type'] = 'client_credentials';
            $post_data['client_id'] = 'client_id';
            $post_data['client_secret'] = 'client_secret';
            $o = "";
            foreach ( $post_data as $k => $v ) 
            {
                $o.= "$k=" . urlencode( $v ). "&" ;
            }
            $post_data = substr($o,0,-1);
            
            $res =$this->request_post($url, $post_data);
            $jsonarr = json_decode($res, true);
            $token=$jsonarr['access_token'];
            $token = $token;

            $url = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' . $token;
            $param = array(
              'image' => $this->base64EncodeImage($img),
              'image_type' => 'BASE64',
              'face_field' => 'age,beauty,expression,gender,emotion,quality,glasses,face_shape'
              // 'face_field' => 'age,beauty,expression,face_shape,gender,glasses,landmark,landmark150,race,quality,eye_status,emotion,face_type'
             );
             $param = json_encode($param);
             $res =$this->request_post($url, $param);
             $result = json_decode($res, true);
             if($result['error_code'] != 0){
                 return json(['msg'=>'失败','code'=>'700','message'=>'上传的人脸不符合要求,请重新上传五官清晰的真实头像']);
                 die;
             }
             $quality = $result['result']['face_list'][0]['age'];  //年龄 
             // $beauty = $result['result']['face_list'][0]['beauty'];
             $beauty = round($result['result']['face_list'][0]['beauty']); //美丑打分,范围0-100,越大表示越美
             $expression = $result['result']['face_list'][0]['expression']['type'];   //表情none:不笑;smile:微笑;laugh:大笑
             $gender = $result['result']['face_list'][0]['gender']['type'];// 性别 male:男性 female:女性
             $emotion = $result['result']['face_list'][0]['emotion']['type'];  //情绪 angry:愤怒 disgust:厌恶 fear:恐惧 happy:高兴 sad:伤心 surprise:惊讶 neutral:无情绪
             $glasses = $result['result']['face_list'][0]['glasses']['type'];   //是否带眼镜,face_field包含,glasses时返回none:无眼镜,common:普通眼镜,sun:墨镜
             $face_shape = $result['result']['face_list'][0]['face_shape']['type'];   //脸型,当face_field包含face_shape时返回,square: 正方形 triangle:三角形 oval: 椭圆 heart: 心形 round: 圆形
            $sex =$gender=='male'?'男':'女';
            if($emotion=='angry'){
                $emotion='愤怒'; 
            }else if ($emotion=='disgust') {
                $emotion='厌恶';
            }else if ($emotion=='fear') {
                $emotion='恐惧';
            }else if ($emotion=='happy') {
                $emotion='高兴';
            }else if ($emotion=='sad') {
                $emotion='伤心';
            }else if ($emotion=='surprise') {
                $emotion='惊讶';
            }else{
                $emotion='无情绪';
            }

            if($expression=='none'){
                $expression='不笑'; 
            }else if ($emotion=='smile') {
                $expression='微笑';
            }else{
                $expression='大笑';
            }
            if($glasses=='none'){
                $glasses='无眼镜'; 
            }else if ($glasses=='common') {
                $glasses='普通眼镜';
            }else{
                $glasses='墨镜';
            }
            if($face_shape=='square'){
                $face_shape='正方形'; 
            }else if ($face_shape=='triangle') {
                $face_shape='三角形';
            }else if ($face_shape=='oval') {
                $face_shape='椭圆';
            }else if ($face_shape=='heart') {
                $face_shape='心形';
            }else{
                $face_shape='圆形';
            }


            $re_data['img']='/public/static/uploads/AI/'.date('Ymd').'/'.$info->getFilename();
            $re_data['result']='年龄:'.$quality.'<br>'.'美丑打分:'.$beauty.'<br>'.'表情:'.$expression.'<br>'.'性别:'.$sex.'<br>'.'情绪:'.$emotion.'<br>'.'眼镜:'.$glasses.'<br>'.'脸型:'.$face_shape;
            $re_data['addtime']=time();
            $re_data['nick_name']=input('nickName');
            $re= db('minwx_ai')->insert($re_data);
            $re_dum=array(
                'sex'=>$sex,  //性别
                'quality'=>$quality,    //年龄
                'beauty'=>$beauty,     //美丑打分
                'expression'=>$expression,     //表情
                'emotion'=>$emotion,     //情绪
                'glasses'=>$glasses,     //眼镜
                'face_shape'=>$face_shape,     //脸型
                'img'=>'/public/static/uploads/AI/'.date('Ymd').'/'.$info->getFilename(),     //图片
                'nick_name'=>input('nickName'),
                );
            return json(['msg'=>'成功','code'=>'200','re_dum'=>$re_dum]);
             
        }
    }
    public function base64EncodeImage($image_path) {
     $base64_image = '';
     $image_info = getimagesize($image_path);
     $image_data = fread(fopen($image_path, 'r'), filesize($image_path));
     $base64_image = chunk_split(base64_encode($image_data));
     return $base64_image;
    }
    public function request_post($url = '', $param = '') {
        if (empty($url) || empty($param)) {
            return false;
        }
        $postUrl = $url;
        $curlPost = $param;
        $curl = curl_init();//初始化curl
        curl_setopt($curl, CURLOPT_URL,$postUrl);//抓取指定网页
        curl_setopt($curl, CURLOPT_HEADER, 0);//设置header
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        curl_setopt($curl, CURLOPT_POST, 1);//post提交方式
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        $data = curl_exec($curl);//运行curl
        curl_close($curl);
        
        return $data;
    }
    public function getAI(){
            $resSetupAI=db('minwx_setup')->find();

            $img=ROOT_PATH.'/public/static/uploads/AI/yan.jpg';
            // $img=ROOT_PATH.'/public/static/uploads/AI/timg.jpg';
            $url = 'https://aip.baidubce.com/oauth/2.0/token';
            $post_data['grant_type'] = 'client_credentials';
            $post_data['client_id'] = $resSetupAI['client_id'];
            $post_data['client_secret'] = $resSetupAI['client_secret'];
            $o = "";
            foreach ( $post_data as $k => $v ) 
            {
                $o.= "$k=" . urlencode( $v ). "&" ;
            }
            $post_data = substr($o,0,-1);
            
            $res =$this->request_post($url, $post_data);
            $jsonarr = json_decode($res, true);
            $token=$jsonarr['access_token'];
            $token = $token;

            $url = 'https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=' . $token;
            $param = array(
              'image' => $this->base64EncodeImage($img),
              'image_type' => 'BASE64',
              'face_field' => 'age,beauty,expression,gender,emotion,quality'
              // 'face_field' => 'age,beauty,expression,face_shape,gender,glasses,landmark,landmark150,race,quality,eye_status,emotion,face_type'
             );
             $param = json_encode($param);
             $res =$this->request_post($url, $param);
             $result = json_decode($res, true);
             if($result['error_code'] != 0){
                 return json(['msg'=>'失败','code'=>'700','message'=>'上传的人脸不符合要求,请重新上传五官清晰的真实头像']);
                 die;
             }
             $quality = $result['result']['face_list'][0]['age'];  //年龄 
             // $beauty = $result['result']['face_list'][0]['beauty'];
             $beauty = round($result['result']['face_list'][0]['beauty']); //美丑打分,范围0-100,越大表示越美
             $expression = $result['result']['face_list'][0]['expression']['type'];   //表情none:不笑;smile:微笑;laugh:大笑
             $gender = $result['result']['face_list'][0]['gender']['type'];// 性别 male:男性 female:女性
             $emotion = $result['result']['face_list'][0]['emotion']['type'];  //情绪 angry:愤怒 disgust:厌恶 fear:恐惧 happy:高兴 sad:伤心 surprise:惊讶 neutral:无情绪
             $eye_status = $result['result']['face_list'][0]['quality'];
             // $eye_statusL = $result['result']['face_list'][0]['eye_status']['left_eye'];  //左眼状态 [0,1]取值,越接近0闭合的可能性越大
             // $eye_statusR = $result['result']['face_list'][0]['eye_status']['right_eye']; //右眼状态 [0,1]取值,越接近0闭合的可能性越大
             halt($result);
    }


【腾讯云】云产品采购季,助力行业复工。1核2G云服务器,首年99元

‘简忆博客’微信公众号 扫码关注‘简忆博客’微信公众号,获取最新文章动态
转载:请说明文章出处“来源简忆博客”。http://www.tpxhm.com/adetail/150.html

×
觉得文章有用就打赏一下文章作者
微信扫一扫打赏 微信扫一扫打赏
支付宝扫一扫打赏 支付宝扫一扫打赏

文章评论(0)

登录

博主信息

头像

今天努力一点,知识一点点积累,谢谢那个曾经努力的自己!

职业:Web工程师

Email:2938039696@qq.com

学习交流群:简忆blogs技术群

项目合作:2938039696

置顶推荐

站点信息

1028运行天数

318文章数量

主题框架:Foundation5
网站地图:XML网站地图
微信公众号:扫码关注公众号
公众号

打赏本站

如果你觉得本站很棒,可以通过扫码支付打赏哦!
微信扫码:你说多少就多少~
微信扫码
支付宝扫码:你说多少就多少~
支付宝扫码
×
×
×