阿里云图像搜索的尝试

阿里云图像搜索

官方文档

什么是图像搜索

引用阿里官方文档的话:

  • 图像搜索服务 (Image Search)是以深度学习和大规模机器学习技术为核心,通过图像识别和搜索功能,实现以图搜图的智能图像搜索产品。图像搜索服务在基于图像识别技术基础上,结合不同行业应用和业务场景,帮助用户实现相同或相似图片搜索。图片搜索匹配到的相同或类似的照片按照阈值大小排序进行返回,最多可返回前500张图片参数,越靠前相似度越高。
  • 图像搜索服务内容:
    商品图像搜索:通过输入商品图片,可以在商品库中准确地找到图片中商品的同款或者相似款,返回对应的商品信息。
    布料图像搜索:通过输入布料图片,可以在布料库中准确地找到与输入相同或相似纹理的布料,返回对应的布料信息。
    商标图像搜索:通过输入商标图片,可以在商标库中准确地找到与输入相同或相似的商标,返回对应的商标信息。
    通用图像搜索:通过输入具有相同元素或主体内容的图片,在海量图片库中查找相似或相同的图片。

前期工作

  1. 登录图像搜索控制台。
  2. 在左侧导航栏里单击相应的 业务场景 (商品图片搜索、布料图片搜索、商标图片搜索、通用图片搜索),并在列表左上方单击 创建实例
  3. 在售卖页面上选择相应的 地域

注意:不同地域内的实例网络不互通,且购买后不能更换地域,请谨慎选择。

  1. 选择 访问频次最大容量。

注意:不同的访问频次和最大容量对应的独享的资源数量不同,相应的价格也不同,目前最大可支持10QPS和5000万图片(注:对于商品图片搜索,该处指的是图片数量,而不是商品数量)容量,如果超出最大容量需单独申请。

  1. 填写实例名称。

注意:实例名称由小写英文字母和数字组成,且首字符为小写英文字母,名称长度为4-32个字符,如: imagesearch1022。

  1. 选择套餐类型、套餐包以及购买时长。
  2. 确认费用并单击立即购买

注意:购买完成后,系统会自动进行实例的初始化操作,如果购买后实例为 新建 或者 初始化失败 状态,请在 实例列表 或者 实例详情页 单击
初始化 按钮进行初始化操作。

完成之后在图像搜索控制台可以看到

在这里插入图片描述

子账号控制台离线导入图片权限配置

离线权限配置

  • 在RAM控制台上,选择 策略管理 > 新建授权策略。
    在这里插入图片描述
  • 在 RAM 控制台上,选择 角色管理 > 新建角色。
    在这里插入图片描述
    在这里插入图片描述
  • 给RAM角色授权ImagesSearchAccessOSS
  • 给RAM角色授权操作OSSAliyunImageSearchFullAccess
    在这里插入图片描述

离线图片上传

在OSS中新建文件夹目录/increment,在/increment目录下上传照片文件,和increment.meta文件
在这里插入图片描述

#increment.meta
{"operator":"ADD","item_id":"test1", "cust_content":"123", "pic_list":["test1.jpg"]}
{"operator":"ADD","item_id":"test2", "cust_content":"456", "pic_list":["test2.jpg"]}
{"operator":"ADD","item_id":"test3", "cust_content":"789", "pic_list":["text3.png"]}

图片搜索控制台中,点击通用照片实例。点击增量。这边使用的图像搜索是试用版本,所以不支持清空实例中的数据的功能。
在这里插入图片描述
下图中 资源名称是在上面创建RAM角色步骤中可以进行查看(ImageSearchRole)
Bucket名称就是OSS中的Bucket名称
数据路径就是/increment
在这里插入图片描述

上传完成

在这里插入图片描述

与项目集成(需要结合前面说到的OSS)

图像搜索与项目的集成在oss项目的基础上进行集成
pom依赖
# pom.xml
<!-- aliyun imagessearch-->
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-imagesearch</artifactId>
    <version>2.0.0</version>
</dependency>
配置文件

