人脸识别业务(基于腾讯人脸识别接口)

使用腾讯云人脸识别接口,基于优图祖母模型。

一、准备工作

人脸识别账号

申请腾讯云服务器账号,生成自己的秘钥。记录秘钥和秘钥ID。

创建人员库

记下人员库id

在配置文件application.yml中添加配置。

plateocr:SecretId: 秘钥IDSecretKey: 秘钥serverIp: iai.tencentcloudapi.comarea: ap-guangzhou #人脸识别服务器所在区域,官方推荐就近groupId: 1 #刚才创建的人脸库IDused: true  #表示人脸识别是否开启passPercent: 80 #通过率,相似率到达多少算通过nonceStr: 123456 #随机数

二、录入人脸的类

需要用到的类:

1.Base64Util :自己写的base64工具类,用于将base64解码写到本地磁盘。

package com.qcby.mycommunity_003.util;import org.apache.commons.codec.binary.Base64;import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;public class Base64Util {/*** 将二进制数据编码为BASE64字符串** @param binaryData* @return*/public static String encode(byte[] binaryData) {try {return new String(Base64.encodeBase64(binaryData), "UTF-8");} catch (UnsupportedEncodingException e) {return null;}}/*** 将BASE64字符串恢复为二进制数据** @param base64String* @return*/public static byte[] decode(String base64String) {try {return Base64.decodeBase64(base64String.getBytes("UTF-8"));} catch (UnsupportedEncodingException e) {return null;}}/*** 将文件转成base64 字符串**  path文件路径* @return ** @throws Exception*/public static String encodeBase64File(String path) throws Exception {File file = new File(path);FileInputStream inputFile = new FileInputStream(file);byte[] buffer = new byte[(int) file.length()];inputFile.read(buffer);inputFile.close();return encode(buffer);}//读取网络图片public static String encodeBase64URLFile(String path) throws Exception {URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection)url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5*1000);InputStream is = conn.getInputStream();byte[] data = readInputStream(is);is.close();conn.disconnect();return encode(data);}public static byte[] readInputStream(InputStream inStream) throws Exception{ByteArrayOutputStream outStream = new ByteArrayOutputStream();//创建一个Buffer字符串byte[] buffer = new byte[1024];//每次读取的字符串长度,如果为-1,代表全部读取完毕int len = 0;//使用一个输入流从buffer里把数据读取出来while( (len=inStream.read(buffer)) != -1 ){//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度outStream.write(buffer, 0, len);}//关闭输入流inStream.close();//把outStream里的数据写入内存return outStream.toByteArray();}/*** 将base64字符解码保存文件** @param base64Code* @param targetPath* @throws Exception*/public static void decoderBase64File(String base64Code, String targetPath) throws Exception {byte[] buffer = decode(base64Code);FileOutputStream out = new FileOutputStream(targetPath);out.write(buffer);out.close();}/*** 将base64字符保存文本文件** @param base64Code* @param targetPath* @throws Exception*/public static void toFile(String base64Code, String targetPath) throws Exception {byte[] buffer = base64Code.getBytes();FileOutputStream out = new FileOutputStream(targetPath);out.write(buffer);out.close();}
}

2.RootResp 类,封装腾讯人脸识别返回的信息。 


