NAV Navbar
Logo
curl Java Python PHP JavaScript iOS Android

ViSearch API

API OVERVIEW

Introduction

ViSearch is an API that 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.3.0
// 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.3.0</version>
</dependency>


// Gradle projects: include this line in your `build.gradle` dependencies block:
compile 'com.visenze:visearch-java-sdk:1.3.0'


// SBT projects: add the following line to `build.sbt`:
libraryDependencies += "com.visenze" % "visearch-java-sdk" % "1.3.0"

* 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';
# Supported on Python 2.6+ and 3.3+
$ pip install visearch
// 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 ViSearch SDK and place the ViSearch to your project directory.
// Include ViSearch API into your project
require_once 'pathTo/ViSearch/viSearch.php';
// you can user 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 won’t affect your page load speed.

<script type="text/javascript">
    !function(e,r,t,a,s){e.__visearch_obj=s;var c=e[s]=e[s]||{};c.q=c.q||[],c.factory=function(e){return function(){var r=Array.prototype.slice.call(arguments);return r.unshift(e),c.q.push(r),c}},c.methods=["idsearch","uploadsearch","colorsearch","set","send"];for(var n=0;n<c.methods.length;n++){var o=c.methods[n];c[o]=c.factory(o)}var i=r.createElement(t);i.type="text/javascript",i.async=!0,i.src=a;var h=r.getElementsByTagName(t)[0];h.parentNode.insertBefore(i,h)}(window,document,"script","https://cdn.visenze.com/visearch/dist/js/visearch-1.3.1-beta.min.js","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.3.0'
...

// Install the ViSearch SDK:
pod install
// Current stable version: 1.2.1
// 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.0.12'

// 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 http://visearch.visenze.com/search?im_name=example-0 \
      -X GET \
      -u access_key:secret_key
ViSearch client = new ViSearch("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
from visearch import client

api = client.ViSearchAPI('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY')
$service = new ViSearch($access_key,$secret_key);
<script type="text/javascript">
    ...
    visearch.set("access_key", "YOUR_ACCESS_KEY");
    visearch.set("secret_key", "YOUR_SECRET_KEY");
</script>
@implementation HomeViewController {
    NSMutableArray *rectangles;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    rectangles = [[NSMutableArray alloc] init];
    self.generalService = [GeneralServices sharedInstance];

    //TODO: insert your own application keys
    NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
    [dict setValue:@"YOUR_APP_KEY" forKey:@"app_key"];
    [[CoreDataModel sharedInstance] insertApplication:dict];
}
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);

      ...
    }
    ...
 }

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.

API Response

# example JSON response
{
  "status": "OK",
  "method": "uploadsearch",
  "im_id":"example_image_id",
  "result": [],
  "error": [],
  "page": 1,
  "limit": 10,
  "total": 1000
}

ViSearch API returns a JSON object string for all requests. The responses contain the following common properties:

name description
status The request status, either “OK”, “warning”, or “fail”.
method The request method.
im_id The unique ID for uploaded image, only visible for uploadsearch.
result The list of result objects if the request was successful i.e. when status is “OK”.
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.

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
The query image is still being processed, please try again later.
Image not found with im_name.
Invalid image file format.
The image format or dimension is invalid.
Invalid image or im_url.
Could not download the image, please try again later.
Timeout while downloading image, please try again later.
App doesn’t have any images.

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 http://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

# 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:

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 http://visearch.visenze.com/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 http://visearch.visenze.com/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 three type of solutions:

  1. Visually Similar Recommendations
    Visually Similar Recommendations solution is to search for visually similar images in the image database giving an indexed image’s unique identifier (im_name).

  2. Search by Image
    Search by image solution is to search similar images by uploading an image or providing an image url. For each uploaded image ViSearch service will return an unique im_id which can be used to do upload search without downloading the image again.

  3. Search by Color
    Search by color solution is to search images with similar color by providing color codes. The color code should be in Hexadecimal and passed to the colorsearch service.

Visually Similar Recommendations

$ curl http://visearch.visenze.com/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);
var IM_ID = "yoox-38377218";
visearch.idsearch({
  im_name: IM_ID,
  fl: ["im_url"]
}, function(res) {
  // @TODO
  // some response handler
});

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.

Search by Image

POST /uploadsearch

Searching an uploaded image file