以下文件中的子账号就是之前sts用到的子账号。
但是至于图像搜索能否集成OSS+STS,我倒是没有看到相关文档,尝试了一下使用STS获取到的临时AccessKeyID和AccessKeySecret和SecurityToken但是失败了,可是查看源代码确实是有发现public static synchronized DefaultProfile getProfile(String regionId, String accessKeyId, String secret, String stsToken)这样一个方法这个方法是否如我所想能够结合ststoken,这点还不是很明确,还望有了解的大神赐教。

# imagesearch.properties
#阿里云imageSearch配置
imageSearch.regionId=cn-shanghai
imageSearch.product=ImageSearch
imageSearch.endpoint=imagesearch.cn-shanghai.aliyuncs.com
#子账号
imageSearch.accessKeyId=LTAI4F*******KYrpsp93Jy
imageSearch.accessKeySecret=WJPEEnybNO*********zSc0AnbsP
imageSearch.roleArn=acs:ram::1********9809:role/********chrole
imageSearch.instanceName=imagessear******

# 注意:
目前阿里云图像搜索只有华东(上海),而图像搜索要求用到的OSS在同一区域中才能使用
所以之前用到的oss最好选择华东(上海)区域的服务。
工具类的使用

这个工具类主要用到的sdk SDK官网中的,结合配置文件。

# ImageSearchUtil.java
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.imagesearch.model.v20190325.*;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.UUID;

/**
 * @Author Qizy
 * @Date 2019/12/18 14:34
 * @Version 1.0
 **/
@Getter
@Setter
@Component
@Configuration
@PropertySource(value = { "classpath:imagesearch.properties" })
public class ImageSearchUtil {
    @Value("${imageSearch.regionId}")
    private String regionId;

    @Value("${imageSearch.product}")
    private String product;

    @Value("${imageSearch.endpoint}")
    private String endpoint;

    @Value("${imageSearch.accessKeyId}")
    private String accessKeyId;

    @Value("${imageSearch.accessKeySecret}")
    private String accessKeySecret;

    @Value("${imageSearch.instanceName}")
    private String instanceName;

    @Value("${imageSearch.roleArn}")
    private String roleArn;

    private IAcsClient initClient() {
        //创建 Profile。生成 IClientProfile 的对象 profile,该对象存放 AccessKeyID 和 AccessKeySecret 和地域信息。
        IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);

        //设置图像搜索服务访问的 EndPoint,假定实例是在上海区域。
        DefaultProfile.addEndpoint(regionId, product, endpoint);

        //创建 Client。从 IClientProfile 类中再生成 IAcsClient 的对象 client,后续获得 response 都需要从 IAcsClient 中获得。
        IAcsClient client = new DefaultAcsClient(profile);