import com.alibaba.fastjson.JSON;public class RootResp {//腾讯api返回的状态码,如果是0代表添加成功,否则会有异常码private int ret = 0;public int getRet() {return this.ret;}public void setRet(int ret) {this.ret = ret;}private String msg;public String getMsg() {return this.msg;}public void setMsg(String msg) {this.msg = msg;}private Object data;public Object getData() {return this.data;}public void setData(Object data) {this.data = data;}@Overridepublic String toString() {return JSON.toJSONString(this);}
}

 3.FaceApi :调用api接口

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qcby.mycommunity_003.configuration.ApiConfiguration;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.iai.v20180301.IaiClient;
import com.tencentcloudapi.iai.v20180301.models.*;
import org.apache.log4j.Logger;public class FaceApi {private Logger logger = Logger.getLogger(FaceApi.class);//人脸分析public RootResp detectFace(ApiConfiguration config, String url) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("Url", url);paramObj.put("MaxFaceNum",1);paramObj.put("MinFaceSize",34);paramObj.put("NeedFaceAttributes",0);paramObj.put("NeedQualityDetection",1);DetectFaceRequest req = DetectFaceRequest.fromJsonString(paramObj.toJSONString(),DetectFaceRequest.class);DetectFaceResponse resp = client.DetectFace(req);result.setData(DetectFaceResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//添加个体public RootResp newperson(ApiConfiguration config, String personId, String personName, String image) {RootResp result = new RootResp();try{//访问腾讯云服务所需要的秘钥信息,进行身份验证和授权凭证Credential cred = new Credential(config.getSecretId(), config.getSecretKey());//设置与腾讯云服务通信的http配置HttpProfile httpProfile = new HttpProfile();//配置接口请求域名httpProfile.setEndpoint(config.getServerIp());//配置客户端相关参数,包括http配置ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);//和腾讯云人脸服务进行通信IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("GroupId", config.getGroupId());paramObj.put("PersonId", config.getPersonIdPre() + personId);paramObj.put("PersonName", personName);paramObj.put("Image", image);//调取创建person的请求CreatePersonRequest req = CreatePersonRequest.fromJsonString(paramObj.toJSONString(), CreatePersonRequest.class);//响应回来的数据转成jsonCreatePersonResponse resp = client.CreatePerson(req);result.setData(CreatePersonResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//删除个体public RootResp delperson(ApiConfiguration config, String personId) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("PersonId", config.getPersonIdPre() + personId);DeletePersonRequest req = DeletePersonRequest.fromJsonString(paramObj.toJSONString(), DeletePersonRequest.class);DeletePersonResponse resp = client.DeletePerson(req);result.setData(DeletePersonResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//增加人脸public RootResp addface(ApiConfiguration config, String personId, String image) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();JSONArray images = new JSONArray();images.add(image);paramObj.put("PersonId", config.getPersonIdPre() + personId);paramObj.put("Images", images);CreateFaceRequest req = CreateFaceRequest.fromJsonString(paramObj.toJSONString(), CreateFaceRequest.class);CreateFaceResponse resp = client.CreateFace(req);result.setData(CreateFaceResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//删除人脸public RootResp delface(ApiConfiguration config, String personId, String faceId) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();JSONArray faces = new JSONArray();faces.add(faceId);paramObj.put("PersonId", config.getPersonIdPre() + personId);paramObj.put("FaceIds", faces);DeleteFaceRequest req = DeleteFaceRequest.fromJsonString(paramObj.toJSONString(), DeleteFaceRequest.class);DeleteFaceResponse resp = client.DeleteFace(req);result.setData(DeleteFaceResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//人脸验证public RootResp faceVerify(ApiConfiguration config, String personId, String image) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("PersonId", config.getPersonIdPre() + personId);paramObj.put("Image", image);VerifyFaceRequest req = VerifyFaceRequest.fromJsonString(paramObj.toJSONString(), VerifyFaceRequest.class);VerifyFaceResponse resp = client.VerifyFace(req);result.setData(VerifyFaceResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}//人员搜索按库返回public RootResp searchPersonsReturnsByGroup(ApiConfiguration config, String image) {RootResp result = new RootResp();try{Credential cred = new Credential(config.getSecretId(), config.getSecretKey());HttpProfile httpProfile = new HttpProfile();httpProfile.setEndpoint(config.getServerIp());ClientProfile clientProfile = new ClientProfile();clientProfile.setHttpProfile(httpProfile);IaiClient client = new IaiClient(cred, config.getArea(), clientProfile);JSONObject paramObj = new JSONObject();paramObj.put("GroupIds", new String[] {config.getGroupId()});paramObj.put("Image", image);//最多返回的最相似人员数目paramObj.put("MaxPersonNumPerGroup", 5);//返回人员具体信息paramObj.put("NeedPersonInfo", 1);//最多识别的人脸数目paramObj.put("MaxFaceNum", 1);SearchFacesReturnsByGroupRequest req = SearchFacesReturnsByGroupRequest.fromJsonString(paramObj.toJSONString(), SearchFacesReturnsByGroupRequest.class);SearchFacesReturnsByGroupResponse resp = client.SearchFacesReturnsByGroup(req);result.setData(VerifyFaceResponse.toJsonString(resp));} catch (TencentCloudSDKException e) {result.setRet(-1);result.setMsg(e.toString());logger.error(e.toString());}logger.info(result);return result;}
}

