基于OpenCV的人脸识别考勤系统(三)
目录
六、百度智能云人脸库的创建
七、人脸识别SDK的导入
八、百度云平台的接入
六、百度智能云人脸库的创建
在百度智能云的人脸识别控制台中,申请领取免费资源,在进一步页面中我们选择领取全部免费接口即可
接下来在左侧公有云服务的应用列表中,创建应用,注意,需要将应用归属选择为个人。3
创建完成后即可看到创建情况:
接下来在可视化人脸库中新建组,上传待识别的照片即可。
七、人脸识别SDK的导入
我们可以使用百度提供的SDK完成人脸信息的上传和比对信息的接收。SDK的下载地址为SDK下载_文字识别SDK_语音识别SDK-百度AI开放平台 (baidu.com), 我们选择人脸识别中的C HTTP SDK进行下载,点击使用说明即可进入该SDK的说明文档。
根据SDK的官方文档说明,有五个步骤来使用该SDK:
- 下载压缩包
- 接下来将下载好的压缩文件解压,并放到我们虚拟机中的对应代码文件处。接下来我们将之前写的main.cpp放到解压好的aip-cpp-sdk-4.16.4文件夹中
- 安装依赖库libcurl openssl和jsoncpp,我们使用以下命令依次安装
sudo pkg-get install libcurl4-openssl-dev sudo pkg-get install openssl sudo pkg-get install libjsoncpp-dev
- 编译时要添加C++11支持,并连接第三方库
g++ main.cpp -o main -lopencv_highgui -lopencv_core -lopencv_imgproc -lopencv_objdetect -lcurl -lcrypto -ljsoncpp -std=c++11
- 在main.cpp中加入include "face.h"和using namespace aip
include "face.h"using namespace aip
如果编译报错base/http.h:23:23: fatal error: json/json.h: 没有这个文件或文件夹,那我们将base文件夹中的http.h文件第23行的#include <json/json.h>改为#include <jsoncpp/json/json.h>
同理,编译报错base/base.h:21:23: fatal error: json/json.h: 没有这个文件或文件夹时,我们将base.h21行中的#include <json/json.h>改为#include <jsoncpp/json/json.h>
编译报错base.utils.h:21:25:fatal error:openssl/evp.h:没有这个文件或文件夹时,需要安装一个新的库文件
sudo apt-get install lib-ssl-dev
八、百度云平台的接入
在之前说的SDK官方文档中,我们按照说明进行。
使用刚刚你创建应用时提供的ID,Key和Serect
接下来使用SDK文档中人脸搜索的client.search方法
该函数的参数为:
因此,我们需要先定义一个std::string类型的image和image_type,之前的图片格式是jpg的,所以需要进行一下转换,变成base64格式的
std::string base64Img;
json::value result;base64Img = base64_encode((char *)jpgBuf.data(), jpgBuf().size()); //格式转换为base64result = client.search(base64Img, "BASE64", "Student", aip::null); //这里的"Student"是你之前新建的人脸分组的名称
上述代码段的前两行需要放在for循环前面,后两行放在for循环内部的imencode函数后即可
接下来编译,会报错找不到函数search,这是因为我们下载的SDK中没有search方法,我们使用下面的代码替换“face.h”中的代码即可。现在即可正常编译运行。
/*** Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved** Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with* the License. You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the* specific language governing permissions and limitations under the License.** @author baidu aip*/#ifndef __AIP_FACE_H__
#define __AIP_FACE_H__#include "base/base.h"namespace aip {class Face: public AipBase{public:std::string _faceverify ="https://aip.baidubce.com/rest/2.0/face/v4/faceverify";std::string _detect ="https://aip.baidubce.com/rest/2.0/face/v2/detect";std::string _match ="https://aip.baidubce.com/rest/2.0/face/v2/match";std::string _identify ="https://aip.baidubce.com/rest/2.0/face/v2/identify";std::string _verify ="https://aip.baidubce.com/rest/2.0/face/v2/verify";std::string _user_add ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/user/add";std::string _user_update ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/user/update";std::string _user_delete ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/user/delete";std::string _user_get ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/user/get";std::string _group_getlist ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/group/getlist";std::string _group_getusers ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/group/getusers";std::string _group_adduser ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/group/adduser";std::string _group_deleteuser ="https://aip.baidubce.com/rest/2.0/face/v2/faceset/group/deleteuser";std::string _face_verify_v4 ="https://aip.baidubce.com/rest/2.0/face/v4/mingjing/verify";std::string _face_match_v4 ="https://aip.baidubce.com/rest/2.0/face/v4/mingjing/match";std::string _online_picture_live_v4 = "https://aip.baidubce.com/rest/2.0/face/v4/faceverify";std::string _face_search = "https://aip.baidubce.com/rest/2.0/face/v3/search";//"https://aip.baidubce.com/rest/2.0/face/capture/search";//Face(const std::string & app_id, const std::string & ak, const std::string & sk): AipBase(app_id, ak, sk){}std::string vector_join_base64(const std::vector<std::string> & v_images) {std::string images;size_t count = v_images.size();for (size_t i = 0; i < count;i++){std::string image = v_images[i];images += base64_encode(image.c_str(), (int) image.size());if (i != count) {images += ",";}}return images;}/*** detect* @param image 图像文件二进制内容,可以使用aip::get_file_content函数获取* options 可选参数:* max_face_num 最多处理人脸数目,默认值1* face_fields 包括age,beauty,expression,faceshape,gender,glasses,landmark,race,qualities信息,逗号分隔,默认只返回人脸框、概率和旋转角度*/Json::Value detect(std::string const & image,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["image"] = base64_encode(image.c_str(), (int) image.size());std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_detect, null, data, null);return result;}/*** match* @param images vector多图图像文件二进制内容,vector中每一项可以使用aip::get_file_content函数获取* options 可选参数:* ext_fields 返回质量信息,取值固定:目前支持qualities(质量检测)。(对所有图片都会做改处理)* image_liveness 返回的活体信息,“faceliveness,faceliveness” 表示对比对的两张图片都做活体检测;“,faceliveness” 表示对第一张图片不做活体检测、第二张图做活体检测;“faceliveness,” 表示对第一张图片做活体检测、第二张图不做活体检测;<br>**注:需要用于判断活体的图片,图片中的人脸像素面积需要不小于100px\*100px,人脸长宽与图片长宽比例,不小于1/3*** types 请求对比的两张图片的类型,示例:“7,13”<br>**12**表示带水印证件照:一般为带水印的小图,如公安网小图<br>**7**表示生活照:通常为手机、相机拍摄的人像图片、或从网络获取的人像图片等<br>**13**表示证件照片:如拍摄的身份证、工卡、护照、学生证等证件图片,**注**:需要确保人脸部分不可太小,通常为100px\*100px*/Json::Value match(const std::vector<std::string> & images,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["images"] = vector_join_base64(images);std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_match, null, data, null);return result;}/*** identify* @param group_id 用户组id(由数字、字母、下划线组成),长度限制128B,多个用户组id,用逗号分隔* @param image 图像文件二进制内容,可以使用aip::get_file_content函数获取* options 可选参数:* ext_fields 特殊返回信息,多个用逗号分隔,取值固定: 目前支持faceliveness(活体检测)。**注:需要用于判断活体的图片,图片中的人脸像素面积需要不小于100px\*100px,人脸长宽与图片长宽比例,不小于1/3*** user_top_num 返回用户top数,默认为1,最多返回5个*/Json::Value identify(std::string const & group_id,std::string const & image,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["group_id"] = group_id;data["image"] = base64_encode(image.c_str(), (int) image.size());std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_identify, null, data, null);return result;}/*** verify* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* @param image 图像文件二进制内容,可以使用aip::get_file_content函数获取* @param group_id 用户组id(由数字、字母、下划线组成),长度限制128B,多个用户组id,用逗号分隔* options 可选参数:* top_num 返回用户top数,默认为1* ext_fields 特殊返回信息,多个用逗号分隔,取值固定: 目前支持faceliveness(活体检测)。**注:需要用于判断活体的图片,图片中的人脸像素面积需要不小于100px\*100px,人脸长宽与图片长宽比例,不小于1/3***/Json::Value verify(std::string const & uid,std::string const & image,std::string const & group_id,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["uid"] = uid;data["image"] = base64_encode(image.c_str(), (int) image.size());data["group_id"] = group_id;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_verify, null, data, null);return result;}/*** user_add* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* @param user_info 用户资料,长度限制256B* @param group_id 用户组id,标识一组用户(由数字、字母、下划线组成),长度限制128B。如果需要将一个uid注册到多个group下,group\_id需要用多个逗号分隔,每个group_id长度限制为48个英文字符。**注:group无需单独创建,注册用户时则会自动创建group。**<br>**产品建议**:根据您的业务需求,可以将需要注册的用户,按照业务划分,分配到不同的group下,例如按照会员手机尾号作为groupid,用于刷脸支付、会员计费消费等,这样可以尽可能控制每个group下的用户数与人脸数,提升检索的准确率* @param image 图像文件二进制内容,可以使用aip::get_file_content函数获取* options 可选参数:* action_type 参数包含append、replace。**如果为“replace”,则每次注册时进行替换replace(新增或更新)操作,默认为append操作**。例如:uid在库中已经存在时,对此uid重复注册时,新注册的图片默认会**追加**到该uid下,如果手动选择`action_type:replace`,则会用新图替换库中该uid下所有图片。*/Json::Value user_add(std::string const & uid,std::string const & user_info,std::string const & group_id,std::string const & image,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["uid"] = uid;data["user_info"] = user_info;data["group_id"] = group_id;data["image"] = base64_encode(image.c_str(), (int) image.size());std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_user_add, null, data, null);return result;}/*** user_update* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* @param image 图像文件二进制内容,可以使用aip::get_file_content函数获取* @param user_info 用户资料,长度限制256B* @param group_id 更新指定groupid下uid对应的信息* options 可选参数:* action_type 目前仅支持replace,uid不存在时,不报错,会自动变为注册操作;未选择该参数时,如果uid不存在会提示错误*/Json::Value user_update(std::string const & uid,std::string const & image,std::string const & user_info,std::string const & group_id,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["uid"] = uid;data["image"] = base64_encode(image.c_str(), (int) image.size());data["user_info"] = user_info;data["group_id"] = group_id;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_user_update, null, data, null);return result;}/*** user_delete* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* @param group_id 删除指定groupid下uid对应的信息* options 可选参数:*/Json::Value user_delete(std::string const & uid,std::string const & group_id,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["uid"] = uid;data["group_id"] = group_id;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_user_delete, null, data, null);return result;}/*** user_get* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* options 可选参数:* group_id 选择指定group_id则只查找group列表下的uid内容,如果不指定则查找所有group下对应uid的信息*/Json::Value user_get(std::string const & uid,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["uid"] = uid;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_user_get, null, data, null);return result;}/*** group_getlist* options 可选参数:* start 默认值0,起始序号* end 返回数量,默认值100,最大值1000*/Json::Value group_getlist(const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_group_getlist, null, data, null);return result;}/*** group_getusers* @param group_id 用户组id(由数字、字母、下划线组成),长度限制128B* options 可选参数:* start 默认值0,起始序号* end 返回数量,默认值100,最大值1000*/Json::Value group_getusers(std::string const & group_id,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["group_id"] = group_id;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_group_getusers, null, data, null);return result;}/*** group_adduser* @param group_id 用户组id(由数字、字母、下划线组成),长度限制128B,多个用户组id,用逗号分隔* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* @param src_group_id 从指定group里复制信息* options 可选参数:*/Json::Value group_adduser(std::string const & group_id,std::string const & uid,std::string const & src_group_id,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["group_id"] = group_id;data["uid"] = uid;data["src_group_id"] = src_group_id;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_group_adduser, null, data, null);return result;}/*** group_deleteuser* @param group_id 用户组id(由数字、字母、下划线组成),长度限制128B,多个用户组id,用逗号分隔* @param uid 用户id(由数字、字母、下划线组成),长度限制128B* options 可选参数:*/Json::Value group_deleteuser(std::string const & group_id,std::string const & uid,const std::map<std::string, std::string> & options){std::map<std::string, std::string> data;data["group_id"] = group_id;data["uid"] = uid;std::copy(options.begin(), options.end(), std::inserter(data, data.end()));Json::Value result =this->request(_group_deleteuser, null, data, null);return result;}/*** 人脸 - 人脸实名认证V4* 基于姓名和身份证号,调取公安权威数据源人脸图,将当前获取的人脸图片,与此公安数据源人脸图进行对比,得出比对分数,并基于此进行业务判断是否为同一人* @param idCardNumber 身份证件号* @param name 姓名(需要是 utf8 编码)* @param image 图片信息(数据大小应小于10M 分辨率应小于1920*1080),5.2版本SDK请求时已包含在加密数据data中,无需额外传入* options 可选参数:* quality_control 质量控制参数*/Json::Value faceMingJingVerify(const std::string& idCardNumber,const std::string& name,std::string* image,std::map<std::string, std::string> options){std::string access_token = this->getAccessToken();Json::Value data;data["id_card_number"] = idCardNumber;data["name"] = name;if (image != nullptr) {data["image"] = *image;}std::map< std::string,std::string >::iterator it ;for(it = options.begin(); it != options.end(); it++){data[it->first] = it->second;}std::string mid = "?access_token=";std::string url = _face_verify_v4 + mid + access_token;Json::Value result =this->request_com(url, data);return result;}/*** 人脸 - 人脸对比V4* 用于比对多张图片中的人脸相似度并返回两两比对的得分,可用于判断两张脸是否是同一人的可能性大小* @param image 图片信息(数据大小应小于10M 分辨率应小于1920*1080),5.2版本SDK请求时已包含在加密数据data中,无需额外传入* @param imageType 图片类型* @param registerImage 图片信息(总数据大小应小于10M),图片上传方式根据image_type来判断。本图片特指客户服务器上传图片,非加密图片Base64值* @param registerImageType 图片类型* options 可选参数*/Json::Value faceMingJingMatch(std::string * image,std::string * imageType,const std::string& registerImage,const std::string& registerImageType,std::map<std::string, std::string> options){std::string access_token = this->getAccessToken();Json::Value data;if (image != nullptr) {data["image"] = *image;}if (imageType != nullptr) {data["image_type"] = *imageType;}data["register_image"] = registerImage;data["register_image_type"] = registerImageType;std::map< std::string,std::string >::iterator it ;for(it = options.begin(); it != options.end(); it++){data[it->first] = it->second;}std::string mid = "?access_token=";std::string url = _face_match_v4 + mid + access_token;Json::Value result =this->request_com(url, data);return result;}/*** 人脸 - 在线图片活体V4* 基于单张图片,判断图片中的人脸是否为二次翻拍* @param sdkVersion sdk版本* options 可选参数*/Json::Value onlinePictureLiveV4(const std::string& sdkVersion,std::vector<std::string>& imageList,std::map<std::string, std::string> options){std::string access_token = this->getAccessToken();Json::Value data;data["sdk_version"] = sdkVersion;Json::Value imageListJson;for (std::string image : imageList) {imageListJson.append(image);}data["image_list"] = imageListJson;std::map< std::string,std::string >::iterator it ;for(it = options.begin(); it != options.end(); it++){data[it->first] = it->second;}std::string mid = "?access_token=";std::string url = _online_picture_live_v4 + mid + access_token;Json::Value result =this->request_com(url, data);return result;}Json::Value search(std::string const & image,std::string const & imageType,std::string const & group_id,const std::map<std::string, std::string> & options){std::string access_token = this->getAccessToken();Json::Value data;data["image"] = image;data["image_type"] = imageType;data["group_id_list"] = group_id;std::string mid = "?access_token=";std::string url = _face_search + mid + access_token;Json::Value result =this->request_com(url, data);return result;}};
}
#endif
到该部分截止,完整代码为:
#include <iostream>
#include "opencv2/opencv.hpp"
#include "face.h"using namespace std;
using namespace cv;
using namespace aip;int main()
{VideoCapture cap(0); // open the default cameraif(!cap.isOpened()) // check if we succeeded{cout<<"Camera open failed!"<<endl;return -1;}cout<<"Camera open successfully!"<<endl;// 设置APPID/AK/SKstd::string app_id = "你的app id";std::string api_key = "你的api key";std::string secret_key = "你的secret key";aip::Face client(app_id, api_key, secret_key);Mat img;Mat grayImg;Mat equalizeImg;vector<Rect> faces;Mat faceImg;vector<uchar> jpgBuf;std::string base64Img;Json::Value result;CascadeClassifier classifier("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml");for(;;){cap >> img; // get a new img from cameracvtColor(img, grayImg, CV_BGR2GRAY); //灰度处理equalizeHist(grayImg,equalizeImg); //均衡化处理classifier.detectMultiScale(equalizeImg, faces); //检测人脸并返回在facas中if(faces.size()){rectangle(equalizeImg, faces[0], Scalar(255,255,255)); //绘制矩形框faceImg = equalizeImg(faces[0]); imencode(".jpg", faceImg, jpgBuf); //将图片编码为jpg格式后存到jpgBuf中base64Img = base64_encode((char *)jpgBuf.data(), jpgBuf.size()); //格式转换为base64
result = client.search(base64Img, "BASE64", "Student", aip::null); //这里的"Student"是你之前新建的人脸分组的名称}elsecout<<"No face detected!"<<endl;imshow("video", equalizeImg); //在video窗口中展示图片 waitKey(40); //设置帧率(40ms读取一帧)}return 0;
}
基于OpenCV的人脸识别考勤系统(三)相关推荐
- 基于OpenCV的人脸识别考勤系统
考勤系统设计 学生上课考勤系统最初的方式是采用的人工纸质点名,目前仍旧有一部分学校依旧采用此种方法点名,这种方法也一直是被认为最有效的签到点名方式.但由于课程繁多加上学生人数众多, 代替点名现象普遍存 ...
- 基于OpenCV的人脸识别考勤系统(一)
本文旨在叙述我基于OpenCV和百度智能云的人脸识别考勤项目, 根据此系列, 应该可以复现出完整的项目. 该项目是在Ubuntu 16.04系统下使用OpenCV技术进行开发的,如果想要成功复现,最好 ...
- 基于OpenCV的人脸识别考勤系统(二)
该部分承接(一),将会实现视频图像的处理以及人脸的识别 目录 四.图像处理 1. cvtColor 2. equalizeHist 五.脸部识别 1. 导入训练文件 2. 绘制人脸框 3. 截取人脸并 ...
- 基于Python的人脸识别考勤系统
基于Python的人脸识别考勤系统 Python源文件: 基于Python3.7编程环境开发 需要安装 tkinter pil face_recognition OpenCV2 库来实现人脸识别 需要 ...
- 基于OpenCV的人脸识别签到系统
1. 摘要 随着人工智能技术的发展,人脸识别技术应用到了生活的很多方面,本文利用人脸识别技术实现了人脸识别签到功能.具体采用 Python 语言以及 dlib 库.face_recognition 库 ...
- 基于OpenCV的人脸识别系统的pyhon源代码
本论文主要阐述了基于OpenCV的人脸识别原型系统.基于生物特征识别的身份认证方法有指纹.掌纹.眼睛虹膜.人脸等,其中,由于人脸的稳定性和可见性,人脸识别的研究与应用成为热点,本文针对出租公寓安全管理 ...
- 【毕业设计_课程设计】基于opencv、dilb的员工人脸识别考勤系统
文章目录 0 项目说明 1 需求分析 2 总体设计 3 详细设计 4 效果展示 5 实验心得 6 项目源码 7 最后 0 项目说明 基于opencv.dilb的员工人脸识别考勤系统 提示:适合用于课程 ...
- python人脸识别考勤系统 dlib+OpenCV和Pyqt5、数据库sqlite 人脸识别系统 计算机 毕业设计 源码
一.项目介绍 Python语言.dlib.OpenCV.Pyqt5界面设计.sqlite3数据库 本系统使用dlib作为人脸识别工具,dlib提供一个方法可将人脸图片数据映射到128维度的空间向量,如 ...
- OpenCV+ Qt Designer 开发人脸识别考勤系统
文章目录 1. 系统介绍 2. 系统架构 3. 开发步骤 3.1 安装必要的库 3.2 设计用户界面 3.3 编写代码 3.3.1 导入库 3.3.2 连接数据库 3.3.3 定义主窗口类 3.3.4 ...
最新文章
- Mac拷贝/复制文件夹路径快捷键
- 慕课网_《Java微信公众号开发进阶》学习总结
- Transact_SQL小手册
- 聊城大学计算机学院韩玉艳,人工蜂群优化及其在资源管理中的应用.doc
- 1.1.1 数据结构的基本概念
- 《Linux内核设计与实现》读书笔记(六)- 内核数据结构
- php文件上传实验总结,53 PHP文件处理(六)文件上传--总结---细说php
- TD-SCDMA智能天线波束赋形能力的讨论
- Apsara Stack 技术百科 | 浅谈阿里云混合云新一代运维平台演进与实践
- ajax 入参为list_ajax向后台传递list参数
- S3C DMA使用方法,2410-2440 dma介绍
- 用c 语言写出五子棋的代码,C语言案例:控制台版本的五子棋游戏【代码】
- 通用安防摄像机通过RTSP转RTMP推流进行H5(RTMP/HLS)直播的方案
- java nio wakeup_Java NIO wakeup实现原理
- 【网络游戏同步技术】游戏中的ping值计算
- 个人发展(职业规划)
- macOS系统低版本升级问题处理纪录
- nkd 编译ffmpeg错误: clang is unable to create an executable file. C compiler test failed.
- bootstrapt 表格自适应_BootStrap table表格插件自适应固定表头(超好用)
- mysql 垃圾_垃圾mysql pipelin
热门文章
- [雪峰磁针石博客]python3标准库-中文版2:内置函数
- uos应用_UOS指标的应用详解
- oracle12c安装卡住_记一次oracle12c安装过程问题及处理方法
- SpringBoot项目实现多数据源的三种方式
- Android 使用经典蓝牙
- ESP32 测试(五): Light-sleep 模式下的电流功耗测试及特性(使用 Wi-Fi)
- ffmpeg学习 pcm文件转wav文件
- Luogu P3488 [POI2009]LYZ-Ice Skates
- 京东云,走进产业数字化深处
- 第十九篇 -- 学习第十八天打卡20190708