$ curl http://visearch.visenze.com/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: [html file input object],
}, function(res) {
  // @TODO
  // some response handler
});
#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 http://visearch.visenze.com/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: "", // image url string
  fl: ["im_url"],
}, function(res) {
  // @TODO
  // some response handler
});
#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);

This API is for searching against your image collection with an uploaded image, by sending in an image object or providing an public accessible image URL. You will get an unique image ID for each uploaded image, you could use the image ID as search query to save the network bandwidth.

There are some limitations on the request and the image:

request parameters

name example description
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.
im_url im_url=http://example.com/exmaple.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.
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).

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.

Searching with im_id that can be retrieved from the previous uploadsearch response.

# Searching an im_id

{
    "status":"OK",
    "method":"uploadsearch",
    "im_id":"example_image_id",
    "error":[
    ],
    "page":1,
    "limit":2,
    "total":1000,
    "result":[
        ...
    ]
}

$ curl http://visearch.visenze.com/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);
# Searching using im_id


//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);

Search by Color

GET /colorsearch

$ curl http://visearch.visenze.com/colorsearch?color=012ACF \
    -u access_key:secret_key
ColorSearchParams params = new ColorSearchParams("9b351b");
PagedSearchResult searchResult = client.colorSearch(params);
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
    }];
...
var colorHex = "fa4d4d";
visearch.colorsearch({
  color: colorHex
}, function(res) {
  // @TODO
  // some response handler
});

This API is for searching for images matching to the colors in your image collection.

request parameters

name example description
color required color=012ACF The 6 character hex color.

Search Responses

ViSearch returns a maximum number of 1000 most relevant image search results. You can provide pagination parameters to control the paging of the image search results. The default page number is 1 and the default result per page limit is 10.

// example response
{
    "status":"OK",
    "method":"uploadsearch",
    "im_id":"example_image_id",
    "error":[
    ],
    "page":1,
    "limit":2,
    "total":1000,
    "result":[
        {
            "im_name":"image-name-1",
        },
        {
            "im_name":"image-name-2",
        }
    ],
    "qinfo":{
        "im_url":"http://example.com/example.jpg",
        "brand":
        "my_brand",
        "price": 199
    },
     "reqid":"597001848511123456"
}
// building pre-indexed search params
SearchParams params = new SearchParams("vintage_wingtips");
params.setPage(1);
params.setLimit(20);
PagedSearchResult searchResult = client.search(params);

// total number of results
int total = searchResult.getTotal();
// get the list of image search results
List<ImageResult> imageResults = searchResult.getResult();
// iterates through the list and get unique identifiers of the results
for (ImageResult imageResult : imageResults) {
    String imName = imageResult.getImName();
    // your code follows
}

// if more results available, get the next page of results
params.setPage(2);
PagedSearchResult nextPageOfSearchResult = client.search(params);
page = 1
limit = 25
response = api.uploadsearch(image_url=image_url, page=page, limit=limit)
$page = 1;
$limit = 25;
$response = $service->uploadsearch($image, $page, $limit);
//set page number and page limit
BaseSearchParams baseSearchParams = new BaseSearchParams();
baseSearchParams.setLimit(20);
baseSearchParams.setPage(1);
ColorSearchParams colorSearchParams = new ColorSearchParams("3322ff");
colorSearchParams.setBaseSearchParams(baseSearchParams);
visearcher.colorSearch(colorSearchParams);

//response can be captured in the callback method
@Override
public void onSearchResult(ResultList resultList) {
    for (ImageResult imageResult : resultList.getImageList()) {
        //Do something with each result image
        ...
    }
}

@Override
public void onSearchError(String error) {

}


@Override
public void onSearchCanceled() {

}
// 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.
...
SearchParams *searchParams = [[SearchParams alloc] init];
searchParams.page = 2;
searchParams.limit = 30;

// start searching
...

// This is an example of image url search.
// The process of handling results by other kinds of search is similar.
[[ViSearchAPI defaultClient]
    searchWithImageUrl:uploadSearchParams
    success:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
        // Iterate all returned results
        for (ImageResult *result in data.imageResultsArray) {
            NSLog("%@", result.url);//log result's image url.
            //Do something here
        }
    } failure:^(NSInteger statusCode, ViSearchResult *data, NSError *error) {
        NSLog("%@", data.error.message);//log network and server error message
    }];
visearch.uploadsearch({
  im_url: "", // image url string,
  page: 1,
  limit: 25,
  fl: ["im_url"],
}, function(res) {
  // @TODO
  // some response handler
});