        return client;
    }

    /**
     * 添加图片
     * @param filePath 文件路径
     * @param categoryId 类别类目(选填)
     *                   对于商品搜索:若设置类目,则以设置的为准;若不设置类目,将由系统进行类目预测,预测的类目结果可在Response中获取 。
     *                   对于布料、商标、通用搜索:不论是否设置类目,系统会将类目设置为 88888888。
     * @param crop  选填,是否需要进行主体识别,默认为true。
     * @param region 选填,图片的主体区域,格式为 x1,x2,y1,y2, 其中 x1,y1 是左上角的点,x2,y2是右下角的点。
     * @param intAttr 选填,整数类型属性,可用于查询时过滤,查询时会返回该字段。
     * @param strAttr 选填,字符串类型属性,最多支持 128个字符。可用于查询时过滤,查询时会返回该字段。
     * @param customContent 选填,用户自定义的内容,最多支持 4096个字符。
     * @return
     */
    public AddImageResponse add(String filePath, Integer categoryId, String region, Boolean crop, Integer intAttr, String strAttr, String customContent) {
        AddImageResponse response = null;
        IAcsClient client = initClient();

        AddImageRequest request = new AddImageRequest();

        if(filePath == null || StringUtils.equals(filePath.trim(), "")){
            return response;
        }

        // 必填,图像搜索实例名称。
        request.setInstanceName(instanceName);

        // 必填,商品id,最多支持 512个字符。
        // 一个商品可有多张图片。
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        request.setProductId(uuid);

        // 必填,图片名称,最多支持 512个字符。
        // 1. ProductId + PicName唯一确定一张图片。
        // 2. 如果多次添加图片具有相同的ProductId + PicName,以最后一次添加为准,前面添加的的图片将被覆盖。
        request.setPicName(uuid + getFileName(filePath.trim()));

        // 选填,图片类目。
        // 1. 对于商品搜索:若设置类目,则以设置的为准;若不设置类目,将由系统进行类目预测,预测的类目结果可在Response中获取 。
        // 2. 对于布料、商标、通用搜索:不论是否设置类目,系统会将类目设置为 88888888。
        if(categoryId != null){
            request.setCategoryId(categoryId);
        }else {
            request.setCategoryId(88888888);
        }

        // 必填,图片内容,Base64编码。
        // 最多支持 2MB大小图片以及5s的传输等待时间。当前仅支持jpg和png格式图片;
        // 对于商品、商标、通用图片搜索,图片长和宽的像素必须都大于等于200,并且小于等于1024;
        // 对于布料搜索,图片长和宽的像素必须都大于等于448,并且小于等于1024;
        // 图像中不能带有旋转信息。
        byte[] bytes2 = getBytes(filePath);
        Base64 base64 = new Base64();
        String encodePicContent = base64.encodeToString(bytes2);
        request.setPicContent(encodePicContent);

        // 选填,是否需要进行主体识别,默认为true。
        // 1.为true时,由系统进行主体识别,以识别的主体进行搜索,主体识别结果可在Response中获取。
        // 2. 为false时,则不进行主体识别,以整张图进行搜索。
        // 3.对于布料图片搜索,此参数会被忽略,系统会以整张图进行搜索。
        if(crop != null){
            request.setCrop(crop);
        }

        // 选填,图片的主体区域,格式为 x1,x2,y1,y2, 其中 x1,y1 是左上角的点,x2,y2是右下角的点。
        // 若用户设置了Region,则不论Crop参数为何值,都将以用户输入Region进行搜索。
        // 对于布料图片搜索,此参数会被忽略,系统会以整张图进行搜索。
        if(region != null && !StringUtils.equals(region.trim(), "")){
            request.setRegion(region);
        }/*else {
            request.setRegion("280,486,232,351");
        }*/

        // 选填,整数类型属性,可用于查询时过滤,查询时会返回该字段。
        //  例如不同的站点的图片/不同用户的图片,可以设置不同的IntAttr,查询时通过过滤来达到隔离的目的
        if(intAttr != null){
            request.setIntAttr(intAttr);
        }

        // 选填,字符串类型属性,最多支持 128个字符。可用于查询时过滤,查询时会返回该字段。
        if(strAttr != null && !StringUtils.equals(strAttr.trim(), "")){
            request.setStrAttr(strAttr);
        }


        // 选填,用户自定义的内容,最多支持 4096个字符。
        // 查询时会返回该字段。例如可添加图片的描述等文本。
        if(customContent != null && !StringUtils.equals(customContent.trim(), "")){
            request.setCustomContent(customContent);
        }

        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            // 抛出异常,例如参数无效,或者实例不可用等情况
            e.printStackTrace();
        }

        return response;
    }

    /**
     * 根据图片搜索图片
     * @param filePath 文件路径
     * @param categoryId 类别类目(选填)
     *                   对于商品搜索:若设置类目,则以设置的为准;若不设置类目,将由系统进行类目预测,预测的类目结果可在Response中获取 。
     *                   对于布料、商标、通用搜索:不论是否设置类目,系统会将类目设置为 88888888。
     * @param crop  选填,是否需要进行主体识别,默认为true。
     * @param region 选填,图片的主体区域,格式为 x1,x2,y1,y2, 其中 x1,y1 是左上角的点,x2,y2是右下角的点。
     * @param num 选填,返回结果的数目。取值范围:1-100。默认值:10。
     * @param start 选填,返回结果的起始位置。取值范围:0-499。默认值:0。
     * @param filter 选填,过滤条件
     *               int_attr支持的操作符有>、>=、<、<=、=,str_attr支持的操作符有=和!=,多个条件之支持AND和OR进行连接
     * @return
     */
    public SearchImageResponse searchByPic(String filePath, Integer categoryId, String region, Boolean crop, Integer num, Integer start, String filter) {
        SearchImageResponse response = null;
        IAcsClient client = initClient();

        SearchImageRequest request = new SearchImageRequest();

        // 必填,图像搜索实例名称。
        request.setInstanceName(instanceName);

        // 选填,搜索类型,取值范围:
        // 1. SearchByPic(默认):根据图片搜索相似图片。
        // 2. SearchByName,根据已添加的图片搜索相似图片。
        request.setType("SearchByPic");

        // 图片内容,Base64编码。最多支持 2MB大小图片以及5s的传输等待时间。当前仅支持jpg和png格式图片;
        // 对于商品、商标、通用图片搜索,图片长和宽的像素必须都大于等于200,并且小于等于1024;
        // 对于布料搜索,图片长和宽的像素必须都大于等于448,并且小于等于1024;
        // 图像中不能带有旋转信息。
        // 1. Type=SearchByPic时,必填
        // 2. Type=SearchByName时,无需填写。
        byte[] bytes2 = getBytes(filePath);
        Base64 base64 = new Base64();
        String encodePicContent = base64.encodeToString(bytes2);
        request.setPicContent(encodePicContent);

        // 选填,商品类目。
//      1. Type=SearchByPic时,选填:
//          1)对于商品搜索,若设置类目,则以设置的为准;若不设置类目,将由系统进行类目预测,预测的类目结果可在Response中获取 。
//          2)对于布料、商标、通用搜索:不论是否设置类目,系统会将类目设置为88888888。
//      2. Type=SearchByName时,无需填写,本参数不生效。
        if(categoryId != null){
            request.setCategoryId(categoryId);
        }else {
            request.setCategoryId(88888888);
        }

        // 选填,图片的主体区域,格式为 x1,x2,y1,y2, 其中 x1,y1 是左上角的点,x2,y2是右下角的点。
//        1. Type=SearchByPic时,选填:若用户设置了Region,则不论Crop参数为何值,都将以用户输入Region进行搜索。
//        2. Type=SearchByName时,无需填写,本参数不生效。
//        3. 对于布料图片搜索,此参数会被忽略,系统会以整张图进行搜索。
        if(region != null &&  !StringUtils.equals(region.trim(), "")){
            request.setRegion(region);
        }

        // 选填,是否需要进行主体识别,默认为true。
//        1.Type=SearchByPic时,选填:
//              1)为true时,由系统进行主体识别,以识别的主体进行搜索,主体识别结果可在Response中获取。
//              2)为false时,则不进行主体识别,以整张图进行搜索。
//        2. Type=SearchByName时,无需填写,本参数不生效。
//        3. 对于布料图片搜索,此参数会被忽略,系统会以整张图进行搜索。
        if(crop != null){
            request.setCrop(crop);
        }

        // 选填,返回结果的数目。取值范围:1-100。默认值:10。
        if(num != null){
            request.setNum(num);
        }

        // 选填,返回结果的起始位置。取值范围:0-499。默认值:0。
        if(start != null){
            request.setStart(start);
        }

        // 选填,过滤条件
        // int_attr支持的操作符有>、>=、<、<=、=,str_attr支持的操作符有=和!=,多个条件之支持AND和OR进行连接。
        // 示例:
        //  1. 根据IntAttr过滤结果,int_attr>=100
        //  2. 根据StrAttr过滤结果,str_attr!="value1"
        //  3. 根据IntAttr和StrAttr联合过滤结果,int_attr=1000 AND str_attr="value1"
        //request.setFilter("int_attr=1");
        if(filter != null && !StringUtils.equals(filter.trim(), "")){
            request.setFilter(filter);
        }

        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
        }

        return response;
    }

    /**
     * 根据已入库的图片(ProductId+PicName)搜索图片
     * @param productId 必填,已添加图片的ProductId。
     * @param picName 必填,已添加图片的PicName。
     * @param num 选填,返回结果的数目。取值范围:1-100。默认值:10。
     * @param start 选填,返回结果的起始位置。取值范围:0-499。默认值:0。
     * @param filter 选填,过滤条件
     *               int_attr支持的操作符有>、>=、<、<=、=,str_attr支持的操作符有=和!=,多个条件之支持AND和OR进行连接
     * @return
     */
    public SearchImageResponse searchByName(String productId, String picName, Integer num, Integer start, String filter) {
        SearchImageResponse response = null;
        IAcsClient client = initClient();

        SearchImageRequest request = new SearchImageRequest();
        // 必填,图像搜索实例名称。
        request.setInstanceName(instanceName);

        // 选填,搜索类型,取值范围:
        // 1. SearchByPic(默认):根据图片搜索相似图片。
        // 2. SearchByName,根据已添加的图片搜索相似图片。
        request.setType("SearchByName");

        // 商品id。
        // 1. Type=SearchByPic时,无需填写
        // 2. Type=SearchByName时,必填,已添加图片的ProductId。
        request.setProductId(productId);

        // 图片名称。
        // 1. Type=SearchByPic时,无需填写
        // 2. Type=SearchByName时,必填,已添加图片的PicName。
        request.setPicName(picName);

        // 选填,返回结果的数目。取值范围:1-100。默认值:10。
        if(num != null){
            request.setNum(num);
        }

        // 选填,返回结果的起始位置。取值范围:0-499。默认值:0。
        if(start != null){
            request.setStart(start);
        }

        // 选填,过滤条件
        // int_attr支持的操作符有>、>=、<、<=、=,str_attr支持的操作符有=和!=,多个条件之支持AND和OR进行连接。
        // 示例:
        //  1. 根据IntAttr过滤结果,int_attr>=100
        //  2. 根据StrAttr过滤结果,str_attr!="value1"
        //  3. 根据IntAttr和StrAttr联合过滤结果,int_attr=1000 AND str_attr="value1"
        //request.setFilter("int_attr=1");
        if(filter != null && !StringUtils.equals(filter.trim(), "")){
            request.setFilter(filter);
        }

        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 根据ID和name,删除图片搜索中的图片
     * @param productId id 必填
     * @param picName name 若不指定本参数,则删除ProductId下所有图片;若指定本参数,则删除ProductId+PicName指定的图片。
     * @Description: id必填 name选填
     * @return
     */
    public DeleteImageResponse delete(String productId, String picName) {
        DeleteImageResponse response = null;
        IAcsClient client = initClient();

        DeleteImageRequest request = new DeleteImageRequest();

        if(productId == null || StringUtils.equals(productId.trim(), "")){
            return null;
        }

        // 必填,图像搜索实例名称。
        request.setInstanceName(instanceName);

        // 必填,商品id。
        request.setProductId(productId);

        // 选填,图片名称。若不指定本参数,则删除ProductId下所有图片;若指定本参数,则删除ProductId+PicName指定的图片。
        request.setPicName(picName);
        try {
            response = client.getAcsResponse(request);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return response;
    }

    private static byte[] getBytes(String filePath) {
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            // picture max size is 2MB
            ByteArrayOutputStream bos = new ByteArrayOutputStream(2000 * 1024);
            byte[] b = new byte[1000];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

    private String getFileName(String filePath){
        String back = null;
        try{
            File tempFile =new File(filePath.trim());
            back =  tempFile.getName();
        } catch (Exception e){
            e.printStackTrace();
        }
        return back;
    }
}

做一下简单的测试

测试的控制层代码集成了swagger2 如果没有集成则需要删除@Api @ApiOperation等注解

# ImagesSearchController.java
import com.aliyuncs.imagesearch.model.v20190325.AddImageResponse;
import com.aliyuncs.imagesearch.model.v20190325.DeleteImageResponse;
import com.aliyuncs.imagesearch.model.v20190325.SearchImageResponse;
import com.learning.ssm_swagger.util.ImageSearchUtil;
import com.learning.ssm_swagger.util.STSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.File;
import java.util.LinkedList;

/**
 * @Author Qizy
 * @Date 2019/12/11 9:43
 * @Version 1.0
 **/
@Controller
@RequestMapping("/imageSearch")
@Api(value="图片搜索 Service Controller", description = "阿里云图片搜索测试")
public class ImagesSearchController {

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    private static final String TO_PATH="upLoad";
    private static final String RETURN_PATH="success";

    @Autowired
    private ImageSearchUtil imageSearchUtil;

    @ApiOperation(value = "图片搜索-上传图片", notes = "图片搜索-上传图片", httpMethod = "POST")
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public AddImageResponse upload(String filePath) throws Exception {
        AddImageResponse add = imageSearchUtil.add(filePath, 88888888, null, false, null, null, null);
        return add;
    }

    @ApiOperation(value = "图片搜索-删除图片", notes = "图片搜索-删除图片", httpMethod = "POST")
    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    @ResponseBody
    public DeleteImageResponse delete(String productId, String picName) throws Exception {
        DeleteImageResponse delete = imageSearchUtil.delete(productId, picName);
        return delete;
    }

    @ApiOperation(value = "图片搜索-搜索图片-根据图片", notes = "图片搜索-搜索图片", httpMethod = "POST")
    @RequestMapping(value = "/searchByPic", method = RequestMethod.POST)
    @ResponseBody
    public SearchImageResponse searchByPic(String filePath) throws Exception {
        SearchImageResponse searchImageResponse = imageSearchUtil.searchByPic(filePath, 88888888, null, false, null, null, null);
        return searchImageResponse;
    }

    @ApiOperation(value = "图片搜索-搜索图片-根据名字", notes = "图片搜索-搜索图片", httpMethod = "POST")
    @RequestMapping(value = "/searchByName", method = RequestMethod.POST)
    @ResponseBody
    public SearchImageResponse searchByName(String productId, String picName) throws Exception {
        SearchImageResponse searchImageResponse = imageSearchUtil.searchByName(productId, picName,  null, null, null);
        return searchImageResponse;
    }

    @ApiOperation(value = "图片搜索-搜索图片-批量", notes = "图片搜索-搜索图片", httpMethod = "POST")
    @RequestMapping(value = "/loadfiles", method = RequestMethod.POST)
    @ResponseBody
    public void loadfiles() throws Exception {
        int fileNum = 0, folderNum = 0;
        File file = new File("C:\\Users\\Administrator.DESKTOP-H1HGKGC\\Desktop\\upload");
        if (file.exists()) {
            File[] files = file.listFiles();
            for (File file2 : files) {
                if (file2.isDirectory()) {
                    folderNum++;
                } else {
                    System.out.println("文件:" + file2.getAbsolutePath());
                    fileNum++;

                    AddImageResponse add = imageSearchUtil.add(file2.getAbsolutePath(), 88888888, null, false, null, null, null);
                }
            }
        } else {
            System.out.println("文件不存在!");
        }
        System.out.println("文件夹共有:" + folderNum + ",文件共有:" + fileNum);
    }
}

图片查询返回数据

根据图片搜索机器学习的性质,查询的图片根据匹配阈值高低进行返回,第一个返回的数据匹配度最高。
返回的json数据各个字段的意思。
官方文档

{
  "requestId": "0FA6726E-85E5-4D70-B871-697AFF256AAA",
  "success": true,
  "code": 0,
  "msg": "success",
  "auctions": [
    {
      "categoryId": 88888888,
      "productId": "ocrtest",
      "picName": "ocrtest.jpg",
      "customContent": "k1:v1,k2:v2,k3:v3",
      "sortExprValues": "25.7281875610352;69",
      "intAttr": null,
      "strAttr": null
    },
    {
      "categoryId": 88888888,
      "productId": "test2",
      "picName": "test2.jpg",
      "customContent": "456",
      "sortExprValues": "5.51136159896851;173",
      "intAttr": null,
      "strAttr": null
    },
    ...
  ],
  "head": {
    "docsReturn": 10,
    "docsFound": 372,
    "searchTime": 112
  },
  "picInfo": {
    "categoryId": 88888888,
    "region": null,
    "allCategories": [
      {
        "id": 0,
        "name": "Tops"
      },
      ...
    ]
  }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值