• 华为云API人脸识别服务FRS的感知力—偷偷藏不住的你


    云服务、API、SDK,调试,查看,我都行

    阅读短文您可以学习到:人工智能AI人脸的识别、检测、搜索、比对

    1、IntelliJ IDEA 之API插件介绍

    API插件支持 VS Code IDE、IntelliJ IDEA等平台、以及华为云自研 CodeArts IDE,基于华为云服务提供的能力,帮助开发者更高效、便捷的搭建应用。API插件关联华为云服务下的 API Explorer、DevStar、CodeLabs、SDK 中心和 CLI 中心产品,致力于为开发者提供更稳定、快速、安全的编程体验。

    在本插件中,我们提供了但不局限于如下的功能:

    对接华为云API开放平台,支持用户检索API、查看API文档、调试API、以及提供SDK示例代码供用户学习如何使用API。

    提供华为云SDK代码片段补全功能,SDK依赖包自动引入,加速用户集成华为云API。

    对接华为云开发体验馆Codelabs,提供500+云服务代码示例,向导式教程帮助用户快速学习。

    说明:

    在IntelliJ IDEA等系列平台和VS Code IDE,华为云API插件的名称是Huawei Cloud API。而在CodeArts IDE,API插件是IDE原生内置的,名称是华为云API开发套件。

    API插件在IntelliJ IDEA等系列平台和VS Code IDE的使用依赖底座插件,请提前安装底座插件。

    2、API插件安装--IntelliJ IDEA

    2.1 IntelliJ IDEA等平台

    安装准备:下载并安装JDK1.8或更高版本。下载并安装IntelliJ IDEA 2020.2或更高版本。

    须知:IntellIj平台同时支撑包括Goland、Pycharm等在内的IDE,若在其它相关IDE上开发,请下载配置好对应语言的编译器或者解释器。这里以IDEA为例介绍IntelliJ平台插件的安装流程,其他IntelliJ系列的IDE请参考IDEA。

    开始安装:

    您可以在直接在IDE插件市场或者直接在JetBrains插件市场下载离线包安装。

    https://developer.huaweicloud.com/develop/toolkit.html

    IDE安装

    1. 在IntelliJ IDEA顶部菜单栏中选择File > Settings,在Settings对话框的左侧导航栏中单击Plugins。
    2. Plugins区域单击Marketplace,在搜索栏中输入Huawei Cloud API。
    3. Search Results区域会出现Huawei Cloud API,单击Install,完成后重启IDE。

    离线包安装:

    1. 进入插件市场搜索Huawei Cloud API,进入插件详情页,在Versions页签下选择想要版本的API插件,点击Download下载离线的插件压缩包保存到本地。。
    2. 在IntelliJ IDEA顶部菜单栏中选择File > Settings,在Settings对话框的左侧导航栏中单击Plugins。
    3. 在Plugins区域单击 ,再单击Install Plugin from Disk...。
    4. 在Choose Plugin File对话框中选择离线安装包(不用解压),并按照IntelliJ IDEA安装页面的提示,完成后续安装步骤。

    说明:若当前您想要安装插件的IntelliJ IDE已经在桌面打开,则进入插件市场搜索Huawei Cloud API,进入插件详情页,在右上角会识别到本地已经打开的IDE,点击相应按钮,在弹出的IDE窗口中点击ok,则IDE后台会开始安装相应版本的API插件。

    安装验证:在IntelliJ系列平台上安装插件成功后在左侧的导航栏中可以看到Huawei Cloud Toolkit图标,点击后面板会出现Huawei Cloud API的字样,则说明安装成功。

    2.2 华为云API

    Toolkit-华为云

    左侧展示API列表,可以查询所有API,目前云服务206,APIs9213

    3、抓住偷偷藏不住的你

    3.1 前期准备

    华为云提供了人脸识别服务端SDK,您可以直接集成服务端SDK来调用人脸识别服务的相关API,从而实现对人脸识别服务的快速操作。

    该示例展示了如何通过Java版SDK实现人脸识别。

    开发前准备:

    • 已注册华为云,并完成实名认证 。
    • 已订阅人脸识别服务。
    • 已具备开发环境,支持Java JDK 1.8及其以上版本。
    • 已获取华为云账号对应的Access Key(AK)和Secret Access Key(SK)。请在华为云控制台“我的凭证 > 访问密钥”页面上创建和查看您的AK/SK。具体请参见 访问密钥 。
    • 已获取直播服务对应区域的项目ID,请在华为云控制台“我的凭证 > API凭证”页面上查看项目ID。具体请参见 API凭证。

    安装SDK:

    您可以通过Maven配置所依赖的人脸识别服务SDK

    1. <dependency>
    2. <groupId>com.huaweicloud.sdk</groupId>
    3. <artifactId>huaweicloud-sdk-frs</artifactId>
    4. <version>3.1.19</version>
    5. </dependency>

    开始使用:

    导入依赖模块

    1. import com.huaweicloud.sdk.core.auth.ICredential;
    2. import com.huaweicloud.sdk.core.auth.BasicCredentials;
    3. import com.huaweicloud.sdk.core.exception.ConnectionException;
    4. import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
    5. import com.huaweicloud.sdk.core.exception.ServiceResponseException;

    //v2版本sdk

    1. import com.huaweicloud.sdk.frs.v2.region.FrsRegion;
    2. import com.huaweicloud.sdk.frs.v2.*;
    3. import com.huaweicloud.sdk.frs.v2.model.*;

    初始化认证信息

    1. public static ICredential getCredential(String ak, String sk) {
    2. return new BasicCredentials()
    3. .withAk(ak)
    4. .withSk(sk);
    5. }

    相关参数说明如下所示:

    ak:华为云账号Access Key。

    sk:华为云账号Secret Access Key 。

    初始化人脸识别服务的客户端

    1. public static FrsClient getClient(Region region, ICredential auth) {
    2. // 初始化人脸识别服务的客户端
    3. return FrsClient.newBuilder()
    4. .withCredential(auth)
    5. .withRegion(region) // 选择服务所在区域 FrsRegion.CN_NORTH_4
    6. .build();
    7. }

    相关参数说明如下所示:

    service region: 服务所在区域,例如:

    CN_NORTH_1 北京一

    CN_NORTH_4 北京四

    SDK demo代码解析

    3.2 人脸识别/检测

    1. DetectFaceByBase64Request detectRequest = new DetectFaceByBase64Request();
    2. FaceDetectBase64Req faceDetectBase64Req = new FaceDetectBase64Req();
    3. faceDetectBase64Req.withImageBase64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    4. faceDetectBase64Req.withAttributes("2");
    5. detectRequest.setBody(faceDetectBase64Req);
    6. try {
    7. DetectFaceByBase64Response detectResponse = client.detectFaceByBase64(detectRequest);
    8. System.out.println(detectResponse.toString());
    9. } catch (ConnectionException e) {
    10. e.printStackTrace();
    11. } catch (RequestTimeoutException e) {
    12. e.printStackTrace();
    13. } catch (ServiceResponseException e) {
    14. e.printStackTrace();
    15. System.out.println(e.getHttpStatusCode());
    16. System.out.println(e.getErrorCode());
    17. System.out.println(e.getErrorMsg());
    18. }
    19. 3.2.1 人脸比对
    20. CompareFaceByBase64Request compareRequest = new CompareFaceByBase64Request();
    21. FaceCompareBase64Req faceCompareBase64Req = new FaceCompareBase64Req();
    22. faceCompareBase64Req.withImage1Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    23. faceCompareBase64Req.withImage2Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    24. compareRequest.withBody(faceCompareBase64Req);
    25. try {
    26. CompareFaceByBase64Response compareResponse = client.compareFaceByBase64(compareRequest);
    27. System.out.println(compareResponse.toString());
    28. } catch (ConnectionException e) {
    29. e.printStackTrace();
    30. } catch (RequestTimeoutException e) {
    31. e.printStackTrace();
    32. } catch (ServiceResponseException e) {
    33. e.printStackTrace();
    34. System.out.println(e.getHttpStatusCode());
    35. System.out.println(e.getErrorCode());
    36. System.out.println(e.getErrorMsg());
    37. }

    3.2.2 人脸搜索

    1. SearchFaceByBase64Request searchRequest = new SearchFaceByBase64Request();
    2. searchRequest.withFaceSetName("face_set_name");
    3. FaceSearchBase64Req faceSearchBase64Req = new FaceSearchBase64Req();
    4. List<Map<String, String>> listbodySort = new ArrayList<>();
    5. Map<String, String> map = new HashMap<>();
    6. map.put("timestamp","asc");
    7. listbodySort.add(map);
    8. List<String> listbodyReturnFields = new ArrayList<>();
    9. listbodyReturnFields.add("timestamp");
    10. listbodyReturnFields.add("id");
    11. faceSearchBase64Req.withSort(listbodySort);
    12. faceSearchBase64Req.withReturnFields(listbodyReturnFields);
    13. faceSearchBase64Req.withImageBase64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    14. searchRequest.withBody(faceSearchBase64Req);
    15. try {
    16. SearchFaceByBase64Response searchResponse = client.searchFaceByBase64(searchRequest);
    17. System.out.println(searchResponse.toString());
    18. } catch (ConnectionException e) {
    19. e.printStackTrace();
    20. } catch (RequestTimeoutException e) {
    21. e.printStackTrace();
    22. } catch (ServiceResponseException e) {
    23. e.printStackTrace();
    24. System.out.println(e.getHttpStatusCode());
    25. System.out.println(e.getErrorCode());
    26. System.out.println(e.getErrorMsg());
    27. }

    创建人脸库

    1. CreateFaceSetRequest createFaceSetRequest = new CreateFaceSetRequest();
    2. CreateFaceSetReq createFaceSetReq = new CreateFaceSetReq();
    3. createFaceSetReq.withFaceSetName("face_set_name");
    4. Map stringTypeInfoMap = new HashMap<>();
    5. TypeInfo typeInfo = new TypeInfo();
    6. typeInfo.withType("long");
    7. stringTypeInfoMap.put("timestamp", typeInfo);
    8. createFaceSetReq.withExternalFields(stringTypeInfoMap);
    9. createFaceSetRequest.withBody(createFaceSetReq);
    10. try {
    11. CreateFaceSetResponse createFaceSetResponse = client.createFaceSet(createFaceSetRequest);
    12. System.out.println(createFaceSetResponse.toString());
    13. } catch (ConnectionException e) {
    14. e.printStackTrace();
    15. } catch (RequestTimeoutException e) {
    16. e.printStackTrace();
    17. } catch (ServiceResponseException e) {
    18. e.printStackTrace();
    19. System.out.println(e.getHttpStatusCode());
    20. System.out.println(e.getErrorCode());
    21. System.out.println(e.getErrorMsg());
    22. }

    查询人脸库

    1. ShowFaceSetRequest showFaceSetRequest = new ShowFaceSetRequest();
    2. showFaceSetRequest.withFaceSetName("face_set_name");
    3. try {
    4. ShowFaceSetResponse showFaceSetResponse = client.showFaceSet(showFaceSetRequest);
    5. System.out.println(showFaceSetResponse.toString());
    6. } catch (ConnectionException e) {
    7. e.printStackTrace();
    8. } catch (RequestTimeoutException e) {
    9. e.printStackTrace();
    10. } catch (ServiceResponseException e) {
    11. e.printStackTrace();
    12. System.out.println(e.getHttpStatusCode());
    13. System.out.println(e.getErrorCode());
    14. System.out.println(e.getErrorMsg());
    15. }

    查询所有人脸库

    1. ShowAllFaceSetsRequest showAllFaceSetsRequest = new ShowAllFaceSetsRequest();
    2. try {
    3. ShowAllFaceSetsResponse showAllFaceSetsResponse = client.showAllFaceSets(showAllFaceSetsRequest);
    4. System.out.println(showAllFaceSetsResponse.toString());
    5. } catch (ConnectionException e) {
    6. e.printStackTrace();
    7. } catch (RequestTimeoutException e) {
    8. e.printStackTrace();
    9. } catch (ServiceResponseException e) {
    10. e.printStackTrace();
    11. System.out.println(e.getHttpStatusCode());
    12. System.out.println(e.getErrorCode());
    13. System.out.println(e.getErrorMsg());
    14. }

    删除人脸库

    1. DeleteFaceSetRequest deleteFaceSetRequest = new DeleteFaceSetRequest();
    2. deleteFaceSetRequest.withFaceSetName("face_set_name");
    3. try {
    4. DeleteFaceSetResponse deleteFaceSetResponse = client.deleteFaceSet(deleteFaceSetRequest);
    5. System.out.println(deleteFaceSetResponse.toString());
    6. } catch (ConnectionException e) {
    7. e.printStackTrace();
    8. } catch (RequestTimeoutException e) {
    9. e.printStackTrace();
    10. } catch (ServiceResponseException e) {
    11. e.printStackTrace();
    12. System.out.println(e.getHttpStatusCode());
    13. System.out.println(e.getErrorCode());
    14. System.out.println(e.getErrorMsg());
    15. }

    添加人脸

    1. //add face
    2. AddFacesByBase64Request addFacesByBase64Request = new AddFacesByBase64Request();
    3. addFacesByBase64Request.withFaceSetName("face_set_name");
    4. AddFacesBase64Req addFacesBase64Req = new AddFacesBase64Req();
    5. addFacesBase64Req.withExternalFields("{\"timestamp\":12}");
    6. addFacesBase64Req.withImageBase64("9j/4AAQSkZJRgABAQAAAQABAAD...");
    7. addFacesByBase64Request.withBody(addFacesBase64Req);
    8. try {
    9. AddFacesByBase64Response addFacesByBase64Response = client.addFacesByBase64(addFacesByBase64Request);
    10. System.out.println(addFacesByBase64Response.toString());
    11. } catch (ConnectionException e) {
    12. e.printStackTrace();
    13. } catch (RequestTimeoutException e) {
    14. e.printStackTrace();
    15. } catch (ServiceResponseException e) {
    16. e.printStackTrace();
    17. System.out.println(e.getHttpStatusCode());
    18. System.out.println(e.getErrorCode());
    19. System.out.println(e.getErrorMsg());
    20. }

    删除人脸

    1. //delete face by faceId
    2. DeleteFaceByFaceIdRequest deleteFaceByFaceIdRequest = new DeleteFaceByFaceIdRequest();
    3. deleteFaceByFaceIdRequest.withFaceSetName("face_set_name");
    4. deleteFaceByFaceIdRequest.withFaceId("iexEBb6t");
    5. try {
    6. DeleteFaceByFaceIdResponse deleteFaceByFaceIdResponse = client.deleteFaceByFaceId(deleteFaceByFaceIdRequest);
    7. System.out.println(deleteFaceByFaceIdResponse.toString());
    8. } catch (ConnectionException e) {
    9. e.printStackTrace();
    10. } catch (RequestTimeoutException e) {
    11. e.printStackTrace();
    12. } catch (ServiceResponseException e) {
    13. e.printStackTrace();
    14. System.out.println(e.getHttpStatusCode());
    15. System.out.println(e.getErrorCode());
    16. System.out.println(e.getErrorMsg());
    17. }

    批量删除人脸

    1. BatchDeleteFacesRequest batchDeleteFacesRequest = new BatchDeleteFacesRequest();
    2. batchDeleteFacesRequest.withFaceSetName("face_set_name");
    3. DeleteFacesBatchReq deleteFacesBatchReq = new DeleteFacesBatchReq();
    4. deleteFacesBatchReq.withFilter("age:[20 TO 30]");
    5. batchDeleteFacesRequest.withBody(deleteFacesBatchReq);
    6. try {
    7. BatchDeleteFacesResponse batchDeleteFacesResponse = client.batchDeleteFaces(batchDeleteFacesRequest);
    8. System.out.println(batchDeleteFacesResponse.toString());
    9. } catch (ConnectionException e) {
    10. e.printStackTrace();
    11. } catch (RequestTimeoutException e) {
    12. e.printStackTrace();
    13. } catch (ServiceResponseException e) {
    14. e.printStackTrace();
    15. System.out.println(e.getHttpStatusCode());
    16. System.out.println(e.getErrorCode());
    17. System.out.println(e.getErrorMsg());
    18. }

    更新人脸

    1. UpdateFaceRequest updateFaceRequest = new UpdateFaceRequest();
    2. updateFaceRequest.withFaceSetName("face_set_name");
    3. UpdateFaceReq updateFaceReq = new UpdateFaceReq();
    4. updateFaceReq.withFaceId("iexEBb6t");
    5. updateFaceRequest.withBody(updateFaceReq);
    6. try {
    7. UpdateFaceResponse response = client.updateFace(updateFaceRequest);
    8. System.out.println(response.toString());
    9. } catch (ConnectionException e) {
    10. e.printStackTrace();
    11. } catch (RequestTimeoutException e) {
    12. e.printStackTrace();
    13. } catch (ServiceResponseException e) {
    14. e.printStackTrace();
    15. System.out.println(e.getHttpStatusCode());
    16. System.out.println(e.getErrorCode());
    17. System.out.println(e.getErrorMsg());
    18. }

    查询人脸

    1. //show faces by faceId
    2. ShowFacesByFaceIdRequest showFacesByFaceIdRequest = new ShowFacesByFaceIdRequest();
    3. showFacesByFaceIdRequest.withFaceSetName("face_set_name");
    4. showFacesByFaceIdRequest.withFaceId("iexEBb6t");
    5. try {
    6. ShowFacesByFaceIdResponse response = client.showFacesByFaceId(showFacesByFaceIdRequest);
    7. System.out.println(response.toString());
    8. } catch (ConnectionException e) {
    9. e.printStackTrace();
    10. } catch (RequestTimeoutException e) {
    11. e.printStackTrace();
    12. } catch (ServiceResponseException e) {
    13. e.printStackTrace();
    14. System.out.println(e.getHttpStatusCode());
    15. System.out.println(e.getErrorCode());
    16. System.out.println(e.getErrorMsg());
    17. }

    3.3 活体识别/检测

    3.3.1 动作活体检测

    1. //detect live by base64
    2. DetectLiveByBase64Request request = new DetectLiveByBase64Request();
    3. LiveDetectBase64Req body = new LiveDetectBase64Req();
    4. body.withActions("1,2,3,4");
    5. body.withVideoBase64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    6. request.withBody(body);
    7. try {
    8. DetectLiveByBase64Response response = client.detectLiveByBase64(request);
    9. System.out.println(response.toString());
    10. } catch (ConnectionException e) {
    11. e.printStackTrace();
    12. } catch (RequestTimeoutException e) {
    13. e.printStackTrace();
    14. } catch (ServiceResponseException e) {
    15. e.printStackTrace();
    16. System.out.println(e.getHttpStatusCode());
    17. System.out.println(e.getErrorCode());
    18. System.out.println(e.getErrorMsg());
    19. }

    3.3.2默活体检测

    1. //detect live face by base64
    2. DetectLiveFaceByBase64Request request = new DetectLiveFaceByBase64Request();
    3. LiveDetectFaceBase64Req body = new LiveDetectFaceBase64Req();
    4. body.withImageBase64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    5. request.withBody(body);
    6. try {
    7. DetectLiveFaceByBase64Response response = client.detectLiveFaceByBase64(request);
    8. System.out.println(response.toString());
    9. } catch (ConnectionException e) {
    10. e.printStackTrace();
    11. } catch (RequestTimeoutException e) {
    12. e.printStackTrace();
    13. } catch (ServiceResponseException e) {
    14. e.printStackTrace();
    15. System.out.println(e.getHttpStatusCode());
    16. System.out.println(e.getErrorCode());
    17. System.out.println(e.getErrorMsg());
    18. }

    3.4人脸搜索

    1. SearchFaceByBase64Request searchRequest = new SearchFaceByBase64Request();
    2. searchRequest.withFaceSetName("face_set_name");
    3. FaceSearchBase64Req faceSearchBase64Req = new FaceSearchBase64Req();
    4. List<Map<String, String>> listbodySort = new ArrayList<>();
    5. Map<String, String> map = new HashMap<>();
    6. map.put("timestamp","asc");
    7. listbodySort.add(map);
    8. List<String> listbodyReturnFields = new ArrayList<>();
    9. listbodyReturnFields.add("timestamp");
    10. listbodyReturnFields.add("id");
    11. faceSearchBase64Req.withSort(listbodySort);
    12. faceSearchBase64Req.withReturnFields(listbodyReturnFields);
    13. faceSearchBase64Req.withImageBase64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    14. searchRequest.withBody(faceSearchBase64Req);
    15. try {
    16. SearchFaceByBase64Response searchResponse = client.searchFaceByBase64(searchRequest);
    17. System.out.println(searchResponse.toString());
    18. } catch (ConnectionException e) {
    19. e.printStackTrace();
    20. } catch (RequestTimeoutException e) {
    21. e.printStackTrace();
    22. } catch (ServiceResponseException e) {
    23. e.printStackTrace();
    24. System.out.println(e.getHttpStatusCode());
    25. System.out.println(e.getErrorCode());
    26. System.out.println(e.getErrorMsg());
    27. }

    3.5 人脸比对

    1. CompareFaceByBase64Request compareRequest = new CompareFaceByBase64Request();
    2. FaceCompareBase64Req faceCompareBase64Req = new FaceCompareBase64Req();
    3. faceCompareBase64Req.withImage1Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    4. faceCompareBase64Req.withImage2Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    5. compareRequest.withBody(faceCompareBase64Req);
    6. try {CompareFaceByBase64Request compareRequest = new CompareFaceByBase64Request();
    7. FaceCompareBase64Req faceCompareBase64Req = new FaceCompareBase64Req();
    8. faceCompareBase64Req.withImage1Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    9. faceCompareBase64Req.withImage2Base64("/9j/4AAQSkZJRgABAQAAAQABAAD...");
    10. compareRequest.withBody(faceCompareBase64Req);
    11. try {
    12. CompareFaceByBase64Response compareResponse = client.compareFaceByBase64(compareRequest);
    13. System.out.println(compareResponse.toString());
    14. } catch (ConnectionException e) {
    15. e.printStackTrace();
    16. } catch (RequestTimeoutException e) {
    17. e.printStackTrace();
    18. } catch (ServiceResponseException e) {
    19. e.printStackTrace();
    20. System.out.println(e.getHttpStatusCode());
    21. System.out.println(e.getErrorCode());
    22. System.out.println(e.getErrorMsg());
    23. }
    24. CompareFaceByBase64Response compareResponse = client.compareFaceByBase64(compareRequest);
    25. System.out.println(compareResponse.toString());
    26. } catch (ConnectionException e) {
    27. e.printStackTrace();
    28. } catch (RequestTimeoutException e) {
    29. e.printStackTrace();
    30. } catch (ServiceResponseException e) {
    31. e.printStackTrace();
    32. System.out.println(e.getHttpStatusCode());
    33. System.out.println(e.getErrorCode());
    34. System.out.println(e.getErrorMsg());
    35. }

    4、偷偷藏不住的你

    身份验证

    使用人脸检测与比对功能,可进行身份核实,适用于机场、海关等人证合一验证场景。

    电子考勤

    人脸检测及比对功能适用于客户企业对员工进行电子考勤。

    客流分析

    客流分析对于商场具有重要价值。基于人脸识别、搜索技术,帮助客户精准营销。

    5、参考文献

    https://support.huaweicloud.com/usermanual-cbs/cbs_01_0029.html

    https://console.huaweicloud.com/cbs/?region=cn-north-4#/cbs/management/skills

    6、体验插件的魅力

    华为云devkit已上线:https://developer.huaweicloud.com/develop/toolkit.html

  • 相关阅读:
    I/O软件层次结构(用户层软件,设备独立性软件,设备驱动程序,中断处理程序,硬件)
    K8S控制器
    什么是鉴权?这些postman鉴权方式你又知道多少?
    RTOS相对延时和绝对延时的区别
    java计算机毕业设计ssm图书馆预约管理系统txke6(附源码、数据库)
    多线程与高并发——并发编程(8)
    Mysql行级锁
    SSCI及SCI撰写|立足于审稿进行论文修改
    【K8S系列】深入解析k8s网络插件—Calico
    第9届Python编程挑战赛海南赛区复赛真题剖析-2023年全国青少年信息素养大赛
  • 原文地址:https://blog.csdn.net/hwxiaozhi/article/details/132730528