The table below explains each field in the response json. The listed response properties are common for all search APIs.

name example description
page “page”: 1 The result page number.
limit “limit”: 10 The number of results per page.
total “total”: 1000 Total number of search results. The maximum number of result returned from API is 1000.
result see code example The list of matching image objects.
qinfo see code example The querying image object.
reqid see code example The unique request id of the api call

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 recognition so the algorithm will try to detect the object in the image and search
fl fl=brand&fl=price The metadata fields to be returned. If the query value is not in data schema, it will be ignored.
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.
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.
page page=1 The result page number.
limit limit=10 The number of results returned per page. The maximum number of results returned from the API is 1000.
qinfo qinfo=true If true, query information will be returned.

Automatic Object Recognition

$ curl http://visearch.visenze.com/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: "", // image url string,
  score: true,
  detection: 'all'
}, function(res) {
  // @TODO
  // some response handler
});

With Automatic Object Recognition, ViSearch /uploadsearch API is smart to detect the objects present in the query image and suggest the best matched product type to run the search on.

We are now able to detect various types of fashion items, including Top, Dress, Bottom, Shoe, Bag, Watch, Furniture, Eyewear, Jewlery, Outerwear, Skirt and Indian Ethnic Wear. The list is ever-expanding as we explore this feature for other categories.

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: detection point

set detection type as ‘bag’

$ curl http://visearch.visenze.com/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: "", // image url string,
  score: true,
  detection: 'bag'
}, function(res) {
  // @TODO
  // some response handler
});

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.

Sample request to detect bag in an uploaded image:

Selection Box

$ curl http://visearch.visenze.com/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: "", // image url string
  // input a string of "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: "x1,y1,x2,y2",
  fl: ["im_url"],
}, function(res) {
  // @TODO
  // some response handler
});

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 http://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


// 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:nike'];
visearch.uploadsearch({
  im_url: "", // image url string,
  fq: filterQuery,
}, function(res) {
  // @TODO
  // some response handler
});
Type Explanation
string Metadata value must be either
  • exactly matched with the query value, e.g. Vintage Wingtips would not match vintage wingtips or vintage
  • matched with multiple exact query values separated with OR operator. e.g. Wingtips OR Longwing would retrieve results that are matched by either Wingtips or Longwing
  • double quoted if it contains special character, e.g. "Women's shoes" OR "Women's Clothes"would retrieve results that are matched by either Women's shoes or Women's Clothes
int Metadata value can be either:
  • exactly matched with the query value
  • matched with a ranged query minValue,maxValue, e.g. int value 1, 99, and 199 would match ranged query 0,199 but would not match ranged query 200,300
float Metadata value can be either
  • exactly matched with the query value
  • matched with a ranged query minValue,maxValue, e.g. float value 1.0, 99.99, and 199.99 would match ranged query 0.0,199.99 but would not match ranged query 200.0,300.0
text Metadata value will be indexed using full-text-search engine and supports fuzzy text matching. Explained in detail in the following section*

Query Syntax for Text Field *

The query syntax for text field is similar to other web based search engine. The commonly used operators are: AND, OR, NOT, XOR, + and -, and double quotes (""). It is case insensitive in any case.

Operator Explanation
AND query text fields which are matched by both of the subexpressions.
  • For example, fq=tag:a AND b retrieves results whose tag fields containing both a and b in any order.
OR query text fields which are matched by either of the subexpressions.
  • For example, fq=tag:a OR b retrieves results whose tag fields containing either a or b or both a and b in any order.
"" phrases enclosed in double quotes match the text fields that contain the query phrases in the exact order without any other phrases in between.
  • For example, fq=tag:"a b" retrieves text fields containing “a,b” or “a b”, but excludes phrases of “a,c,b” or “b a” .

Default Operator

The default query operator is AND.

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.

Delimiter

The accepted field delimiter includes: space, comma(,), semicolon(;) and vertical bar(|). The delimiter will not be used for matching, but to separate the text phrases.

For example, the four queries below have the same performance as the query fq=tag:a AND b:

Precedence

The default precedence from highest to lowest is:

  1. AND
  2. 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 http://visearch.visenze.com/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: "", // image url string,
  score: true,
}, function(res) {
  // @TODO
  // some response handler
});

// only retrieve search results with scores between 0.5 and 0.8
visearch.uploadsearch({
  im_url: "", // image url string,
  score: true,
  min_score: 0.3,
  max_score: 0.8
}, function(res) {
  // @TODO
  // some response handler
});

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.

