Search API
API OVERVIEW
Introduction
Our ViSenze Search (ViSearch) API provides accurate, reliable and scalable image search. ViSearch API provides endpoints that let developers index their images and perform image searches efficiently. We provide powerful SDKs in various languages, so that our API can be easily integrated into your web and mobile applications.
SDK Setup
// Current stable version: 1.8.6
// Minimum JDK version: 1.6
// Maven projects: include the dependency in `pom.xml`:
<dependency>
<groupId>com.visenze</groupId>
<artifactId>visearch-java-sdk</artifactId>
<version>1.8.6</version>
</dependency>
// Gradle projects: include this line in your `build.gradle` dependencies block:
compile 'com.visenze:visearch-java-sdk:1.8.6'
// SBT projects: add the following line to `build.sbt`:
libraryDependencies += "com.visenze" % "visearch-java-sdk" % "1.8.6"
* Current stable version: 1.0.1
* Minimum requirement: php5 and php5-curl
You can get the source code of the SDK and demos from the Github repo. Download the <a>ViSearch SDK</a>and place the ViSearch to your project directory.
Include ViSearch API into your project.
//To Include ViSearch API
require_once 'pathTo/ViSearch/viSearch.php';
# Current stable version: 0.4.5
# Supported on Python 2.6+ and 3.3+
$ pip install visearch
// You can use NPM to install
npm install visearch-javascript-sdk --save
// OR,
// Paste the following snippet into the header of your site.
// This snippet will load visearch.js onto the page asynchronously,
// so it will not affect your page load speed.
<script type="text/javascript">
!function(e,r,t,s,a){e.__visearch_obj=a;var c=e[a]=e[a]||{};c.q=c.q||[],c.factory=function(r){return function(){var e=Array.prototype.slice.call(arguments);return e.unshift(r),c.q.push(e),c}},c.methods=["idsearch","uploadsearch","colorsearch","set","send","search","recommendation","out_of_stock","similarproducts","discoversearch"];for(var o=0;o<c.methods.length;o++){var n=c.methods[o];c[n]=c.factory(n)}var i=r.createElement(t);i.type="text/javascript",i.async=!0,i.src="//cdn.visenze.com/visearch/dist/js/visearch-1.5.2.min.js";var h=r.getElementsByTagName(t)[0];h.parentNode.insertBefore(i,h)}(window,document,"script",0,"visearch");
visearch.set("app_key", "YOUR_APP_KEY");
</script>
// First you need to install the Cocoapods Ruby gem:
[sudo] gem install cocoapods
pod setup
// Then go to your project directory to create an empty Podfile:
cd /path/to/Demo
pod init
// Edit the Podfile as follow:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '7.0'
...
pod 'ViSearch', '~>1.4.1'
...
// Install the ViSearch SDK:
pod install
// Current stable version: 1.2.2
// Minimum Android SDK Version: API 9, Android 2.3
// To integrate ViSearch SDK with your own application, you can start with including
// the dependency in your project using gradle:
compile 'com.visenze:visearch-android:1.2.2'
// In the build.gradle file under your app module, add the packaging options to
// ensure a successful compilation:
android {
...
packagingOptions {
exclude 'META-INF/NOTICE'
exclude 'META-INF/LICENSE'
}
...
}
You can easily setup our SDK with your preferred language and get started with integrations. You can find the source code our SDKs on the following github repos:
Authentication
$ curl https://visearch.visenze.com/search?im_name=example-0 \
-X GET \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/search?im_name=example-0 \
-X GET \
-u access_key:secret_key
ViSearch client = new ViSearch("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
// for China, please use
ViSearch client = new ViSearch("https://visearch.visenze.com.cn" ,"YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
from visearch import client
api = client.ViSearchAPI('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY')
# for China, please use
api = client.ViSearchAPI(access_key, secret_key, host="https://visearch.visenze.com.cn")
$service = new ViSearch($access_key,$secret_key);
<script type="text/javascript">
...
visearch.set("app_key", "YOUR_APP_KEY");
</script>
// for China, please use
<script type="text/javascript">
...
visearch.set("app_key", "YOUR_APP_KEY");
visearch.set("endpoint", "https://visearch.visenze.com.cn");
</script>
#import <ViSearch/VisearchAPI.h>
...
// using default ViSearch client. The client, by default,
// connects to Visenze's server
// 1. new way of init ViSearch client with only app key
static NSString * const appKey = @"your_app_key";
[ViSearchAPI setupAppKey:appKey];
ViSearchClient *client = [ViSearch defaultClient];
// 2. OR old way of init ViSearch client with access and secret key
static NSString * const accessKey = @"your_access_key";
static NSString * const privateKey = @"your_secret_key";
[ViSearchAPI setupAccessKey:accessKey andSecretKey:secretKey];
ViSearchClient *client = [ViSearch defaultClient];
client.isAppKeyEnabled = NO;
...
// OR using customized client, which connects to your own server
static NSString * const privateKey = @"your_url";
ViSearchClient *client = [[ViSearchClient alloc] initWithBaseUrl:url
appKey:appKey];
...
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViSearch viSearch = new ViSearch
.Builder("YOUR_APP_KEY")
.build(this);
viSearch.setListener(this);
...
}
...
}
// for China, please use
ViSearch viSearch = new ViSearch
.Builder(APP_KEY)
.setApiEndPoint("https://visearch.visenze.com.cn")
.build(context);
Once an application is created in ViSearch Dashboard system, a unique pair of access key and secret key will be assigned to this application. The key pair will be used to authenticate each API call.
We provide HTTP Basic Auth to authenticate the call to the ViSearch API. The access key and secret key are encoded into base64 string and append to the request header, which is easy to use but only suitable for API calls from the backend system.
HTTP Basic Auth
This authentication method is the standard HTTP Basic Auth. Use your access key as the basic auth username, and secret key as the basic auth password.
Error Codes
General error messages:
Message |
---|
Invalid access key or secret key. |
Unauthorized. |
Exceeds image collection size limit. |
System busy, please try again later. |
A system error is reported and we are fixing it right now. |
Data API Errors
Code | Message |
---|---|
101 | Transaction not found with trans_id. |
102 | Image not found with im_name. |
103 | Exceeded maximum insert batch size of 100. |
104 | No image inserted. |
105 | Number of parameters for image exceeds maximum limit of 32. |
106 | {parameter} exceeds length limit. |
107 | Invalid im_name. |
108 | Missing im_url. |
109 | {field} should be of data type {type}. |
201 | Could not download the image from im_url. |
202 | Unsupported image format. |
Search API Errors
Message | Remarks |
---|---|
The query image is still being processed, please try again later. | Depending on the number of images in your catalog, this process can take several minutes. |
Image not found with im_name. | Please check to ensure im_name is keyed in correctly; otherwise the image you are looking for has not been uploaded. |
Invalid image file format. | The supported image formats include: ..jpg, .jpeg, .jpe, .png, .gif, .bmp, .dib, .webp, .pbm, .pgm, .ppm, .sr, .ras, .tiff, .tif |
The image format or dimension is invalid. | Please have images with at least 100 pixels in any one direction and no larger than 40MP in size. |
Invalid image or im_url . |
The file or url you have supplied may not be an image. |
Could not download the image, please try again later. | Please check your image url and see if it’s accessible to the public. |
Timeout while downloading image, please try again later. | Your image size may have been too large; we recommend images around 1024x1024 pixels. |
App doesn’t have any images. | You can upload images via the dashboard or API. |
DATA INDEXING APIs
ViSearch Data APIs provide interfaces to manage your image collections. To add or update images, you call the Insert API with a list of images and their metadata. You can retrieve the image processing progress and errors occurred during the process by calling the Insert Status API. If you need to remove images, you can call the Remove API.
Insert Image
POST /insert
$ curl https://visearch.visenze.com/insert \
-d im_name[0]=example-0 \
-d im_url[0]=http://example.com/example-0.jpg \
-d brand[0]=my_brand \
-d price[0]=199 \
-d im_name[1]=example-1 \
-d im_url[1]=http://example.com/example-1.jpg \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/insert \
-d im_name[0]=example-0 \
-d im_url[0]=http://example.com/example-0.jpg \
-d brand[0]=my_brand \
-d price[0]=199 \
-d im_name[1]=example-1 \
-d im_url[1]=http://example.com/example-1.jpg \
-u access_key:secret_key
# example response JSON
{
"status": "OK",
"method": "insert",
"trans_id": 246806789063168000,
"total": 2,
"result": [],
"error": []
}
List<Image> images = new ArrayList<Image>();
String imName = "vintage_wingtips";
String imUrl = "http://mydomain.com/images/vintage_wingtips.jpg";
// add metadata to your image
Map<String, String> metadata = new HashMap<String, String>();
metadata.put("title", "Vintage Wingtips");
metadata.put("description", "A pair of high quality leather wingtips");
metadata.put("price", "100.0");
images.add(new Image(imName, imUrl, metadata));
client.insert(images);
images = [{
'im_name': 'blue_dress',
'im_url': 'http://mydomain.com/images/blue_dress.jpg',
'title': 'Blue Dress',
'description': 'A blue dress',
'price': 100.0
},
...
]
# calls the /insert endpoint to index the image
response = api.insert(images)
$images[] = array('im_name'=>'blue_dress',
'im_url'=>'http://mydomain.com/images/blue_dress.jpg',
'title'=>'Blue Dress',
'description'=>'A blue dress',
'price'=> 100.0f);
// calls the /insert endpoint to index the image
$response = $service->insert($images);
This API is for adding or updating images to your image collections.
request parameters
The request parameters for the images must be in the following format:
{key}[index]=value
where key is the im_name
, im_url
, or metadata field name, and index is the 0 based integer index of the images.
There are several limits on the parameters and images:
- The maximum number of keys for an image is 32.
- The maximum length of im_name is 128.
- The maximum length for each of the values is 5000.
- The maximum number of images to insert for each call is 100.
- For optimal results, we recommend images with at least 100 pixels in both dimensions and larger than 800x800 pixels.
- The maximum image resolution is 40 Megapixels (height * width <= 40 Megapixels).
- The supported image formats includes: .jpg, .jpeg, .jpe, .png, .gif, .bmp, .dib, .webp, .pbm, .pgm, .ppm, .sr, .ras, .tiff, .tif
name | example | description |
---|---|---|
im_name required | im_name[0]=example-0 im_name[1]=example-1 | A unique image name used as an identifier in the App image collection. Valid characters are [a-z], [A-Z], [0-9], [-], [_], [.], and [:]. If an image with the same name exists in the image collection, the image will be updated. |
im_url required | im_url[0]=http://example.com/example-0.jpg im_url[1]=http://example.com/example-1.jpg | The image url that correspond to the image name. The image will be downloaded to our server to process. |
[metadata fields] | brand[0]=my_brand price[0]=199 | Metadata fields for the image. |
Check Insert Status
GET /insert/status/{trans_id}
$ curl https://visearch.visenze.com/insert/status/29031939452 \
-u access_key:secret_key \
# for China, please use
$ curl https://visearch.visenze.com.cn/insert/status/29031939452 \
-u access_key:secret_key \
# example response json:
{
"status": "OK",
"method": "insert/status",
"result": [
{
"trans_id": 29031939452,
"processed_percent": 100,
"success_count": 1,
"fail_count": 3,
"total": 4,
"error_list": [
{
"im_name": "image_1",
"error_code": 201,
"error_message": "Could not download the image from im_url."
},
{
"im_name": "image_2",
"error_code": 202,
"error_message": "Unsupported image format."
},
{
"im_name": "image_3",
"error_code": 203,
"error_message": "Unsupported image dimension."
}
],
"error_page": 1,
"error_limit": 10
}
],
"error": []
}
List<Image> images = new ArrayList<Image>();
String imName = "vintage_wingtips";
String imUrl = "http://mydomain.com/images/vintage_wingtips.jpg";
images.add(new Image(imName, imUrl));
// index the image and get the InsertTrans
InsertTrans trans = client.insert(images);
InsertStatus status;
// check the status of indexing process while it is not complete
int percent = 0;
while (percent < 100) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
status = client.insertStatus(trans.getTransId());
percent = status.getProcessedPercent();
System.out.println(percent + "% complete");
}
int pageIndex = 1; // error page index always starts with 1
int errorPerPage = 10; // set error page limit
status = client.insertStatus(trans.getTransId(), pageIndex, errorPerPage);
System.out.println("Start time:" + status.getStartTime());
System.out.println("Update time:" + status.getUpdateTime());
System.out.println(status.getTotal() + " insertions with "
+ status.getSuccessCount() + " succeed and "
+ status.getFailCount() + " fail");
// print all the error messages if there are any
if (status.getFailCount() > 0) {
int totPageNumber = (int) Math.ceil(1.0 * status.getFailCount() / status.getErrorLimit());
for (pageIndex = 1; pageIndex <= totPageNumber; pageIndex++) {
status = client.insertStatus(trans.getTransId(), pageIndex, errorPerPage);
List<InsertError> errorList = status.getErrorList();
for (int errorIndex = 0; errorIndex < errorList.size(); errorIndex++) {
System.out.println("failure at page " + pageIndex
+ " with error message: " + errorList.get(errorIndex));
}
}
}
import time
import math
# the list of images to be indexed
# the unique identifier of the image 'im_name', the publicly downloadable url of the image 'im_url'
images = [
{'im_name': 'pic5', 'im_url': 'http://mydomain.com/images/vintage_wingtips.jpg'},
]
response = api.insert(images)
trans_id = response['trans_id']
percent = 0
while (percent < 100):
time.sleep(1)
status_response = api.insert_status(trans_id)
if 'result' in status_response and len(status_response['result']) > 0:
percent = status_response['result'][0]['processed_percent']
print '{}% complete'.format(percent)
page_index = 1
error_per_page = 10
fail_count = None
status_response = api.insert_status(trans_id, page_index, error_per_page)
if 'result' in status_response and len(status_response['result']) > 0:
result_data = status_response['result'][0]
print result_data
fail_count = result_data['fail_count']
print 'Start time: {}'.format(result_data['start_time'])
print 'Update time: {}'.format(result_data['update_time'])
print "{} insertions with {} succeed and {} fail".format(
result_data['total'],
result_data['success_count'],
result_data['fail_count']
)
if fail_count > 0:
result_data = status_response['result'][0]
error_limit = result_data['error_limit']
total_page_number = int(math.ceil(float(fail_count) / error_limit))
for i in range(total_page_number):
page_index = i + 1
status_response = api.insert_status(trans_id, page_index, error_per_page)
error_list = status_response['result'][0]['error_list']
for error in error_list:
print "failure at page {} with error message {}".format(
page_index,
error)
Retrieve image processing status for an insert transaction. You can find the trans_id
for an insert transaction in the response of the insert call.
request parameters
If there are failed images in the insert transaction, you can paginate the errors by providing the following parameters:
name | type | description |
---|---|---|
error_page | integer | Specifies the page of error info to be returned. |
error_limit | integer | Specifies the number of error info per page to be returned. |
response properties
name | description |
---|---|
trans_id | The transaction id. |
processed_percent | Rounded percentage value of the amount of processed images over the total number of images. |
success_count | Number of image inserted successfully. |
fail_count | Number of image failed to insert. |
total | Total number of images in the transaction. |
error_list | The list of error encountered when processing the images in the transaction. |
error_page | The page of error info. |
error_limit | The number of error info per page. |
Remove Image
POST /remove
$ curl https://visearch.visenze.com/remove \
-d im_name[0]=example-0 \
-d im_name[1]=example-1 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/remove \
-d im_name[0]=example-0 \
-d im_name[1]=example-1 \
-u access_key:secret_key
# example response JSON
{
"status": "OK",
"method": "remove",
"total": 2,
"result": [
],
"error": []
}
// the list of unique identifiers 'im_name' of the images to be removed
List<String> removeList = new ArrayList<String>();
// removing previously indexed image "red_dress"
removeList.add("red_dress");
client.remove(removeList);
image_names = ["red_dress", "blue_dress"]
response = api.remove(image_names)
$response = $service->remove(array("red_dress","blue_dress"));
This API is for removing images from the image collection. Please allow 5 mins for the process that removes images from the indexed database.
request parameters
name | example | description |
---|---|---|
im_name required | im_name[0]=example-0 im_name[1]=example-1 | The image names for the images to be removed. |
SOLUTION APIs
ViSenze provides APIs for four types of solutions:
Visually Similar Recommendations
Visually Similar Recommendations solution is to search against your image collection using an existing image in the collection.Search by Image
Search by image solution is to search for similar images in the image database by uploading an image or providing an image url. The solution can detect the primary object in the uploaded image and search it against image database. Alternatively, the user can specify a bounding box as an API request parameter to search for the bounded object.Multiple Product Search
Multiple Product Search solution is to detect multiple objects in the uploaded image, and search for their respective similar images in the image database. The API response will return the search results for each detected object.Search by Color
Search by color solution is to search for images with similar color by providing color codes. The color code should be in Hexadecimal and passed to the color search service.
Visually Similar Recommendations
GET /search
$ curl https://visearch.visenze.com/search?im_name=example-0 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/search?im_name=example-0 \
-u access_key:secret_key
SearchParams params = new SearchParams("vintage_wingtips");
PagedSearchResult searchResult = client.search(params);
response = api.search("blue_dress")
$service = new ViSearch($access_key,$secret_key);
$service->search("blue_dress");
#import <ViSearch/VisearchAPI.h>
...
SearchParams *searchParams = [[SearchParams alloc] init];
searchParams.imName = @"imName-example";
[[ViSearchAPI defaultClient]
searchWithImageId:searchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
IdSearchParams idSearchParams = new IdSearchParams("dress_1");
viSearch.idSearch(idSearchParams);
visearch.search({
im_name: 'your-image-name',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
This API is for searching against your image collection using an existing image in the collection.
request parameters
name | example | description |
---|---|---|
im_name required | im_name=example_name | The image name of the image to search against the image collection. |
page | page=1 | The result page number. Default value is 1. |
limit | limit=10 | The number of results per page. Default value is 10. The maximum number of results returned from the API is 1000. |
[advanced parameters] | Check out even more powerful advanced parameters. |
# example response JSON
{
"status": "OK",
"method": "search",
"error": [],
"page": 1,
"limit": 10,
"total": 1000,
"result": [
{
"im_name": example_image_name,
}, ...
],
"reqid": example_reqid
}
Search by Image
POST /uploadsearch
Searching an uploaded image file
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-u access_key:secret_key
File imageFile = new File("/path/to/your/image");
UploadSearchParams params = new UploadSearchParams(imageFile);
PagedSearchResult searchResult = client.uploadSearch(params);
$image = new Image(imagePath);
$response = $service->uploadsearch($image);
image_path = 'blue_dress.jpg'
response = api.uploadsearch(image_path=image_path)
visearch.uploadsearch({
image: inputImageFile,
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
#import <ViSearch/VisearchAPI.h>
...
UIImage *image = [UIImage imageNamed:@"example.jpg"];
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.imageFile = image
[[ViSearchAPI defaultClient]
searchWithImageData:uploadSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
// Using an image from a local file path:
Image image = new Image("/local/path/to/image.jpg");
UploadSearchParams uploadSearchParams.setImage(image);
viSearch.uploadSearch(uploadSearchParams);
// Using an image by providing the Uri of the image in photo gallery:
Image image = new Image(context, uri);
UploadSearchParams uploadSearchParams = new UploadSearchParams(image);
viSearcher.uploadSearch(uploadSearchParams);
// Construct the `image` from the byte array returned
// by the camera preview callback:
@Override
public void onPictureTaken(byte[] bytes, Camera camera) {
Image image = new Image(bytes);
UploadSearchParams uploadSearchParams = new UploadSearchParams(image);
viSearcher.uploadSearch(uploadSearchParams);
}
Searching a publicly accessible image URL
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-u access_key:secret_key
String url = "http://mydomain.com/sample_image.jpg";
UploadSearchParams params = new UploadSearchParams(url);
PagedSearchResult searchResult = client.uploadSearch(params);
image_url = 'http://mydomain.com/images/red_dress.jpg'
response = api.uploadsearch(image_url=image_url)
$image = new Image('http://mydomain.com/images/red_dress.jpg');
$response = $service->uploadsearch($image);
visearch.uploadsearch({
im_url: 'your-image-url',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
#import <ViSearch/VisearchAPI.h>
...
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.imageUrl = @"http://example.com/example.jpg";
[[ViSearchAPI defaultClient]
searchWithImageUrl:uploadSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
String url = "http://mydomain.com/sample_image.jpg";
UploadSearchParams uploadSearchParams = new UploadSearchParams(url);
viSearcher.uploadSearch(uploadSearchParams);
Searching with im_id that can be retrieved from the previous uploadsearch response.
$ curl https://visearch.visenze.com/uploadsearch \
-d im_id=example_image_id \
-d box=0,0,20,20 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_id=example_image_id \
-d box=0,0,20,20 \
-u access_key:secret_key
//get imid from previous request
String imId = prevSearchResult.getImId();
UploadSearchParams params = new UploadSearchParams(imId);
PagedSearchResult searchResult = client.uploadSearch(params);
// Get imid from previous request
$imid = $response->im_id;
// Searching using im_id
$newimage->setfilepath(imagepath);
$newimage = new Image();
$newimage->setimid($imid);
$response = $service->uploadsearch($new_image);
// Searching using im_id
#import <ViSearch/VisearchAPI.h>
...
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.imId = visearchResult.imId;
[[ViSearchAPI defaultClient]
searchWithImage:uploadSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
// Searching using im_id
String imId;
@Override
public void onSearchResult(ResultList resultList) {
imId = resultList.getImId();
for (ImageResult imageResult : resultList.getImageList()) {
//Do something with the result
...
}
}
UploadSearchParams uploadSearchParams = new UploadSearchParams();
uploadSearchParams.setImId(imId);
viSearcher.uploadSearch(uploadSearchParams);
This API is for searching for similar images in the image database by uploading an image or providing an image url. The solution can detect the primary object in the uploaded image and search it against image database. Alternatively, the user can specify a bounding box as an API request parameter to search for the bounded object.
There are some limitations on the request and the image:
- The request must be made with Content-Type: multipart/form-data.
- For optimal results, we recommend images around
1024x1024
pixels. Low resolution images may result in unsatisfying search results. - If the image is larger, we recommended to resize the image to
1024x1024
pixels before sending to API. Too high resolution images may result in timeout. - The maximum file size of an image is 10MB.
request parameters
name | example | description |
---|---|---|
im_url | im_url=http://example.com/example.jpg | The url for the image to be downloaded and searched against the image collection. Image file or im_url or im_id must be provided. |
im_id | im_id=example_image_id | For each uploaded image ViSearch service will return an unique im_id which can be used to do further search without downloading the image again. Image file or im_url or im_id must be provided. |
image | (image file object) | The image file object that will be searched against the image collection. Image file or im_url or im_id must be provided. |
box | box=0,0,20,20 | Optional parameter for restricting the image area x1,y1,x2,y2. The upper-left corner of an image is (0,0). |
page | page=1 | The result page number. Default value is 1. |
limit | limit=10 | The number of results per page. Default value is 10. The maximum number of results returned from the API is 1000. |
[advanced parameters] | Check out even more powerful advanced parameters. |
For each uploaded image ViSearch service will return an unique im_id
which can be used to do further uploadsearch without downloading the image again. If you need to do several upload searches using one same image, this is recommended to save the bandwidth and improve the overall speed.
response properties
# example response JSON
{
"status":"OK",
"method":"uploadsearch",
"error":[],
"page":1,
"limit":10,
"total":1000,
"product_types":[
{
"type": "top",
"attributes": {},
"score": 0.9955333471298218,
"box": [
75,
133,
303,
388
]
}, ...
],
"product_types_list": [
...
],
"result": [
{
"im_name": example_image_name,
}, ...
],
"im_id": example_image_id,
"reqid": example_reqid
}
name | description |
---|---|
status | The request status, either “OK”, “warning”, or “fail”. |
method | the request method. |
error | The list of error if the request was not successful i.e. when status is “warning” or “fail”. |
page | The result page number. |
limit | The number of results per page. |
total | The total number of result. |
product_types | The list of objects detected. |
product_types_list | The product_types_list contains the complete list of object types supported for detection for this app. |
result | The list of result objects if the request was successful, i.e. when status is “OK”. |
im_id | The unique ID for uploaded image. |
reqid | The unique request id of the api call. |
Multiple Product Search
POST /discoversearch
$ curl https://visearch.visenze.com/discoversearch \
-d im_url=http://example.com/example-0.jpg \
-d detection=all \
-d detection_limit=5 \
-d result_limit=10 \
-d score=true \
-d “fl=im_url” \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/discoversearch \
-d im_url=http://example.com/example-0.jpg \
-d detection=all \
-d detection_limit=5 \
-d result_limit=10 \
-d score=true \
-d “fl=im_url” \
-u access_key:secret_key
// Using an image from a local file path
File imageFile = new File("/path/to/your/image");
UploadSearchParams params = new UploadSearchParams(imageFile);
PagedSearchResult searchResult = client.discoverSearch(params);
// Using image url
String url = "http://mydomain.com/sample_image.jpg";
UploadSearchParams params = new UploadSearchParams(url);
PagedSearchResult searchResult = client.discoverSearch(params);
response = api.discoversearch(im_url='http://www.test.com/test.jpg', detection='all', detection_limit=3, result_limit=10, detection_sensitivity='high', box=(0, 0, 10, 10))
// Searching an uploaded image file
visearch.discoversearch({
image: inputImageFile,
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
// Searching a publicly accessible image URL
visearch.discoversearch({
im_url: 'your-image-url',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
#import <ViSearch/VisearchAPI.h>
...
UIImage *image = [UIImage imageNamed:@"example.jpg"];
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.imageFile = image
[[ViSearchAPI defaultClient]
discoverSearchWithImageData:uploadSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
#import <ViSearch/VisearchAPI.h>
...
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.imageUrl = @"http://example.com/example.jpg";
[[ViSearchAPI defaultClient]
discoverSearchWithImageUrl:uploadSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
This API is for detecting multiple objects in the uploaded image, and search for their respective similar images in the image database. The API response will return the search results for each detected object.
There are some limitations on the request and the image:
- The request must be made with Content-Type: multipart/form-data.
- For optimal results, we recommend images around
1024x1024
pixels. Low resolution images may result in unsatisfying search results. - If the image is larger, we recommended to resize the image to
1024x1024
pixels before sending to API. Too high resolution images may result in timeout. - The maximum file size of an image is 10MB.
request parameters
name | example | description |
---|---|---|
im_url | im_url=http://example.com/example.jpg | The url for the image to be downloaded and searched against the image database. User must input one of the following: image file, im_url or im_id . |
im_id | im_id=example_image_id | For each uploaded image ViSearch service will return an unique im_id which can be used to do further search without downloading the image again. User must input one of the following: image file, im_url or im_id . |
image | (image file object) | The image file object that will be searched against the image database. User must input one of the following: image file, im_url or im_id . |
detection | detection = eyewear | Selects the type of objects to be recognized in the query image, can be used in following ways:
|
detection_limit | detection_limit = 3 | Maximum number of products could be detected for a given image; default value is 5. Values must range between 1-30. Returns the objects with higher confidence score first. |
detection_sensitivity | detection_sensitivity = low / detection_sensitivity = high | Parameter to set the detection to more or less sensitive. Default is low.
|
box | box=0,0,20,20 | Optional parameter for restricting the image area x1,y1,x2,y2. Once this is passed in the parameter, only the area within bounding box will be analyzed. |
point | point=15,40 | Pixel coordinates to indicate the position of the target object [x,y]. The upper-left corner of an image is [0,0]. Stack inputs for multiple points up to 5 values as default. box and point parameters are not allowed to appear in the same request. detection_limit is ignored when point exists. |
page | page=1 | The result page number. Default value is 1. |
result_limit | result_limit = 10 | The number of results returned per page for each product; default value is 10. Values must range between 1-1000. |
[advanced parameters] | Check out even more powerful advanced parameters. |
response properties
# example response JSON
{
"status": "OK",
"method": "discoversearch",
"error": [],
"result_limit": 10,
"detection_limit": 5,
"page": 1,
"objects": [
{
"type": "top",
"attributes": {},
"score": 0.9919997453689575,
"box": [
234,
263,
634,
706
],
"total": 100,
"result": [
{
"im_name": example_image_name-0,
}, ...
]
},
{
"type": "bottom",
"attributes": {},
"score": 0.7576414883136749,
"box": [
252,
657,
689,
1099
],
"total": 100,
"result": [
{
"im_name": example_image_name-1,
}, ...
]
}
],
"object_types_list": [
{
"type": "top",
"attributes_list": {
"gender": [
"men",
"women"
]
}
},
{
"type": "bottom",
"attributes_list": {
"gender": [
"men",
"women"
]
}
}
],
"im_id": example_image_id,
"reqid": example_reqid
}
name | description |
---|---|
status | The request status, either “OK”, “warning”, or “fail”. |
method | The request method. |
error | The list of error if the request was not successful i.e. when status is “warning” or “fail”. |
result_limit | The number of results returned per page for each product. Default value is 10. |
detection_limit | Maximum number of products could be detected for a given image. Default value is 5. |
page | The result page number. |
objects | The objects is structured in the way that it contains all objects detected in the given image, including the object type, the confidence score, as well as the box coordinates of the objects. Under each object, the total number of search results will be returned, and the im_name and score of the search results will be returned. |
object_type_list | The object_type_list contains the complete list of object types supported for detection for this app. |
Search by Color
GET /colorsearch
$ curl https://visearch.visenze.com/colorsearch?color=012ACF:40&color=19668f:60 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/colorsearch?color=012ACF:40&color=19668f:60 \
-u access_key:secret_key
ColorSearchParams.ColorAndWeight colorAndWeight1 = new ColorSearchParams.ColorAndWeight("000000", 50);
ColorSearchParams.ColorAndWeight colorAndWeight2 = new ColorSearchParams.ColorAndWeight("ffffff", 50);
ColorSearchParams params = new ColorSearchParams(Lists.newArrayList(colorAndWeight1, colorAndWeight2));
PagedSearchResult searchResult = client.colorSearch(params);
visearch.colorsearch({
color: ['fa4d4d:30','3f48cc:70'],
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
response = api.colorsearch("fa4d4d")
$service->colorsearch("fa4d4d");
ColorSearchParams colorSearchParams = new ColorSearchParams("9b351b");
viSearch.colorSearch(colorSearchParams);
#import <ViSearch/VisearchAPI.h>
...
ColorSearchParams *colorSearchParams = [[ColorSearchParams alloc] init];
colorSearchParams.color = @"012ACF";
[[ViSearchAPI defaultClient]
searchWithColor:colorSearchParams
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request succeeds
} failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Do something when request fails
}];
...
This API is for searching for images matching to the colors in your image collection. The API accepts multiple colors inputs and relative ratios.
The API supports up to 5 colors inputs by default. This number of colors input limit is customisable by ViSenze.
request parameters
name | example | description |
---|---|---|
color required | color=012ACF:33 color=012ACF |
6 digit color hex codes with relative ratios. Ratios must be integers ranging from 1 to 100. If no ratio input for all the color hex, treat as equal ratios. |
page | page=1 | The result page number. Default value is 1. |
limit | limit=10 | The number of results per page. Default value is 10. The maximum number of results returned from the API is 1000. |
[advanced parameters] | Check out even more powerful advanced parameters. |
# example response JSON
{
"status": "OK",
"method": "colorsearch",
"error": [],
"page": 1,
"limit": 10,
"total": 1000,
"result": [
{
"Im_name":"image-name-1",
},
{
"Im_name":"image-name-2",
}, ...
],
"reqid": example_reqid
}
ADVANCED PARAMETERS
ViSearch API is even more powerful with advanced parameter configuration. The table summarizes the optional parameters that are common for all the search APIs. The usages of the parameters are explained in detail in the following sections.
name | example | description |
---|---|---|
detection | detection=all | Turn on automatic object detection so the algorithm will try to detect the object in the image and search. detection is not supported for /search or /colorsearch |
fq | fq=brand:my_brand&fq=price:0,199 | The metadata fields to filter the results. Only fields marked with ‘searchable’ in ViSearch Dashboard can be used as filters. If the filter field is not in data schema, it will be ignored. Text fields can only be ‘searchable’. |
fl | fl=brand&fl=price | The metadata fields to be returned. If the query value is not in data schema, it will be ignored. Text fields are not applicable for fl fetch. |
get_all_fl | get_all_fl=true | If set true, return metadata for all the fields applicable for fl fetch. Default value is false. |
score | score=true | If the value is true, the score for each image result will be included in the response. |
score_min | score_min=0.5 | Sets the minimum score threshold for the search. The value must be between 0.0 to 1.0 inclusively, or an error will be returned. Default value is 0.0. |
score_max | score_max=0.8 | Sets the maximum score threshold for the search. The value must be between 0.0 to 1.0 inclusively, or an error will be returned. Default value is 1.0. |
dedup | dedup=false | Parameter to turn on remove similar image results function. Default is false. |
dedup_score_threshold | dedup_score_threshold=0.5 | Sets the minimum gap between adjacent results. Only works when dedup=true. Default is 0.0. |
facets | facets = color,brand,price | List of fields to enable faceting. |
facets_limit | facet_limit = 10 | Limit of the number of facet values to be returned. Only for non-numerical fields. Default value is 10. |
facets_show_count | facets_show_count = true | Option to show the facets count in the response. Item counts are based on the top 1000 results. |
group_by | group_by=category | The metadata field used to group the search results. Only fields marked with ‘searchable’ in ViSearch Dashboard can be used as group_by field. group_by is not supported for /discoversearch . |
group_limit | group_limit = 10 (default) | Limit of the number of groups displayed per page. The maximum value is 100. |
sort_by | sort_by=price:desc | The metadata field used to sort the search results per page. Ascending or descending order needs to be specified. |
qinfo | qinfo=true | If true, query information will be returned. |
Automatic Object Detection
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-d detection=all \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-d detection=all \
-u access_key:secret_key
# example of json response
{
"status":"OK",
"method":"uploadsearch",
"error":[
],
"page":1,
"limit":30,
"total":1000,
"product_types":[
{
"type":"top",
"attributes":{},
"score":1,
"box":[
574,
826,
1693,
2171
]
}
],
"product_types_list":[
{
"type": "bag",
"attributes_list": {}
},
{
"type": "bottom",
"attributes_list": {}
},
{
"type": "dress",
"attributes_list": {}
},
...
],
"result":[
{
"im_name":"image-name-1",
},
{
"im_name":"image-name-2",
}
]
}
String url = "http://mydomain.com/sample_image.jpg";
UploadSearchParams params = new UploadSearchParams(url);
params.setDetection("all");
PagedSearchResult searchResult = client.uploadSearch(params);
param = {'detection': 'all'}
response = api.uploadsearch(image_url=image_url, **param)
$detection = 'all';
$response = $service->uploadsearch($image, $page, $limit, $fl, $fq, $get_all_fl,
$score, $score_max, $score_min, $detection);
params.detection = @"all";
uploadSearchParams.setDetection("all");
visearch.uploadsearch({
im_url: 'your-image-url',
score: 'true',
detection: 'all',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
With Automatic Object Recognition, ViSearch /uploadsearch
and /discoversearch
API are smart to detect the objects present in the query image and suggest the best matched product type to run the search on. /discoversearch
API supports a point
parameter to indicate the position of the target object by [x,y] coordinates.
We are now able to detect various types of products. Based on the domain of your application, the below sets of objects can be detected respectively:
- Fashion domain: Top, Dress, Bottom, Shoe, Bag, Watch, Furniture, Eyewear, Jewlery, Outerwear, Skirt and Indian Ethnic Wear.
- Furniture domain: Bed, Clock, Floating Shelf, Lighting, Mirror, Photo Frame, Seating, Soft Furnishing, Standing Lamp, Storage, Table, Vase and Pot, Shelf and Cabinet.
You can use the Box parameter to restrict the image area [x1,y1,x2,y2] as the portion of your image to search for. When you input a box with 0 width and 0 height, eg. “box”:[574,224,574,224]. We will treat it as a point and detect the object over the current point.
Automatic object recognition based on user input point:
set detection type as ‘bag’
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d detection=bag \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d detection=bag \
-u access_key:secret_key
String url = "http://mydomain.com/sample_image.jpg";
UploadSearchParams params = new UploadSearchParams(url);
params.setDetection("bag");
PagedSearchResult searchResult = client.uploadSearch(params);
param = {'detection': 'bag'}
response = api.uploadsearch(image_url=image_url, **param)
$detection = 'bag';
$response = $service->uploadsearch($image, $page, $limit, $fl, $fq, $get_all_fl,
$score, $score_max, $score_min, $detection);
uploadSearchParams.setDetection("bag");
params.detection = @"bag";
visearch.uploadsearch({
im_url: 'your-image-url',
score: 'true',
detection: 'bag',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
You could also recognize objects from a particular type on the uploaded query image through configuring the detection parameter to a specific product type as detection={type}
. Our API will run the search within that product type.
To obtain the full list for your application, simply make an uploadsearch or discoversearch API call and get from the {product_types_list} in the response.
Sample request to detect bag
in an uploaded image:
Selection Box
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-u access_key:secret_key
File imageFile = new File("/path/to/your/image");
UploadSearchParams params = new UploadSearchParams(imageFile);
// create the box to refine the area on the searching image
// Box(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.
Box box = new Box(50, 50, 200, 200);
params.setBox(box);
PagedSearchResult searchResult = client.uploadSearch(params);
$image = new Image(imagePath);
// create the box to refine the area on the searching image
// Box(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.
$box = new Box(0,0,10,10);
$image->set_box($box);
image_url = 'http://mydomain.com/images/red_dress.jpg'
box = (0,0,10,10)
response = api.uploadsearch(image_url=image_url, box=box)
// create the box to refine the area on the searching image
// Box(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.
...
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
Box *box = [[Box alloc]initWithX1:0 y1:0 x2:100 y2:100];
uploadSearchParams.box = box;
// start searching
...
// if you are uploading an local image
Image image = new Image(this, uri);
// create the box to refine the area on the searching image
// Box(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.
image.setBox(0, 0, 400, 400);
// if you are using im_url or im_id for upload search
// you should pass the box in this way
UploadSearchParams uploadSearchParams = new UploadSearchParams();
uploadSearchParams.setImId(imId);
uploadSearchParams.setBox(new Box(0, 0, 400, 400));
viSearcher.uploadSearch(uploadSearchParams);
visearch.uploadsearch({
im_url: 'your-image-url',
// The box format is [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
// - (x2, y2) is the bottom-right corner of the box
// IMPORTANT: Do not put space before/after any comma in the box coordinates
box: 'x1,y1,x2,y2',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
If the object you wish to search for takes up only a small portion of your image, or if other irrelevant objects exists in the same image, chances are the search result could become inaccurate. Use the Box parameter to refine the search area of the image to improve accuracy. The box coordinates are set with respect to the original size of the uploading image. For box parameters given in the sequences as x1, y1, x2, y2, (x1, y1) is the top-left corner of the box and (x2, y2) is the bottom-right corner of the box.
Filtering Results
To filter search results based on metadata values, provide a map of metadata key to filter value in the fq
(filter query) property:
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=brand \
-d fl=price \
-d fq=brand:my_brand \
-d fq=price:199 \
-d score=true \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=brand \
-d fl=price \
-d fq=brand:my_brand \
-d fq=price:199 \
-d score=true \
-u access_key:secret_key
# example of json response
{
"status":"OK",
"method":"uploadsearch",
"im_id":"example_image_id",
"error":[
],
"page":1,
"limit":10,
"total":1000,
"result":[
{
"im_name":"image-name-1",
"value_map":{
"brand":"my_brand",
"price":"199"
}
},
{
"im_name":"image-name-2",
"value_map":{
"brand":"my_brand",
"price":"199"
}
},
...
]
}
SearchParams params = new SearchParams("vintage_wingtips");
// add fq param to specify the filtering criteria
Map<String, String> fq = new HashMap<String, String>();
// description is metadata type text
fq.put("description", "wingtips");
// price is metadata type float
fq.put("price", "0,199");
params.setFq(fq);
PagedSearchResult searchResult = client.search(params);
fq = {"im_cate": "bags", "price": "10,199"}
response = api.uploadsearch(image_url=image_url, fq=fq)
$fq = array("im_cate" => "bags");
$response = $service->uploadsearch($image, $page, $limit, $fl, $fq);
// add fq param to specify the filtering criteria
Map<String, String> fq = new HashMap<String, String>();
// description is metadata type text
fq.put("description", "wingtips");
// price is metadata type float
fq.put("price", "0,199");
baseSearchParams.setFq(fq);
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
// the type of "count" on db schema is int,
// so we can specify the value range, or do a value match
[uploadSearchParams.fq setObject:@"0,199" forKey:@"count"];
[uploadSearchParams.fq setObject:@"199" forKey:@"count"];
// the type of "price" on db schema is float,
// so we can specify the value range, or do a value match
[uploadSearchParams.fq setObject:@"0.0,199.0" forKey:@"price"];
[uploadSearchParams.fq setObject:@"15.0" forKey:@"price"];
// the type of "description" on db schema is string, so we can do a string match.
[uploadSearchParams.fq setObject:@"wooden" forKey:@"description"];
// start searching
...
var filterQuery = ['description:bag', 'brand:brandA'];
visearch.uploadsearch({
im_url: 'your-image-url',
fq: filterQuery,
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
Type | Explanation |
---|---|
string | Metadata value must be either
|
int | Metadata value can be either:
|
float | Metadata value can be either
|
text | Query text field with partial matching and operators. Explained in detail in the following section*
|
Query Syntax for Text Field *
ViSearch supports querying text fields with partial matching and operators. The commonly used operators are: AND
, OR
, and NOT
. It is case insensitive in any case.
Delimiter
The delimiter will not be used for matching, but to separate the text phrases and concatenate the phrases with the operator to form the query value.
For example, both queries below have the same performance as the query fq=tag:a AND b
:
fq=tag:a b
fq=tag:a,b
The accepted field delimiter:
Type | Accepted Delimier |
---|---|
Latin language | [.,?~!@#$%^&*(-+=_`‘\“:;<>/]), space and newlilnes. |
non-Latin language | unicode delimiters*, including white spaces, English and CJK punctuations. |
The full list of unicode delimiter:
Delimiter | Explanation | Codepoint |
---|---|---|
whitespace: tab (\t) | U+0009 | |
whitespace newline (\n) | U+000A | |
whitespace: form feed (\f) | U+000C | |
whitespace: carriage return (\r) | U+000D | |
whitespace: space | U+0020 | |
! | ascii: exclamation mark | U+0021 |
” | ascii: double quotes | U+0022 |
# | ascii: number sign | U+0023 |
$ | ascii: dollar sign | U+0024 |
% | ascii: percent sign | U+0025 |
& | ascii: ampersand | U+0026 |
’ | ascii: single quote | U+0027 |
( | ascii: open bracket | U+0028 |
) | ascii: close bracket | U+0029 |
* | ascii: asterisk | U+002A |
+ | ascii: plus | U+002B |
, | ascii: comma | U+002C |
- | ascii: hyphen | U+002D |
. | ascii: dot | U+002E |
/ | ascii: slash | U+002F |
: | ascii: colon | U+003A |
; | ascii: semicolon | U+003B |
< | ascii: less than | U+003C |
= | ascii: equals | U+003D |
> | ascii: greater than | U+003E |
? | ascii: question mark | U+003F |
@ | ascii: at symbol | U+0040 |
[ | ascii: open square bracket | U+005B |
\ | ascii: backslash | U+005C |
] | ascii: close square bracket | U+005D |
^ | ascii: caret | U+005E |
_ | ascii: underscore | U+005F |
` | ascii: grave accent | U+0060 |
{ | ascii: open curly bracket | U+007B |
| | ascii: vertical bar | U+007C |
} | ascii: close curly bracket | U+007D |
~ | ascii: tilde | U+007E |
¡ | latin: inverted exclamation mark | U+00A1 |
¦ | latin: broken bar | U+00A6 |
« | latin: open double angle quotations | U+00AB |
latin: soft hyphen | U+00AD | |
¯ | latin: macron | U+00AF |
´ | latin: acute accent | U+00B4 |
¸ | latin: cedilla | U+00B8 |
» | latin: close double angle quotations | U+00B8 |
¿ | latin: inverted question mark | U+00BF |
ˇ | modifier: caron | U+02C7 |
ˉ | modifier: macron | U+02C9 |
ˊ | modifier: acute accent | U+02CA |
ˋ | modifier: grave accent | U+02CB |
˜ | modifier: small tilde | U+02DC |
‐ | punctuation: hyphen | U+2010 |
— | punctuation: dash | U+2014 |
― | punctuation: horizontal bar | U+2015 |
‖ | punctuation: double vertical bar | U+2016 |
‘ | punctuation: left single quotation | U+2018 |
’ | punctuation: right single quotation | U+2019 |
“ | punctuation: left double quotation | U+201C |
” | punctuation: right double quotation | U+201D |
• | punctuation: bullet | U+2022 |
… | punctuation: ellipsis | U+2026 |
‹ | punctuation: single left angle quotation | U+2039 |
› | punctuation: single right angle quotation | U+203A |
∕ | maths: division | U+2215 |
CJK: space | U+3000 | |
、 | CJK: comma | U+3001 |
。 | CJK: full stop (period) | U+3002 |
〈 | CJK: left angle bracket | U+3008 |
〉 | CJK: right angle bracket | U+3009 |
《 | CJK: left double angle bracket | U+300A |
》 | CJK: right double angle bracket | U+300B |
「 | CJK: left corner bracket | U+300C |
」 | CJK: right corner bracket | U+300D |
『 | CJK: left white corner bracket | U+300E |
』 | CJK: right white corner bracket | U+300F |
【 | CJK: left black lenticular bracket | U+3010 |
】 | CJK: right black lenticular bracket | U+3011 |
〔 | CJK: left tortoise shell bracket | U+3014 |
〕 | CJK: right tortoise shell bracket | U+3015 |
〖 | CJK: left white lenticular bracket | U+3016 |
〗 | CJK: right white lenticular bracket | U+3017 |
〝 | CJK: reversed double prime quotations | U+301D |
〞 | CJK: double prime quotations | U+301E |
・ | CJK: katakana middle dot | U+30FB |
︰ | CJK: vertical two dot leader | U+FE30 |
︳ | CJK: vertical low line | U+FE33 |
︴ | CJK: vertical wavy low line | U+FE34 |
︵ | CJK: vertical left bracket | U+FE35 |
︶ | CJK: vertical right bracket | U+FE36 |
︷ | CJK: vertical left curly bracket | U+FE37 |
︸ | CJK: vertical right curly bracket | U+FE38 |
︹ | CJK: vertical left tortoise shell bracket | U+FE39 |
︺ | CJK: vertical right tortoise shell bracket | U+FE3A |
︻ | CJK: vertical left black lenticular bracket | U+FE3B |
︼ | CJK: vertical right black lenticular bracket | U+FE3C |
︽ | CJK: vertical left double angle bracket | U+FE3D |
︾ | CJK: vertical right double angle bracket | U+FE3E |
︿ | CJK: vertical left angle bracket | U+FE3F |
﹀ | CJK: vertical right angle bracket | U+FE40 |
﹁ | CJK: vertical left corner bracket | U+FE41 |
﹂ | CJK: vertical right corner bracket | U+FE42 |
﹃ | CJK: vertical left white corner bracket | U+FE43 |
﹄ | CJK: vertical right white corner bracket | U+FE44 |
﹉ | CJK: dashed overline | U+FE49 |
﹊ | CJK: centreline overline | U+FE4A |
﹋ | CJK: wavy overline | U+FE4B |
﹌ | CJK: double wavy overline | U+FE4C |
﹍ | CJK: dashed underline | U+FE4D |
﹎ | CJK: centreline underline | U+FE4E |
﹏ | CJK: wavy underline | U+FE4F |
﹐ | CJK: comma | U+FE50 |
﹑ | CJK: ideographic comma | U+FE51 |
﹔ | CJK: semicolon | U+FE54 |
﹕ | CJK: colon | U+FE55 |
﹖ | CJK: question mark | U+FE56 |
﹝ | CJK: left tortoise shell bracket | U+FE5D |
﹞ | CJK: rihgt tortoise shell bracket | U+FE5E |
﹟ | CJK: number sign | U+FE5F |
﹠ | CJK: ampersand | U+FE60 |
﹡ | CJK: asterisk | U+FE61 |
﹢ | CJK: plus | U+FE62 |
﹤ | CJK: less than | U+FE64 |
﹦ | CJK: equals | U+FE66 |
﹨ | CJK: backslash (solidus) | U+FE68 |
﹩ | CJK: dollar sign | U+FE69 |
﹪ | CJK: percent sign | U+FE6A |
﹫ | CJK: at sign | U+FE6B |
! | CJK: full-width exclamation mark | U+FF01 |
" | CJK: full-width double quotations | U+FF02 |
' | CJK: full-width single quotation (apostrophe) | U+FF03 |
( | CJK: full-width left bracket | U+FF08 |
) | CJK: full-width right bracket | U+FF09 |
, | CJK: full-width comma | U+FF0C |
: | CJK: full-width colon | U+FF1A |
; | CJK: full-width semicolon | U+FF1B |
? | CJK: full-width question mark | U+FF1F |
_ | CJK: full-width underscore | U+FF3F |
Operator
Operator | Explanation |
---|---|
AND |
query text fields which are matched by both of the subexpressions.
|
OR |
query text fields which are matched by either of the subexpressions.
|
NOT |
query text fields which are not matched by the subexpressions.
|
The default query operator is AND
. The default query operator can be customised.
For example, fq=tag:a b
will retrieve results with tag value that contain both a
and b
, same as fq=tag:a AND b
.
Precedence
The default precedence from highest to lowest is:
NOT
AND
OR
For example, in the query fq=tag:a OR b AND c
, the AND
takes precedence, so this is the same as fq=tag:a OR (b AND c)
. You can override the precedence using fq=tag:(a OR b) AND c
.
Result Scores
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-F min_score=0.5 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-F min_score=0.5 \
-u access_key:secret_key
// get similarity score
SearchParams params = new SearchParams("vintage_wingtips");
// return scores for each image result, default is false
params.setScore(true);
PagedSearchResult searchResult = client.search(params);
List<ImageResult> imageResults = searchResult.getResult();
for (ImageResult imageResult : imageResults) {
float score = imageResult.getScore();
// do something with the score
}
// only retrieve search results with scores between 0.5 and 0.8
SearchParams params = new SearchParams("vintage_wingtips");
params.setScoreMin(0.5f);
params.setScoreMax(0.8f);
PagedSearchResult searchResult = client.search(params);
score = True
response = api.uploadsearch(image_url=image_url, score=score)
# only retrieve search results with scores between 0.5 and 0.8
score_min = 0.5
score_max = 0.8
response = api.uploadsearch(
image_url=image_url,
score_max=score_max,
score_min=score_min)
$score = true;
$response = $service->uploadsearch($image, $page, $limit, $fl, $fq, $score);
// only retrieve search results with scores between 0.5 and 0.8
$score_min = 0.5;
$score_max = 0.8;
$response = $service->uploadsearch($image, $page, $limit, $fl, $fq,
$score, $score_max, $score_min);
// return scores for each image result, default is false
baseSearchParams.setScore(true);
IdSearchParams idSearchParams = new IdSearchParams("dress_1");
idSearchParams.setBaseSearchParams(baseSearchParams);
visearch.idSearch(idSearchParams);
...
@Override
public void onSearchResult(ResultList resultList) {
for (ImageResult imageResult : resultList.getImageList()) {
float score = imageResult.getScore();
//Do something with the score
...
}
}
//set the threshold value
baseSearchParams.setScoreMin(0.5);
baseSearchParams.setScoreMax(0.8);
// only retrieve search results with scores between 0.5 and 0.8
IdSearchParams idSearchParams = new IdSearchParams("dress_1");
idSearchParams.setBaseSearchParams(baseSearchParams);
visearch.idSearch(idSearchParams);
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.score = YES; // result will include score for every image
UploadSearchParams *uploadSearchParams = [[UploadSearchParams alloc] init];
uploadSearchParams.score = YES;
// result will include score for every image
uplaodSearchParams.scoreMin = 0.3; // the minimum score is 0.3
uplaodSearchParams.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({
im_url: 'your-image-url',
score: 'true',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
// only retrieve search results with scores between 0.5 and 0.8
visearch.uploadsearch({
im_url: 'your-image-url',
score: 'true',
score_min: '0.5',
score_max: '0.8',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
ViSearch image search results are ranked in descending order i.e. from the highest scores to the lowest, ranging from 1.0 to 0.0. By default, the score for each image result is not returned. You can turn on the score
property to retrieve the scores for each image result:
If you need to restrict search results from a minimum score to a maximum score, specify the score_min
and/or score_max
parameters:
Name | Type | Description |
---|---|---|
score_min | Float | Minimum score for the image results. Default is 0.0. |
score_max | Float | Maximum score for the image results. Default is 1.0. |
Remove Similar Image Results
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-F dedup=true \
-F dedup_score_threshold=0.5 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-F dedup=true \
-F dedup_score_threshold=0.5 \
-u access_key:secret_key
To remove repeated images or very similar images from the search result list, use dedup and dedup_score_threshold parameters to enlarge the score gap between adjacent results.
Name | Type | Description |
---|---|---|
dedup | Boolean | Parameter to turn on deduplication function. Default is false. |
dedup_score_threshold | Float | Sets the minimum gap between adjacent results. Only works when dedup=true. Default is 0.0. |
Retrieving Metadata
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-F fl=brand \
-F fl=price \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-F fl=brand \
-F fl=price \
-u access_key:secret_key
SearchParams params = new SearchParams("vintage_wingtips");
// add fq param to specify the list of metadata to retrieve
List<String> fl = new ArrayList<String>();
fl.add("title");
fl.add("price");
params.setFl(fl);
PagedSearchResult searchResult = client.search(params);
List<ImageResult> imageResults = searchResult.getResult();
for (ImageResult imageResult : imageResults) {
Map<String, String> metadata = imageResult.getMetadata();
// read your metadata here
}
fl = ["price", "brand", "title", "im_url"]
#, or fl = ("price", "brand", "title", "im_url")
response = api.uploadsearch(image_url=image_url, fl=fl)
$fl = array("price","brand","title","im_url");
$response = $service->uploadsearch($image, $page, $limit, $fl);
BaseSearchParams baseSearchParams = new BaseSearchParams();
List<String> fl = new ArrayList<>();
fl.add("price");
fl.add("brand");
baseSearchParams.setFl(fl);
UploadSearchParams uploadSearchParams =
new UploadSearchParams(new Image("/path/to/image"));
uploadSearchParams.setBaseSearchParams(baseSearchParams);
//In result callback you can read the metadata
@Override
public void onSearchResult(ResultList resultList) {
for (ImageResult imageResult : resultList.getImageList()) {
Map<String, String> metaData = imageResult.getMetaData();
//Do something with the metadata
...
}
}
SearchParams *searchParams = [[SearchParams alloc] init];
searchParams.fl = @[@"price",@"brand",@"im_url"];
// In result callback you can read the metadata
success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
// Iterate all returned results
for (ImageResult *result in data.imageResultsArray) {
NSLog("%@", result.metadataDictionary);//log result's metadata.
NSLog("%@", [result.metadataDictionary
objectForKey:@"price"]);//log price in metadata
//Do something here
}
}
visearch.uploadsearch({
im_url: 'your-image-url',
fl: ['price', 'brand', 'title', 'im-url'], // list of fields to be returned
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
To retrieve metadata of your image results, provide the list of metadata keys for the metadata value to be returned in the fl
(field list) property.
example of query all metadata
$ curl https://visearch.visenze.com/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-F get_all_fl=true \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-F image=@example-0.jpg \
-F box=0,0,20,20 \
-F get_all_fl=true \
-u access_key:secret_key
# example of json response
{
"status":"OK",
"method":"uploadsearch",
"im_id":"example_image_id",
"error":[
],
"page":1,
"limit":10,
"total":1000,
"result":[
{
"im_name":"image-name-1",
"value_map":{
"brand":"BrandA",
"price":"99.0",
"gender": "Male",
"age_group": "Adult",
"item_group_id": "8596225",
"itemId": "3311950",
}
},
...
]
}
SearchParams params = new SearchParams("vintage_wingtips");
params.setGetAllFl(true);
PagedSearchResult searchResult = client.search(params);
List<ImageResult> imageResults = searchResult.getResult();
for (ImageResult imageResult : imageResults) {
Map<String, String> metadata = imageResult.getMetadata();
// read your metadata here
}
get_all_fl = True
response = api.uploadsearch(image_url=image_url, get_all_fl=get_all_fl)
$get_all_fl = true;
$response = $service->uploadsearch($image, $page, $limit, $get_all_fl);
BaseSearchParams baseSearchParams = new BaseSearchParams();
baseSearchParams.setGetAllFl(true);
UploadSearchParams uploadSearchParams =
new UploadSearchParams(new Image("/path/to/image"));
uploadSearchParams.setBaseSearchParams(baseSearchParams);
visearch.uploadsearch({
im_url: 'your-image-url',
get_all_fl: 'true',
}, (res) => {
// TODO handle response
}, (err) => {
// TODO handle error
});
To retrieve all metadata of your image results, specify get_all_fl
parameter and set it to true.
Name | Type | Example | Description |
---|---|---|---|
fl | String | fl=brand&fl=price | The metadata fields to be returned. If the query value is not in data schema, it will be ignored. Text fields are not applicable for fl fetch. |
get_all_fl | Boolean | get_all_fl=true | If set true, return metadata for all the fields applicable for fl . Default value is false. |
Facet and Filtering
You can get the facet results by sending a list of fields to enable faceting on. Here are some limitations on the request:
- Facet fields need to be marked as ‘searchable’ on ViSenze dashboard.
- Text field is not supported as facet field even it is ‘searchable’.
- System will return value range, the min, max value for numerical fields which are in ‘int’, ‘float’ type.
- Only facet values that exist in current search results will be returned. For example, if your search results contain 10 unique brands, then the facet filters will return the value for these 10 brands.
- Facet value list is ordered by the item count descendingly. Item counts are based on the top 1000 results rather than items avaliable in the whole database.
- When the value is set to all (
facets
= *), all the searchable fields will be used as facet fields. - There is no limitation for the number of fields to enable faceting.
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=Brand \
-d fl=Gender \
-d fl=Price \
-d facets=color,brand,size,price \
-d facets_limit=5 \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=Brand \
-d fl=Gender \
-d fl=Price \
-d facets=color,brand,size,price \
-d facets_limit=5 \
-u access_key:secret_key
# example of json response
{
"status": "OK",
"method": "uploadsearch",
"error": [],
"page": 1,
"limit": 2,
"total": 1000,
"result": [
{
"im_name": "3024",
"value_map": {
"Brand": "BrandA",
"Gender": "Women",
"Price": "10"
}
},
{
"im_name": "OL13071",
"value_map": {
"Brand": "BrandB",
"Gender": "Men",
"Price": "20"
}
}
],
"facets": [
{
"key": "Brand",
"items": [
{
"value": "BrandA",
"count": 1
},
{
"value": "BrandB",
"count": 1
}
},
{
"key": "Gender",
"items": [
{
"value": "Women",
"count": 1
},
{
"value": "Men",
"count": 1
}
]
},
{
"key": "Price",
"range": {
"min": 10,
"max": 20
}
}
]
}
Request Parameters
Name | Type | Example | Description |
---|---|---|---|
facets | String | facets = color,brand,price | List of fields to enable faceting. |
facets_limit | Integer | facet_limit = 10 (default) | Limit of the number of facet values to be returned. Only for non-numerical fields. |
facets_show_count | Boolean | facets_show_count = true | Option to show the facets count in the response. Item counts are based on the top 1000 results. |
# E.g. of filtering request with facet result
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=brand \
-d fl=price \
-d fq=brand:brandA OR brandB \
-d fq=color:red \
-d fq=price:0,199 \
-d score=true \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d box=0,0,20,20 \
-d fl=brand \
-d fl=price \
-d fq=brand:brandA OR brandB \
-d fq=color:red \
-d fq=price:0,199 \
-d score=true \
-u access_key:secret_key
Facet Filtering
To filter search results based on facet values, provide a map of metadata key to filter value in the fq (filter query) property. All the syntax are same as normal filtering results.
Grouping Search Results
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d group_by=category \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d group_by=category \
-u access_key:secret_key
# example of json response
{
"status": "OK",
"method": "uploadsearch",
"error": [],
"page": 1,
"group_by_key": "category",
"group_limit": 10,
"total": 1000,
"group_results": [
{
"group_by_value": "dress",
"result": [
{
"im_name": "1201"
},
{
"im_name": "1202"
},
]
},
{
"group_by_value": "skirt",
"result": [
{
"im_name": "2201"
},
{
"im_name": "2202"
},
]
},
{
"group_by_value": "jumpsuit",
"result": [
{
"im_name": "3201"
},
{
"im_name": "3202"
}
]
}
]
}
You can group your search results by a specified field. The parameters are applicable to /search
and /uploadsearch
. Here are some limitations on the request:
- The specified group_by field needs to be marked as ‘searchable’ on ViSenze dashboard.
- The field data type must be string format. Text/int/float fields are not supported as group_by field.
- Only one group_by field is allowed in each request.
- The response structure will be based on group_by_value when group_by parameter is not null. Please refer to the example json response for details.
- Only group_by_value that exist in current search results will be returned. For example, if you use category as group_by key, and your search results contain 3 unique categories, then the results will return 3 grouped by results based on categories.
- Within each group, the results are returned in descending order of confidence scores. Among different groups, by default the groups are ordered by the top result’s confidence score.
Request Parameters
Name | Type | Example | Description |
---|---|---|---|
group_by | String | group_by = category | Field to be used as a group_by key. |
group_limit | Integer | group_limit = 10 (default) | Limit of the number of groups displayed per page. The maximum value is 100. |
Sorting Search Results
$ curl https://visearch.visenze.com/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d sort_by=price:desc \
-u access_key:secret_key
# for China, please use
$ curl https://visearch.visenze.com.cn/uploadsearch \
-d im_url=http://example.com/example-0.jpg \
-d sort_by=price:desc \
-u access_key:secret_key
# example of json response
{
"status": "OK",
"method": "uploadsearch",
"error": [],
"page": 1,
"limit": 10,
"total": 1000,
"result": [
{
"im_name": "001",
"value_map": {
"price": "120.0"
}
},
{
"im_name": "002",
"value_map": {
"price": "85.0"
}
},
{
"im_name": "003",
"value_map": {
"price": "82.0"
}
}
]
}
Be default, the search results are sorted in descending order of the scores. You can refine the sorting logic per page for your search results according to a named field. For example, you can sort according to descending order of the price. The parameters are applicable to /search
, /uploadsearch
and /discoversearch
. Here are some limitations on the request:
- The specified sort_by field must be int/ float/string format.
- Only one sort_by field is allowed in each request.
- When sorting logic is applied, it is highly possible that less similar results of the same page will be ranked in front.
Request Parameters
Name | Type | Example | Description |
---|---|---|---|
sort_by | String | sort_by = price:asc sort_by = price:desc |
Field to be used as sort key per page, and specify the ascending/ descending order. |
Tagging API
API OVERVIEW
Introduction
Our Tagging API (ViRecognition) can be used to detect individual products/objects in images, find their detailed fashion attributes/styles, and predict the image’s quality.
Integrate with your in-house product catalog management system; enable new user scenarios through fashion insights analysis
The API encapsulates powerful deep learning models in cloud-based, easy-to-use REST APIs.
When you upload an image via file or URL, our ViRecognition API can generate tags
that describe the object in the image.
- A
tag_group
may contain multipletags
that each describe a certain attribute- For example, within the
tag_group
ofproduct_color
, the API can recognize red and blue.
- For example, within the
You may choose tag_group
and tags
based on your needs and requirements. Our system will process your images based on the chosen tag_group
.
We currently provide a list of tag_group
for fashion recognition and image quality recognition. The list is ever-expanding as we explore for more use cases. Check information below for more details.
Authentication key pairs are required to authenticate each API call. Contact us at support@visenze.com to get your API Key pair and tag_group list.
Fashion Recognition
Our image recognition for fashion uncovers every layer of a fashion image. Fashion attribute recognition analyzes your images and tells you what are the fashion attributes inside of them. Fashion style and occasion recognition tells you the fashion elements and trends in your images.
fashion_attributes
tag_group name: fashion_attributes
. ViSenze’s fashion attributes taxonomy covers 70 fashion categories and more than 220 fashion tags under attributes including color, pattern, neckline, sleeve style, dress shape, shoe decoration, and many more.
Your images can be clean product images or user generated content. Fashion attribute recognition supports the detection of fashion object(s) in your images, and return the category and the associated attribute tags for each object.
Interested in the complete taxonomy? Please contact your account manager or start a free trial if you do not have an account yet.
fashion_style
tag_group name: fashion_style
. This tag_group is used to predict the styles of the fashion object in your image. ViSenze’s fashion style taxonomy covers the following list of styles:
- bohemian
- business
- casual
- fashion_statement
- feminine
- minimalism
- modest
- sexy
- sophisticated
- sporty
- streetstyle
fashion_occasion
tag_group name: fashion_occasion
. This tag_group is used to predict the suitable occasions associated with the fashion object in your image. ViSenze’s fashion occasion taxonomy covers the following list of occasions:
- beach_swim
- black_tie
- casual
- dating
- nightout
- semi_formal
- special_occasion
- sport
- winter
- workwear
gender_detect
tag_group name: gender_detect
. This tag_group is used to predict the gender associated with the fashion objects in your images. ViSenze’s gender taxonomy covers the following list of gender information:
- female
- male
- kid
- unisex
- other (referring to items without any gender attribute, eg. a chair)
Image Quality Recognition
Our API can also recognize images with low quality in terms of whether they are collaged, with text or watermark, blurred, with human/model or show only part of the product.
Here is a list of tag_group names available for image quality recognition:
image_detail
: to predict whether the image shows the whole product or only a part of it.image_human
: to predict whether there is a human model in the image.image_collage
: to predict whether the image is collaged.image_text
: to predict whether the image has watermark or text on it.image_mosaic
: to predict whether the image is blurry or pixelated.
RECOGNITION API
Authentication
$ curl http://virecognition.visenze.com/v1/image/recognize \
-u access_key:secret_key
We provide authentication using HTTP Basic Authentication. You can append the base64 string of access key and secret key pair in the request header, which is easy to use and suitable for API calls from backend systems.
name | description |
---|---|
access_key | Access key string. |
secret_key | Secret key string. Keep the secret key in a safe place and do not call the API directly from the client-side for security reasons. |
For the first method, the following steps describe how a client request URL is generated before making an API call.
- Generate the authorization information using the following steps:
- Concatenate the access key and secret together, separated by a colon
access_key
:secret_key
- Encode the above information into a base64 string (base64 encoding)
- Concatenate the access key and secret together, separated by a colon
- Put the authorization information in the header
Authorization
. Remember to appendBasic
before the base64 encoded key pair, in accordance with the HTTP Basic Authentication specifications.
The format of authorization in the header is like this:
Authorization: Basic access_key:secret_key.
Request
POST https://virecognition.visenze.com/v1/image/recognize
/image/recognize method uses an image (URL or file) as input and generates tags about the image.
Parameters
$ curl http://virecognition.visenze.com/v1/image/recognize \
-F url=https://example.com/shorts.png \
-F tag_group=fashion_attributes \
-F tag_group=fashion_occasion \
-u access_key:secret_key
There are several limits on the parameters and images:
- The images should be at least 100 pixels in both dimensions.
- For optimal results, we recommend images around
1024x1024
pixels. Low resolution images may result in unsatisfying search results. - If the image is larger, we recommended to resize the image to
1024x1024
pixels before sending to API. Too high resolution images may result in timeout. - The maximum image resolution is 40 Megapixels (height * width <= 40 Megapixels).
- The maximum file size of an image is 10MB.
- The supported image formats includes: .jpg, .jpeg, .jpe, .png, .gif, .bmp, .dib, .webp, .pbm, .pgm, .ppm, .sr, .ras, .tiff, .tif
name | description | example |
---|---|---|
url | An image URL that will be used to call the engine. NOTE: required if file has not been specified. |
url=http://example_image.com |
file | An image file. NOTE: required if url has not been specified. |
file=example_image.jpg |
tag_group required | The tag_group parameter allows user to specify the attributes to predict in the given image. Users can specify multi tag_groups in one API call using multiple tag_group key-value pairs. Users can also specify the version of the tag_group by adding the version number behind the tag_group name seperated by “:”. NOTE: Use GET https://virecognition.visenze.com/v1/tag_groups to check the available tag group versions and default versions on your account. |
tag_group=fashion_style tag_group=fashion_attributes tag_group=fashion_style:2.0.2 |
object_limit | Maximum number of objects to be returned. Return objects with higher confidence (box) score first. Default is 5, and Maximum number is 30 |
object_limit = 3 |
limit | Maximum number of tags to be returned for each attribute. Return top N results with confidence scores in descending order. Default number varies for different tag groups, and maximum number is 30 | limit = 3 |
language | The language parameter allows user to specify the language he/she prefers the tag to be returned in. The default language is English, and currently we support Chinese(zh), Korean(ko), Japanese(ja) and Indonesian(id). |
language = zh |
box | Optional parameter for restricting the image area x1,y1,x2,y2. Once this is passed in the parameter, only the area within bounding box will be analyzed.The box’s size must be minimally 20x20. | box=0,0,20,20 |
detection | The detection parameter allows user to specify the type of products to detect and draw box on. Here is a list of commonly used product types:
NOTE: The above list of product types is not exhaustive, please approach your account manager to get the full list. |
detection = top |
taxonomy_mapping | The taxonomy_mapping parameter allows user to receive a group of custom tags defined by a rule-based mapping from ViSenze tags. NOTE: Please approach your account manager to set up the taxonomy mapping for your account. |
taxonomy_mapping = seo_keywords |
Response
# example response JSON
{
"error": [],
"status": "OK",
"method": "image/recognize",
"reqid": "853563886081818624",
"result": [
{
"objects": [
{
"tags": [
{
"tag": "category:apparel",
"score": 0.9984000325202942
},
{
"tag": "apparel:lower_body_garment",
"score": 0.9795398712158203
},
{
"tag": "lower_body_garment:shorts",
"score": 0.8808417320251465
},
{
"tag": "product_color:grey",
"score": 0.8789975643157959
},
{
"tag": "product_pattern:melange",
"score": 0.7442622184753418
},
{
"tag": "lower_body_length:extra_short",
"score": 0.7016705870628357
},
{
"tag": "rise_type:high_rise",
"score": 0.4379652738571167
}
],
"box": [
45,
170,
1009,
919
]
}
],
"tag_group": "fashion_attributes"
},
{
"objects": [
{
"tags": [
{
"tag": "beach_swim",
"score": 0.9997109770774841
}
],
"box": [
45,
170,
1009,
919
]
}
],
"tag_group": "fashion_occasion"
}
]
}
For a single tag group, the information includes:
name | description |
---|---|
status | OK or fail . |
error | List of error messages. |
result | List of tags (with confidence scores) grouped according to tag groups. |
tag | Name of the tag. |
tag_group | The name of the tag group which the tag belongs to. |
box | The perimeter of the detected object, with the coordinates [x1, y1, x2, y2]. [x1, y1] and [x2, y2] are the bottom-left and upper-right coordinates of the bounding box accordingly. Valid only when the requested tag_group enable object detection. |
score | Confidence score ranging from 0 to 1. The higher the number, the more confident our ViRecognition engine is of correctly recognizing the object. |
Automatic Object Detection
# Automatically recognize the main object(s) and return corresponding tag values:
$ curl 'https://virecognition.visenze.com/v1/image/recognize' -u access_key:secret_key \
-F "url=https://example.com/example_1.jpg" \
-F "tag_group=fashion_attributes"
# example response JSON
{
"status": "OK",
"method": "image/recognize",
"error": [],
"result": [
{
"objects": [
{
"tags": [
{
"tag": "category:t_shirt",
"score": 0.9992560148239136
},
{
"tag": "neckline:o_neck",
"score": 0.9824492931365967
},
{
"tag": "sleeve_length:short",
"score": 0.9993560910224915
},
{
"tag": "sleeve_style:straight",
"score": 0.9986153841018677
},
{
"tag": "top_length:short",
"score": 0.9964359402656555
}
],
"box": [
185,
118,
397,
299
]
},
{
"tags": [
{
"tag": "category:jeans",
"score": 0.9683170318603516
},
{
"tag": "pants_fit_type:straight_leg",
"score": 0.8666971325874329
},
{
"tag": "denim_wash_color:medium",
"score": 0.9181555509567261
}
],
"box": [
207,
267,
395,
621
]
}
],
"tag_group": "fashion_attributes"
}
]
}
Our recognize API can automatically extract the objects from a noisy background image. For example, in the image below, we could recognize the tshirt and the jeans as two objects and return their corresponding attributes. For the t_shirt
, we will return its neckline
, sleeve_length
, sleeve_style
, and top_length
; while for the jeans
, we will return its pants_fit_type
and denim_wash_color
.
If you have already known what’s the product for the image, you can specify the category
parameter with the product type to make our automatic extraction of the key objects more accurate. This is an optional parameter but it is highly recommended for eCommerce clients to tag product images with well-defined category info.
For the same image, when specify the category=jeans
, our API will detect the jeans in the given images and return only the jeans
attributes correspondingly, including pants_fit_type
and denim_wash_color
.
Error Codes
General Error Messages
Message |
---|
System busy, please try again later. |
Image Error Messages
Message | Remarks |
---|---|
Image not given. | Do check your image source again and see if it is an image or another filetype. |
Only one image source is allowed. | Do use **either* im_url or image param.* |
Multiple image url detected. Only one is allowed. | – |
Missing tag group parameters. | Your tag_group param should contain at least one of the categories found in the product tagging catalogue. |
Invalid image. | The supported image formats includes: .jpg, .jpeg, .jpe, .png, .gif, .bmp, .dib, .webp, .pbm, .pgm, .ppm, .sr, .ras, .tiff, .tif |
Image file size over limit. | The maximum file size of an image is 10MB. |
Unable to get image from url. | Do check your im_url to see if it links to a publicly accessible image. |
Invalid box parameter. | Your box parameters may be out of the range of the given image. |
Box parameter should not contain negative values. | – |
Box parameter dimensions should be at least 20x20. | – |
Please use form-data for request body in POST method. Query with url params is no longer supported. | – |
Authentication Error Messages
Message |
---|
Authentication failed. Invalid access key or secret key. |
No access rights to tag groups: {0}. |
Missing authorization information. |
Account is disabled. Please contact administrator for enquiries. |
Invalid tag group {0}. |
Tag group {0} given in version does not match with any tag group given. |