4.ApiConfiguration :封装配置信息(调用腾讯接口需要的部分参数) 

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@ConfigurationProperties(value="plateocr")
@Component
@Data
@ApiModel(value = "ApiConfiguration",description = "人脸识别参数描述")
public class ApiConfiguration {@ApiModelProperty("人脸识别secretId")private String secretId;@ApiModelProperty("人脸识别secretKey")private String secretKey;//	服务器ip@ApiModelProperty("人脸识别服务器ip")private String serverIp;//	服务器区域@ApiModelProperty("人脸识别服务器区域")private String area;//	默认分组@ApiModelProperty("人脸识别默认分组")private String groupId;//	用户id前缀,这个属性在配置文件里面没有@ApiModelProperty("人脸识别用户id前缀")private String personIdPre;//	随机数@ApiModelProperty("人脸识别随机数")private String nonceStr;//	是否使用@ApiModelProperty("人脸识别,是否启用人脸识别功能")private boolean used = false;//	识别准确率@ApiModelProperty("人脸识别比对准确度,如符合80%就识别通过")private float passPercent;}

 5.表现层代码

@PostMapping("/addPerson")public Result addFace(@RequestBody AddFaceVo personFaceForm){//1============严谨性判断Person person = personService.getById(personFaceForm.getPersonId());if(person==null){return Result.error("居民不存在");}if(personFaceForm.getFileBase64()==null||personFaceForm.getFileBase64().equals("")){return Result.error("请上传base64编码的文件");}//1.腾讯接口使用的是腾讯优图祖母模型,if(apiConfiguration.isUsed()){//**************方法一:调用腾讯api识别。String faceId = newPerson(personFaceForm, person.getUserName());String faceBase = personFaceForm.getFileBase64().substring(0, 60);
//            ************方法二:自己模拟判断是不是人脸图片************:
//            String faceId = RandomUtil.getBitRandom();//如果不是头像(这一行如果不注释就报错)
//            if(faceBase.equals("iVBORw0KGgoAAAANSUhEUgAAAoAAAAHgCAYAAAA10dzkAAAAAXNSR0IArs4c")) {
//                return Result.error("人脸识别失败");
//            }//2.存到本地的文件夹内
//            //存储头像String filename = faceId + "." + personFaceForm.getExtName();
//            String savePath = face + filename;
//            try {
//                Base64Util.decoderBase64File(personFaceForm.getFileBase64(), savePath);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }//**********************这是方法一结束*****************://生成头像访问路径String faceUrl = urlPrefix + "community/upload/face/" + filename;person.setFaceUrl(faceUrl);person.setState(2);person.setFaceBase(faceBase);//3.存到数据库中(包括base64编码存储)//更新人脸识别状态及图片地址this.personService.updateById(person);return Result.ok();}return Result.error("未开启人脸识别");}/*** 腾讯api接口相关* @param vo* @param personName* @return*/private String newPerson(AddFaceVo vo,String personName) {String faceId = null;String faceBase64 = vo.getFileBase64();String extname = vo.getExtName();String personId = vo.getPersonId()+"";String savePath = face;if (faceBase64!=null && !faceBase64.equals("")) {FaceApi faceApi = new FaceApi();RootResp resp = faceApi.newperson(apiConfiguration, personId, personName, faceBase64);if(resp.getRet()==0) {JSONObject data = JSON.parseObject(resp.getData().toString());faceId = data.getString("FaceId");if(faceId!=null) {String filename = faceId + "." + extname;savePath += filename;try {//调用自定义工具类,将base64编码文件解码,并报存在指定路径Base64Util.decoderBase64File(faceBase64, savePath);} catch (Exception e) {e.printStackTrace();}}}else {return faceId;}}return faceId;}

6.接收前端传递参数的类

import lombok.Data;@Data
public class AddFaceVo {private Integer personId;private String extName;private String fileBase64;
}

三、录入人脸的流程 

1.调用腾讯api

调用api需要的参数有: 

配置文件中配置的秘钥、秘钥id、服务器ip、区域、人脸库id、是否开启、精确度、随机数

人员id、人员姓名、图片的base64码

 

2.如果腾讯接口返回的状态码是0,就说明保存成功,将图片存到本地。

3.更新数据库,存base64编码。

四、人脸识别 

1.表现层代码

  //1判断是不是在人员库存在)
//        (1)调用腾讯AI接口(FaceApi faceApi = new FaceApi();RootResp resp = faceApi.searchPersonsReturnsByGroup(apiConfiguration, inOutFaceForm.getFileBase64());String msg = "";
//        封装人员信息的json对象JSONObject personInfo = null;
//        (2)根据状态码,如果是0就是在人员库if(resp.getRet() == 0) {JSONObject object = JSONObject.parseObject(resp.getData().toString());JSONArray resultsReturnsByGroup = object.getJSONArray("ResultsReturnsByGroup");JSONObject returnsByGroupJSONObject = resultsReturnsByGroup.getJSONObject(0);JSONArray groupCandidates = returnsByGroupJSONObject.getJSONArray("GroupCandidates");JSONObject groupCandidatesJSONObject = groupCandidates.getJSONObject(0);JSONArray candidates = groupCandidatesJSONObject.getJSONArray("Candidates");
//            (3)拿到全部人员库对象,匹配数据库人员信息String personId ="";String faceId = "";String personName = "";String faceUrl = "";long pid = 0;Person p = null, p1 = null;for(int i = 0;i < candidates.size();i++) {personInfo= candidates.getJSONObject(i);personId = personInfo.getString("PersonId");faceId = personInfo.getString("FaceId");personName = personInfo.getString("PersonName");personId = personId.substring(4);pid = Integer.parseInt(personId);p = personService.getById(pid);if(p == null)continue;elsep1 = p;faceUrl = p.getFaceUrl();if(faceUrl == null || faceUrl.equals("")){continue;}faceUrl = faceUrl.substring(faceUrl.lastIndexOf("/")+1,faceUrl.lastIndexOf("."));if(faceId.equals(faceUrl)) {break;}}
//          (4)if(p==null) {return Result.ok().put("data","人员信息不存在");}if(inOutFaceForm.getCommunityId() != p.getCommunityId()) {return Result.ok().put("data","对不起,你不是本小区居民,请与系统管理员联系。");}
//        (5)创建出入记录对象,封装InOutRecord inoutrecord = new InOutRecord();inoutrecord.setCommunityId(p.getCommunityId());inoutrecord.setPersonId(p.getPersonId());try {//保存图片String newFileName = UUID.randomUUID()+"." + inOutFaceForm.getExtName();String fileName = face + newFileName;Base64Util.decoderBase64File(inOutFaceForm.getFileBase64(),fileName);String basePath = urlPrefix + "community/upload/face/" + newFileName;//查找系统中是否有该人员的出入场信息InOutRecord inoutrecord1 = this.inOutRecordMapper.getInOutRecord(inoutrecord);
//        (6)根据出去等于null来查,如果查不到就新建一个对象,查到了就是出去小区//进入小区if(inoutrecord1 == null) {inoutrecord.setInPic(basePath);this.inOutRecordMapper.insert(inoutrecord);return Result.ok().put("status", "success").put("data", "【"+p.getUserName() + "】进入小区");//离开小区} else {inoutrecord1.setOutPic(basePath);inoutrecord1.setOutTime(new Date());this.inOutRecordMapper.updateById(inoutrecord1);return Result.ok().put("status", "success").put("data", "【"+p.getUserName() + "】离开小区");}} catch (Exception e) {e.printStackTrace();}}else{msg = "人脸识别失败,错误码=" + resp.getRet() + "," + resp.getMsg();}return Result.ok().put("data",msg);

五、人脸识别流程

1.调用腾讯接口进行比对

2.根据状态码,判断是不是存在相似度通过的人脸。如果存在就和根据查找到的人员id来查找数据库中对应的id的人员的姓名。如果姓名也和人员库返回的一致就通过。

3.如需做进出登记,就在进出登记数据表中存入信息。

如果本id下是有“出”是null的就表示改人员是出小区,否则就新建一条记录,表示进小区。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/805375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Day1 省选衔接题 思路总结

Day1 省选题 思路 取数 可反悔的贪心。我们开一个双向链表记录此时每个数的前/后一个数是什么。一个简单但不一定正确的贪心策略即为&#xff1a;每次都取走当前值最大的且可取的数&#xff0c;并更新列表。考虑如何使这个贪心思路正确。 设 p r e x pre_x prex​ 表示 x x …

Path Aggregation Network for Instance Segmentation

PANet 摘要1. 引言2.相关工作3.框架 PANet 最初是为 proposal-based 实例分割框架提出来的&#xff0c;mask 是实例的掩码&#xff0c;覆盖了物体包含的所有像素&#xff0c;proposal 在目标检测领域是可能存在目标的区域。在实例分割中&#xff0c;首先利用RPN(Region Proposa…

练习题(2024/4/10)

1. 删除有序数组中的重复项 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元…

2022年蓝桥杯省赛——直线

目录 题目链接&#xff1a;11.直线 - 蓝桥云课 (lanqiao.cn) 题目描述 思路 代码思路如下 代码实现 坑来喽~~ 导致这个BUG的原因&#xff01;&#xff01;&#xff01; 总结 整体的 两种b的情况对比数据 题目链接&#xff1a;11.直线 - 蓝桥云课 (lanqiao.cn) 题目描…

JVM面试整理--对象的创建和堆

文章目录 对象的创建过程是怎样的?对象在内存中的结构是怎样的&#xff08;专业的叫法&#xff1a;对象的内存布局&#xff09;对象在内存分配时使用的哪种方式&#xff08;有的地方也称为&#xff1a;分配算法&#xff09;知道什么是“指针碰撞”吗&#xff1f;知道什么是“空…

LeetCode 80—— 删除有序数组中的重复项 II

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 让 index指向删除重复元素后数组的新长度&#xff1b;让 st_idx 指向重复元素的起始位置&#xff0c;而 i 指向重复元素的结束位置&#xff0c;duplicate_num代表重复元素的个数&#xff1b;一段重复元素结束后&am…

php校园活动报名系统vue+mysql

开发语言&#xff1a;php 后端框架&#xff1a;Thinkphp/Laravel 前端框架&#xff1a;vue.js 服务器&#xff1a;apache 数据库&#xff1a;mysql 运行环境:phpstudy/wamp/xammp等本选题则旨在通过标签分类管理等方式&#xff0c;管理员&#xff1b;首页、个人中心、学生管理、…

Redis 缓存穿透、缓存击穿、缓存雪崩区别和解决方案

缓存穿透 什么是缓存穿透&#xff1f; 缓存穿透说简单点就是大量请求的 key 是不合理的&#xff0c;根本不存在于缓存中&#xff0c;也不存在于数据库中 。这就导致这些请求直接到了数据库上&#xff0c;根本没有经过缓存这一层&#xff0c;对数据库造成了巨大的压力&#xf…

2、Qt UI控件 -- qucsdk项目使用

前言&#xff1a;上一篇文章讲了qucsdk的环境部署&#xff0c;可以在QDesigner和Qt Creator中看到qucsdk控件&#xff0c;这一篇来讲下在项目中使用qucsdk库中的控件。 一、准备材料 要想使用第三方库&#xff0c;需要三个先决条件&#xff0c; 1、控件的头文件 2、动/静态链…

记录vue之npm run serve报错SET NODE_OPTIONS

> vue-antd-pro3.0.0 serve > SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-service servesh: SET: command not found 一定要注意&#xff1a;将 SET NODE_OPTIONS–openssl-legacy-provider && 删除即可

17 - Games101 - 笔记 - 材质与外观

**17 **材质与外观 材质与BRDF 自然界中的材质&#xff1a;丝绸、头发、蝴蝶翅膀表面、寿司表面等等 图形学中的材质&#xff1a;同一个模型之所以渲染出不同结果的原因就是因为材质。在图形学中是给不同的物体指定不同的材质&#xff0c;知道它们如何和光线作用后就能正确的…

C++11 数据结构0 什么是 “数据结构“?数据,数据对象,数据元素,数据项 概念。算法的基本概念 和 算法的度量,大O表示法,空间换时间的代码

数据&#xff1a; 是能输入计算机且能被计算机处理的各种符号的集合。数值型的数据&#xff1a;整数和实数。非数值型的数据&#xff1a;文字、图像、图形、声音等。 数据对象&#xff1a; 性质相同的 "数据元素" 的集合 例如一个 int arr[10], Teacher tea[3]; 数…

汽车4S行业的信息化特点与BI建设挑战

汽车行业也是一个非常大的行业&#xff0c;上下游非常广&#xff0c;像主机厂&#xff0c;上游的零配件&#xff0c;下游的汽车流通&#xff0c;汽车流通之后的汽车后市场&#xff0c;整个链条比较长。今天主要讲的是汽车流通&#xff0c;汽车4S集团。一个汽车4S集团下面授权代…

MySQL高级篇(存储引擎InnoDB、MyISAM、Memory)

目录 1、存储引擎简介 1.1、查询建表语句&#xff0c;默认存储引擎&#xff1a;InnoDB 1.2、查看当前数据库支持的存储引擎 1.3、创建表&#xff0c;并指定存储引擎 2、 存储引擎-InnoDB介绍 2.1、存储引擎特点 3、MyISAM存储引擎 4、Memory存储引擎 5、InnoDB、MyISAM、Memory…

HTML基础(3)

1、内联框架 iframe用于在网页内显示网页&#xff0c;语法如下&#xff1a; <iframe src"URL"></iframe> URL指向隔离页面 hight&#xff0c;weight设置高宽&#xff0c;删除边框将frameborder设置为0 <td> <iframe frameborder"0&qu…

麒麟v10安装mysql-8.0.35

因为要修复漏洞的原因&#xff0c;这两天将麒麟v10操作系统的服务器上的MySQL版本由5.7.27升级到8.0.35&#xff08;mysql安装包下载地址&#xff1a;MySQL :: Download MySQL Community Server (Archived Versions)&#xff09;&#xff0c;mysql的安装过程主要参考了这个博主…

JavaScript-throw、try,2024年前端高级面试题总结

提交电话 二、xml初识 xml文件是用来做什么的 核心思想&#xff1a; 答&#xff1a;存储数据 延伸问题&#xff1a; xml是怎样存储数据的&#xff1f; 答&#xff1a;以标签的形式存储 例: coco 什么是xml元素? 元素该如何编写? xml中的元素其实就是一个个的标签 标签…

面试官为什么喜欢考察Vue底层原理

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

国产低代码工具,轻松搞定数据迁移

在日常的业务系统升级或者数据维护过程中&#xff0c;数据迁移是各个企业用户不得不面临的问题&#xff0c;尤其是数据迁移过程中要保障数据完整性、统一性和及时性&#xff0c;同时也需要注意源数据中的数据质量问题&#xff0c;比如缺失、无效、错误等问题&#xff0c;需要在…

前端面试算法题1

1.已知&#xff1a; • 布局分为&#xff1a;父元素A和N个子元素B&#xff1b; • A宽度不固定&#xff1a;最小宽度为1000px&#xff0c;内部边距是32px • B的宽度不固定&#xff1a;相邻两个B元素的间距是16px&#xff0c;所有B的宽度相同&#xff0c;边框为1像素&#x…