Retrieving Metadata

$ curl http://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

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: "", // image url string,
  fl: ["price","brand","title","im_url"], //list of field list to be returned
}, function(res) {
  // @TODO
  // some response handler
});

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 http://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

// 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: "", // image url string,
  get_all_fl: true,
}, function(res) {
  // @TODO
  // some response handler
});

To retrieve all metadata of your image results, specify get_all_fl parameter and set it to true.

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:

$ curl http://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

// example of json response

{
  "status": "OK",
  "method": "uploadsearch",
  "error": [],
  "page": 1,
  "limit": 2,
  "total": 1000,
  "result": [
      {
        "im_name": "3024",
        "value_map": {
          "Brand": "H&M",
          "Gender": "Women",
          "Price": "10"
        }
      },
      {
        "im_name": "OL13071",
        "value_map": {
          "Brand": "Zara",
          "Gender": "Men",
          "Price": "20"
        }
      }
  ],
  "facets": [
    {
      "key": "Brand",
      "items": [
          {
            "value": "H&M",
            "count": 1
          },
          {
            "value": "ZARA",
            "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 http://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:nike OR adidas \
       -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.

ViRecognition API

OVERVIEW

ViRecogintion API empowers developers to understand the image content by encapsulating powerful deep learning models in cloud-based easy-to-use REST APIs. You can use the API to predict the quality of images, detect individual products or objects and find the detailed fashion attributes within images. You can enable new user scenarios through fashion attributes analysis, moderate low quality images or integrate with your in-house product catalogue management system.

Given an image URL or an image file, ViRecogintion API can generate tags about the image. tags refer to the visual concept that can be recognized by our system. A tag_group may contain multiple tags that describe certain attribute. For example, within the tag_group product_color, red and blue are two examples of tags we can recognize. 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 attributes recognition and low quality image 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 Attribute Recognition

Fashion attribute recognition analyzes your images and tells you what are the fashion attributes inside of them. Fashion attributes refer to color, pattern and other predefined attributes of the products. 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 fashion attribute tags for each object.

fashion_attributes

tag_group name: fashion_attributes. This tag_group is used to detect the fashion object(s) in an image, then predict the category information and fashion attributes for each object. fashion_attributes works well on images with multiple objects or user generated content.

The category list and the types of fashion attributes to be predicted are predefined:

category example predefined attributes category example predefined attributes
sweater sweater sweater_neckline,
outerwear_length,
sweater_style,
product_color,
product_pattern
sweatshirt sweatshirt sweatshirt_neckline,
product_color,
product_pattern
blouse blouse neckline,
sleeve_length,
sleeve_style,
tops_length,
product_color,
product_pattern
shirt shirt neckline,
sleeve_length,
sleeve_style,
tops_length,
product_color,
product_pattern
crop_top crop_top neckline,
sleeve_length,
sleeve_style,
tops_length,
product_color,
product_pattern
t_shirt t_shirt neckline,
sleeve_length,
sleeve_style,
tops_length,
product_color,
product_pattern
jacket jacket closure_type,
outerwear_length,
outerwear_neckline,
product_color,
product_pattern
coat coat closure_type,
outerwear_length,
outerwear_neckline,
overcoat_style,
product_color,
product_pattern
blazer blazer closure_type,
outerwear_length,
outerwear_neckline,
product_color,
product_pattern
suit suit closure_type,
product_color,
product_pattern
playsuit playsuit neckline,
sleeve_length,
sleeve_style,
product_color,
product_pattern
jumpsuit jumpsuit neckline,
sleeve_length,
sleeve_style,
product_color,
product_pattern
dress dress neckline,
sleeve_length,
sleeve_style,
skirt_length,
skirt_shape,
product_color,
product_pattern
skirt skirt skirt_length,
skirt_shape,
product_color,
product_pattern
jeans jeans pants_fit_type,
denim_wash_color,
product_color,
product_pattern
pants pants pants_fit_type,
product_color,
product_pattern
shorts shorts shorts_waist,
product_color,
product_pattern

For details of the fasion attributes, please contact us at support@visenze.com.

fashion_attributes_clean

tag_group name: fashion_attributes_clean. This tag_group is used to classify the product image into its relevant category, and return the fashion attributes of the product. Unlike fashion_attributes, the tag group fashion_attributes_clean does not detect multiple objects, therefore it works best on clean fashion product images.

The list of categories and fashion attributes to be predicted are the same as fashion_attributes above.

product_color

tag_group name: product_color. This tag_group is used to predict the product color. Note that product_color is one of the attributes in fashion_attributes tag_group. This stand-alone tag_group can be used on a wider range of fashion objects.

List of tags and examples:

tag example tag example
white product_color_white brown product_color_brown
yellow product_color_yellow black product_color_black
beige product_color_beige grey product_color_grey
pink product_color_pink navy product_color_navy
orange product_color_orange blue product_color_blue
red product_color_red green product_color_green
purple product_color_purple multi product_color_mutli

product_pattern

tag_group name: product_pattern. This tag_group is used to predict the product pattern for fashion objects. Note that product_pattern is one of the attributes in fashion_attributes tag_group. This stand-alone tag_group can be used on a wider range of fashion objects.

List of tags and examples:

tag example tag example tag example
animalprint product_pattern_animalprint dotted product_pattern_dotted floral product_pattern_floral
biggraphic product_pattern_biggraphic plaid product_pattern_plaid solid product_pattern_solid
camouflage product_pattern_camouflage stripes product_pattern_stripes text product_pattern_text

Low Quality Image Recognition

We could 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.

image_collage

tag_group name: image_collage. This tag_group is used to detect whether the image is collaged.

List of tags and examples:

tag example tag example
collage image_collage_collage no_collage image_collage_no_collage

image_text

tag_group name: image_text. This tag_group is used to detect whether the image has watermark or text on it.

List of tags and examples:

tag example tag example
text image_text_text no_text image_text_no_text

image_mosaic

tag_group name: image_mosaic. This tag_group is used to detect whether the image is blurry.

List of tags and examples:

tag example tag example
mosaic image_mosaic_mosaic no_mosaic image_mosaic_clean

image_human

tag_group name: image_human. This tag_group is used to detect whether the image has human or model in it.

List of tags and examples:

tag example tag example
model image_human_human no_model image_human_nohuman

image_detail

tag_group name: image_detail. This tag_group is used to detect whether the image shows the whole product or only a part of the product.

List of tags and examples:

tag example tag example
detail image_detail_part no_detail image_detail_whole

RECOGNITION API

Authentication

curl "api_endpoint_here"
      -u access_key:secret_key

curl "api_endpoint_here"
  -H "Authorization: Basic base64_encoded_string_of_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.

The format of authorization in the header is like this: Authorization: Basic €˜access_key:secret_key.

Request

POST http://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' -u access_key:secret_key  \
    -F "url=https://example.com/dress.png"
    -F "tag_group=product_color"

There are several limits on the parameters and images:

name description example required
url An image URL that will be used to call the engine. url=http://example_image.com Required if file has not been specified.
file An image file. file=example_image.jpg Required if url has not been specified.
tag_group The specific attribute user want to predict in the given image.
Include at least one tag_group, and use a new form field for each tag group.
Please refer to Overview section for details.
tag_group=product_color YES
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 NO

Response

# example response json:
{
  "status": "OK",
  "method": "image/recognize",
  "error": [],
  "result": [
        {
            "objects": [
                {
                    "tags": [
                        {
                            "tag": "red",
                            "score": 0.9801902723312378
                        }
                    ],
                    "box": [
                      185,
                      118,
                      397,
                      299
                    ]
                }
            ],
            "tag_group": "product_color"
        }
]
}

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:

Input

curl 'http://virecognition.visenze.com/v1/image/recognize' -u access_key:secret_key  \
   -F "url=https://example.com/example_1.jpg" \
   -F "tag_group=fashion_attributes"

Response

{
    "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": "tops_length:short",
                            "score": 0.9964359402656555
                        }
                    ],
                    "box": [
                      185,
                      118,
                      397,
                      299
                    ]
                }
            ],
            "objects": [
                {
                    "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 tops_length; while for the jeans, we will return its pants_fit_type and denim_wash_color.

recognize

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.

recognize_pants

Error Codes

General Error Messages

Message
System busy, please try again later.

Image Error Messages

Message
Image not given.
Only one image source is allowed.
Multiple image url detected. Only one is allowed.
Missing tag group parameters.
Invalid image.
Image file size over limit.
Unable to get image from url.
Invalid box parameter.
Box parameter should not contain negative value.
Box parameter dimensions should be at least 20 x 20.
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.