ViSearch 是一种提供精确、可靠和可扩展的图像搜索的 API。ViSearch API 提供两项服务(数据 API 和搜索 API),让开发人员可以高效地准备图像数据库和执行图像搜索。ViSearch API 可以轻松集成到您的网页和移动应用程序中。更多详细信息,请参阅 ViSearch API 文档。
ViSearch iOS SDK 是一个开源软件,用于将 ViSearch 搜索 API 与您的 iOS 应用程序轻松集成。它提供了基于 ViSearch 解决方案 API 的四种搜索方法 - 查找相似、你可能也喜欢、按图像搜索和按颜色搜索。请访问 GitHub 仓库 以获取源代码和参考资料。
当前稳定版本
支持的 iOS 版本:iOS 8.x 及以上
示例应用程序的源代码与 SDK 一起提供(示例)。您只需在 XCode 中打开 示例 项目并运行示例即可。
在运行之前,您应将AppDelegate文件中的访问密钥和秘密密钥更改为自己的密钥对。
ViSearch.sharedInstance.setup(accessKey: "YOUR_ACCESS_KEY", secret: "YOUR_SECRET_KEY")
您可以尝试我们的演示应用程序,以了解我们如何使用ViSearch SDK构建酷炫的图像搜索功能。
在Xcode中,转到“文件”>“新建”>“项目”,选择“单视图应用程序”。
为您的项目输入一个名称并按“下一步”,这里我们使用“Demo”作为项目名称。
您还可以直接下载iOS ViSearch SDK。要使用它,将其解压缩并将ViSearchSDK项目拖动到Demo项目中。
打开ViSearchSDK
文件夹,并将ViSearchSDK.xcodeproj
拖放到您的应用Xcode项目的项目导航器中。
它应该出现在您应用蓝色项目图标下的嵌套中。它是否位于所有其他Xcode组之上或之下无关紧要。
在项目导航器中选择ViSearchSDK.xcodeproj
,并验证部署目标与您的应用目标目标相匹配。
+
按钮。ViSearchSDK.framework
。
ViSearchSDK.framework
会自动添加为目标依赖、链接框架和嵌套框架。
您已完成!
iOS 10现在要求用户许可才能访问相机和相册。如果您的应用需要这些访问,请在Info.plist中添加NSCameraUsageDescription,NSPhotoLibraryUsageDescription的描述。更多细节可以在这里找到。
ViSearch
必须在可以使用之前用访问密钥/秘密密钥对进行初始化。
import ViSearchSDK
...
// using default ViSearch client. The client, by default, will connect to Visenze's server
ViSearch.sharedInstance.setup(accessKey: "YOUR_ACCESS_KEY", secret: "YOUR_SECRET_KEY")
...
// or using customized client, which connects to your own server
client = ViSearchClient(baseUrl: yourUrl, accessKey: accessKey, secret: secret)
...
查找相似解决方案用于在图像数据库中根据索引图像的唯一标识符(im_name)搜索视觉相似的图像。
import ViSearchSDK
...
let params = ViSearchParams(imName: "imName-example")
ViSearch.sharedInstance.findSimilar( params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \\(err.localizedDescription)")
})
...
您可能还会喜欢解决方案用于根据可定制的规则,从索引图像数据库中提供一个推荐项目列表,基于索引图像的唯一标识符(im_name)。
import ViSearchSDK
...
let params = ViSearchParams(imName: "imName-example")
ViSearch.sharedInstance.recommendation( params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \\(err.localizedDescription)")
})
...
根据图像搜索解决方案用于通过上传图像或提供图像URL来搜索相似的图像。您需要构建UIImage
对象并将其传递给ViUploadSearchParams
以开始搜索。
import ViSearchSDK
...
let image = UIImage(named: "someImage.png")
let params = ViUploadSearchParams(image: image!)
ViSearch.sharedInstance.uploadSearch(params: params,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \\(err.localizedDescription)")
})
ViUploadSearchParams
以启动搜索import ViSearchSDK
...
let params = ViUploadSearchParams(im_url: "http://somesite.com/sample_image.png")
ViSearch.sharedInstance.uploadSearch(params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \\(err.localizedDescription)")
})
...
import ViSearchSDK
...
let params = ViUploadSearchParams(im_id: "im_id_example")
ViSearch.sharedInstance.uploadSearch(params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \\(err.localizedDescription)")
...
如果您要搜索的对象只占图像的一小部分,或者图像中存在其他无关对象,那么搜索结果可能不准确。使用Box参数来细化图像的搜索区域,以提高准确性。框坐标是以上传图像的原始大小设置的。注意:坐标系使用像素为单位,而不是点。
// create the box to refine the area on the searching image
// ViBox(x1, y1, x2, y2) where (0,0) is the top-left corner
// of the image, (x1, y1) is the top-left corner of the box,
// and (x2, y2) is the bottom-right corner of the box.
...
let params = ViUploadSearchParams(.....)
let box = ViBox(x1: 0, y1: 0, x2: 100, y2: 100)
params!.box = box
// start searching
...
在执行上传搜索时,您可能会注意到随着图像文件大小的增加,搜索延迟也会增加。这是因为将您的图像传输到ViSearch服务器所花费的时间增加,处理较大图像文件的时间也增加。
为了减少上传搜索延迟,默认情况下,uploadSearch方法会复制您的图像文件,并将副本调整到512x512像素,如果原始尺寸中有一个超过512像素。这是降低搜索延迟的同时,不会牺牲一般用例搜索精度的优化大小
// by default, the max width of the image is set to 512px, quality is 0.97
let params = ViUploadSearchParams(.....)
// or you can explicitly set a param's settings
params?.img_settings = ViImageSettings(setting: .highQualitySetting)
如果您的图像包含如纺织图案和纹理等精细细节,您可以使用更大的图像进行搜索以获得更好的搜索结果
// by default, the max width of the image is set to 512px, quality is 0.97
let params = ViUploadSearchParams(.....)
// set the image with high quality settings.
// Max width is 1024px, and the quality is 0.985. Note: Quality with 1.0 take hugespace
params?.img_settings = ViImageSettings(setting: .highQualitySetting)
或者,提供自定义的调整大小设置。为了有效地利用移动设备的内存和网络带宽,最大大小设置为1024 x 1024。任何超出限制的图像都将调整到限制
//resize the image to 800 by 800 area using jpeg 0.9 quality
params?.img_settings = ViImageSettings(size: CGSize(width: 800, height: 800), quality: 0.9)
根据颜色搜索解决方案是通过对颜色代码进行搜索以获取类似颜色的图像。颜色代码应该是十六进制格式,并以字符串形式传递给ViColorSearchParams
。
import ViSearchSDK
...
let params = ViColorSearchParams(color: "ff00ff")
// alternately, you can pass UIColor object to the initializer
// let params = ViColorSearchParams(color: someUIColorObject)
client.colorSearch( params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \(err.localizedDescription)")
})
...
在成功执行搜索请求后,结果列表以ViResponseData的形式传递给回调函数。您可以使用以下属性来实现您自己的目的。
名称 | 类型 | 描述 |
---|---|---|
hasError | 布尔型 | 如果有由Visenze服务器返回的错误,则为true。 |
错误 | [字符串] | 如果有任何错误消息从服务器返回,则返回错误消息。 |
结果 | [ViImageResult] | 从服务器返回的图像结果列表。 |
reqId | 字符串? | 可以用于跟踪的请求ID。更多详情可以在第7节中找到。 |
im_id | 字符串? | 结果中返回的图像ID,代表已上传的图像。它可以重新用于对同一图像进行上传搜索。更多详情在按照图像搜索中。 |
以下是一个ViImageResult的属性。
名称 | 类型 | 描述 |
---|---|---|
im_name | 字符串 | 图像的标识名称。 |
im_url | 字符串? | 如果有可用,图像的URL,例如当设置getAllFl为true或设置fl属性以包括im_url时。 |
分数 | 浮点型? | 0.0到1.0之间的浮点值。请参考第6.3节结果分数。 |
metadataDict | 字典 | 来自服务器的其他元数据。请参阅 第6.1节 检索元数据。 |
// example
ViSearch.sharedInstance.uploadSearch( params: params!,
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
if let data = data {
// check if that there is no error
if !data.hasError {
for imgResult in data.result {
// process img result
}
}
}
},
failureHandler: {
(err) -> Void in
// Do something when request fails e.g. due to network error
print ("error: \(err.localizedDescription)")
})
您可以通过配置代码中的基本搜索参数ViBaseSearchParams
来提供分页参数,以通过图片搜索结果分页。由于结果以每页图像列表的格式返回,使用limit
设置每页结果数量,page
表示页数。
名称 | 类型 | 描述 |
---|---|---|
页码 | 整数 | 指定结果页面页码的可选参数。默认页码从1开始。默认值为1。 |
limit | 整数 | 指定每页结果数量限制的可选参数。默认值为10。 |
// For example, when the server side has 60 items, the search operation will return
// the first 30 items with page = 1 and limit = 30. By changing the page to 2,
// the search will return the last 30 items.
...
params.page = 2;
params.limit = 30;
// start searching
...
要检索搜索结果的数据,请在基本搜索属性中的fl
(字段列表)中提供一个元数据键列表。
params!.fl = ["price","brand","im_url"]
要检索所有图像结果的元数据,指定get_all_fl
参数并将其设置为true。
params.getAllFl = true;
您可以在结果回调中读取元数据。
successHandler: {
(data : ViResponseData?) -> Void in
// Do something when request succeeds
// preview by calling : dump(data)
// check ViResponseData.hasError and ViResponseData.error for any errors return by ViSenze server
if let data = data {
// check if that there is no error
if !data.hasError {
for imgResult in data.result {
// process img result
// example: extract price meta-data if available in server
print imgResult.metadataDict["price"]
}
}
}
}
从ViSearch中只能检索字符串、整数和浮点型元数据。文本类型的元数据无法检索。
要根据元数据值过滤搜索结果,请提供元数据键到过滤值的映射,作为fq
(过滤查询)属性。
...
// the type of "count" on db schema is int,
// so we can specify the value range, or do a value match
params?.fq["count"] = "0, 199"
params?.fq["count"] = "199"
// the type of "price" on db schema is float,
// so we can specify the value range, or do a value match
params?.fq["price"] = "0.0, 199.0"
params?.fq["price"] = "15.0"
// the type of "description" on db schema is string, so we can do a string match.
params?.fq["description"] = "wooden"
// start searching
...
以下表格列出了每种元数据类型的查询语法。
类型 | FQ |
---|---|
字符串 | 元数据值必须与查询值精确匹配,例如:“Vintage Wingtips”将不会与“vintage wingtips”或“vintage”匹配。 |
文本 | 元数据值将使用全文搜索引擎索引,并支持模糊文本匹配,例如:“一双高质量的皮鞋尖头”将与这个短语中的任何单词匹配。 |
整数 | 元数据值可以是
|
浮点数 | 元数据值可以是
|
ViSearch的图片搜索结果按降序排列,即从最高分到最低分,范围从1.0到0.0。默认情况下,结果分数不会返回。您可以打开分数参数来检索每个图像结果的分数。
...
params.score = true; // result will include score for every image
// start searching
...
如果需要限制搜索结果的最小分数和最大分数,请指定score_min和/或score_max参数。
...
params.score = true; // result will include score for every image
params.scoreMin = 0.3; // the minimum score is 0.3
params.scoreMax = 0.8; // the maximum score is 0.8
// start searching. Every image result will have a score within [0.3, 0.8].
...
通过自动对象识别,ViSearch /uploadsearch API智能检测查询图像中存在的对象,并建议最佳匹配的产品类型以执行搜索。
您可以通过设置API参数“detection=all”来在上传搜索中打开此功能。我们现在能够检测各种类型的时尚商品,包括Top
、Dress
、Bottom
、Shoe
、Bag
、Watch
和Indian Ethnic Wear
。随着我们探索其他类别,这个列表将不断扩展。
注意:此功能目前仅适用于时尚应用程序类型。您需要确保在ViSenze仪表板上配置了您的应用程序类型为“时尚”。
params.detection = "all";
您可以使用Box参数来限制图像区域[x1, y1, x2, y2],作为图像搜索的部分。当您输入一个宽度为0和高度为0的矩形,例如“box”:[574,224,574,224]。我们将它视为一个点,并在当前点检测对象。
您也可以通过将检测参数配置为特定产品类型来识别上传查询图像上的特定类型对象,如“detection={type}”。我们的API将在该产品类型内执行搜索。
以下示例请求检测上传图像中的bag
对象
params.detection = "bag";
检测到的产品类型及其匹配分数和检测对象区域列表在product_types
中列出。可以检测查询图像中的多个对象,并按分数从高到低排序。API支持的产品类型完整列表也将返回在product_types_list
中。
可以使用这种方式发送用户动作(例如,在搜索后点击图片)
let params = ViTrackParams(accessKey: ViSearch.sharedInstance.client!.accessKey, reqId: recentReqId, action: "click" )
// You can also append an im_name field
params.imName = "example_clicked_im_name"
// send tracking request to server
ViSearch.sharedInstance.track(params: params!, handler: nil)
以下字段可以用于跟踪用户事件
字段 | 描述 | 必需 |
---|---|---|
reqid | 当前查询的visearch请求ID。此属性可以在第5节的ViResponseData中访问 | 必需 |
action | 动作类型,例如:查看、点击、购买、添加购物车。目前,我们仅支持click 事件。未来将支持更多事件。 | 必需 |
imName | 为此行为提供的图像ID(im_name) | 可选 |