Skip to content

Fashion Search

PRICING DEMO

With Fashion Search, your customers can take real-life pictures & find visually similar products in your clothing e-commerce (we call it "visual search"). Moreover, the Fashion Search service integrates three services that are often requested by our apparel & fashion customers - Fashion Tagging, Product Similarity and Dominant Colors.

Screenshot

How it works

  • Your database is synchronized with a collection in Ximilar cloud (see below).
  • You can get fashion tags for each product in your database (see below).
  • You can get similar items to display alternative products to your customers (see below).
  • You can send a real-life photo (e.g. from a cell phone), let the system detect apparel items on the photo and get the closest matching items from your collection (see below).

The API is on the following URL:

https://api.ximilar.com/similarity/fashion/v2/<method>

and it contains all methods from Photo & Product Similarity.

Python Library

If you are using Python programming language in your project you can query our API with our library. Our library is available on gitlab and through the pypi. For the Fashion Search, use class ximilar.client.search.SimilarityFashionClient.

Things to note

  • For insert (/v2/insert) you can specify maximum of 10 records per request/batch size in "records" field
  • Search (/v2/visualTagsKNN) is only possible with one record (photo) in field "query_record"
  • We support a lot of customization as renaming/translation of tags, advanced filtering, ...

You store your product image database into a collection in Ximilar cloud in the same way you do with in Photo & Product Similarity. When a product photo is inserted into the collection, Ximilar process the image like this:

  1. detect apparel items on the photo,
  2. run Fashion Tagging on the largest detected item (see Apparel Detection & Tags),
  3. extract the visual information from this largest detected item,
  4. insert the image with the fashion tags to the collection.

Ximilar can do the sync

You can keep the collection synchronized yourself via the insert and delete API methods. The other option is let Ximilar do this for you - run a regular process (e.g. nightly) that:

  • downloads your current database export (in any format agreed on) from a given URL,
  • calculates the difference between the export and your collection
  • inserts new products to the collection
  • removes stale products from the collection.

Ximilar must know the format of your data and we can together define a mapping between your categories and Ximilar taxonomy and thus specify the top category (and category) of the main item during the insert operation (see above). We usually charge a small fee for implementation of the synchronization script (depending on complexity and format of the export).

Contact us at tech@ximilar.com and we will arrange this regular sync for you.

Sometimes it is difficult to correctly estimate the main item on the product image and its category. You can help Ximilar with this by sending over the information about the Top Category (and Category) of the product. You must use the categories according to Ximilar Fashion Taxonomy and put the information into each inserted image record, e.g.

{
  "records": 
  [
    {
      "product_id": "ABC",
      "_id": "ABC_1",
      "_url": "https://example.com/product/image/url.png",
      "Top Category": "Clothing",
      "Category": "Clothing/Pants"        
    }
  ] 
}

If you do this, the insert operation will not necessarily select the largest object detected but the largest object with the matching Top Category (and Category). In case there is no such object detected in the image, Ximilar considers the whole image as fashion item and uses Fashion Tagging method to determine its categories and tags.

Get fashion tags

As mentioned above, each product photo is processed by the Apparel Detection & Tags method. The response from this method is in the record stored in your Ximilar collection. There are two ways to get to this output:

  1. When you call the insert API operation, the response from this operation contains also the JSON response from the Apparel Detection & Tags method.
  2. You can use method /v2/get to get the fashion tags stored in individual records. See example of such response below.
CLICK TO SHOW JSON RESPONSE EXAMPLE

{
  "records": [
    {
      "_url": "__URL_PATH__",
      "_objects": [
        {
          "name": "Clothing",
          "id": "8e6cf45d-d416-4560-a89a-1b83b80e003b",
          "bound_box": [
            266,
            281,
            544,
            707
          ],
          "prob": 0.9437555074691772,
          "area": 0.20078531901041666,
          "Top Category": "Clothing",
          "_tags": {
            "Category": [
              {
                "prob": 0.99295,
                "name": "Clothing/Pants",
                "id": "7e3a6f68-f13a-417c-9613-16e6045b4020"
              }
            ],
            "Color": [
              {
                "prob": 0.53784,
                "name": "black",
                "id": "ca5a002b-d206-45a3-b586-820539845a5e"
              },
              {
                "prob": 0.46087,
                "name": "dark blue and navy",
                "id": "848d99a2-0f52-4ecf-8ca4-947ee55e1c36"
              }
            ],
            "Style": [
              {
                "prob": 1.0,
                "name": "elegant",
                "id": "8ec36318-6a71-41f6-90e6-6f8eba3dad2a"
              }
            ],
            "Subcategory": [
              {
                "prob": 0.99998,
                "name": "suit trousers",
                "id": "87ea03a2-040f-4b21-8b12-33e3b5f04261"
              },
              {
                "name": "formal trousers",
                "prob": 0.99295
              }
            ],
            "Pattern": [
              {
                "prob": 0.95253,
                "name": "plain",
                "id": "5065ee09-6fa1-48f3-834f-eced387f46a8"
              }
            ],
            "Gender": [
              {
                "prob": 0.38094,
                "name": "men",
                "id": "724afe83-bfb7-4f18-aeeb-a7511feeb9b1"
              },
              {
                "prob": 0.32215,
                "name": "women",
                "id": "6d310c15-258f-40e7-9ced-d8be7059b3e9"
              }
            ],
            "Length": [
              {
                "prob": 0.97548,
                "name": "long",
                "id": "bfca0daa-2ef7-4eff-892d-2021087064a9"
              }
            ],
            "Fit": [
              {
                "prob": 0.74897,
                "name": "slim",
                "id": "ebb81e52-8a41-450e-988c-58003a714286"
              }
            ],
            "Top Category": [
              {
                "id": "13052be8-2cc7-48e4-a782-a00d658f997c",
                "name": "Clothing",
                "prob": 1.0
              }
            ]
          },
          "_tags_simple": [
            "elegant",
            "long",
            "Clothing/Pants",
            "plain",
            "slim",
            "Clothing",
            "formal trousers",
            "suit trousers",
            "black"
          ],
          "Category": "Clothing/Pants"
        },
        {
          "name": "Clothing",
          "id": "8e6cf45d-d416-4560-a89a-1b83b80e003b",
          "bound_box": [
            208,
            33,
            588,
            356
          ],
          "prob": 0.886322557926178,
          "area": 0.2080959743923611,
          "Top Category": "Clothing",
          "Category": "Clothing/Jackets and Coats"
        }
      ]
    }
  ],
  "status": {
    "code": 200,
    "text": "OK",
    "request_id": "fd114fb0-dff9-4851-842c-bf9bc4ce856d",
    "proc_id": "55669f4d-79f8-4957-aaf5-0be301252708"
  },
  "statistics": {
    "processing time": 2.2415950298309326
  }
}

Get similar fashion products

You can get similar item recommendations in the same way as you would with image similarity using method

https://api.ximilar.com/similarity/fashion/v2/visualTagsKNN

The method combines the visual similarity with the similarity of tags from the fashion tagging (it is stored in field _tags_simple). Internally, the system also uses a default filter that is automatically internally added to the filter parameter specified in the API methods. Currently this default filter is:

{ "filter": { "Top Category": "{TAKE_FROM_QUERY}", "Category": "{TAKE_FROM_QUERY}" } }

This default filter might change in future but it does not influence the overall behaviour of the search.

Visual search by real photo

Finally, let us see how to get visual search results like in this demo. It is done via the same method as getting similar collection items:

https://api.ximilar.com/similarity/fashion/v2/visualTagsKNN

This method returns:

  • all fashion items detected in the query photo - it is in field query_records[0]._objects,
  • and products from your collection that are similar to the largest item detected - standard fields answer_records and distances.

CLICK TO SHOW JSON RESPONSE EXAMPLE

 {
  "query_records": [
     {
       "_id": "49831",
       "_url": "https://example.com/image.png",
       "_objects": [
         {
           "area": 0.696093738079071,
           "prob": 0.9520546793937683,
           "Top Category": "Clothing",
           "Category": "Clothing/Jackets and Coats",
           "bound_box": [
             49,
             3,
             346,
             378
           ],
           "_tags": {
             "detailed tag list as returned from detect_tags": true
           },
           "_tags_simple": [
              "simple tag list as returned from detect_tags"
           ]
         },
         {
           "area": 0.376093738079071,
           "prob": 0.9120546793937683,
           "Top Category": "Clothing",
           "Category": "Clothing/Pants",
           "bound_box": [
             349,
             23,
             646,
             378
           ]
         }
       ]
     }
   ],
   "answer_records": [
     {
       "_id": "294215",
       "_url": "https://images.ximilar.com/fashion/Clothing/Pullover/Knit sweater/v70kjnwe53sz4may/v70kjnwe53sz4may_1.jpg"
     },
     {
       "_id": "426897",
       "_url": "https://images.ximilar.com/fashion/Clothing/Pullover/Cardigans/tjp1xeo84f67yu3m/tjp1xeo84f67yu3m_1.jpg"
     },
     {
       "_id": "148430",
       "_url": "https://images.ximilar.com/fashion/Clothing/Pullover/kebwxtnm84c7lhf0/kebwxtnm84c7lhf0_1.jpg"
     },
     {
       "_id": "148232",
       "_url": "https://images.ximilar.com/fashion/Clothing/Pants/Jumpsuits/pw369sxkearg08ot/pw369sxkearg08ot_1.jpg"
     },
     {
       "_id": "1364490",
       "_url": "https://images.ximilar.com/fashion/Clothing/Swimwear/Beach clothing/row0ztdqnj897li3/row0ztdqnj897li3_1.jpg"
     }
   ],
   "answer_distances": [
     0.64635134,
     0.65307707,
     0.66936225,
     0.6757167,
     0.6777565
   ],
   "answer_count": 5,
   "status": {
     "code": 200,
     "text": "OK"
   },
   "statistics": {
     "OperationTime": 19
   }
}

If you want to get products similar to any other object than the main (largest) one, you can do it by simply passing the query object with the field _objects pre-filled with the secondary object. The query might then look like this:

$ curl --request POST \
    --url https://api.ximilar.com/similarity/fashion/v2/visualTagsKNN \
    --header 'authorization: Token __API_TOKEN__' \
    --header 'collection-id: __COLLECTION_ID__' \
    --header 'content-type: application/json' \
    --data '{
    "query_record": {
       "_url": "https://example.com/image.png",
       "_objects": [
         {
           "area": 0.376093738079071,
           "prob": 0.9120546793937683,
           "Top Category": "Clothing",
           "Category": "Clothing/Pants",
           "bound_box": [
             349,
             23,
             646,
             378
           ]
         }
       ]
    },
    "fields_to_return": [ "_id", "_url", "product_id" ]
  }'
from ximilar.client.search import SimilarityFashionClient

client = SimilarityFashionClient(token='__API_TOKEN__', collection='__COLLECTION_ID__')

result = client.search([{"_url": "__URL_PATH_TO_IMAGE__", "_objects": [ 
         {
           "area": 0.376093738079071,
           "prob": 0.9120546793937683,
           "Top Category": "Clothing",
           "Category": "Clothing/Pants",
           "bound_box": [
             349,
             23,
             646,
             378
           ]
         }
    ]
}])

Just make sure that you copy the whole JSON record of the object (all fields) from the API response.

You can combine the Apparel Detection method and the visual search like this:

  1. call the Apparel Detection method to get all fashion items in the photo (without directly getting similar products),
  2. let your user select the item they are interested in,
  3. use the object JSON record in the subsequent visual search query.

Customization and special features

Following examples are for /v2/insert endpoint. If you want to use this in search (/v2/visualTagsKNN) please use "query_record" dictionary instead of "records" list.

Connect custom flow

Ximilar Custom Image Recognition allows you to train image categorization or tagging models. With Ximilar Flows you can connect these models to powerful complex vision systems with hierarchy. During the insert process to your collection or during the search/query you can call your trained models with Flows. This will add more knowledge/meta information to your product images. This is great if you want to recognize some special tags which are not included in our Fashion Tagging taxonomy. It is working by specifing custom_flow field in your request. There are several requirements for the flow which must be satisfied in order to run it successfully. Just write us and we will discuss the usage with you.

{
    "records": [
        {
            "_url": "__URL_IMAGE__",
            "_tags_custom": ["men"]
        }
    ],
    "custom_flow": "__FLOW_ID__"
}

Use custom profile

Would you like to rename some of our tags or do some other modifications? For example if our tagging system says that the product is 'Dress', 'black', 'mini' we can generate 'black mini dress' tag. This is done by creating custom profile for you. Just write us and we will discuss the usage with you.

{
    "records": [
        {
            "_url": "__URL_IMAGE__",
            "_tags_custom": ["men"]
        }
    ],
    "profile": "__FLOW_ID__"
}

Use custom tags and gender tags

Do you know if your product is for men, women, children or unisex? Then specify this in a record field _tags_custom. You can also add any your tag to _tags_custom.

{
    "records": [
        {
            "_url": "__URL_IMAGE__",
            "_tags_custom": ["men"]
        }
    ]
}

Draw a bounding box in mobile app?

Do you want to use fashion search in your mobile app and let user to draw the object? Just specify it in following way. The format of bounding box is [xmin, ymin, xmax, ymax].

{
    "records": [
        {
            "_url": "__URL_IMAGE__",
            "_objects": [
                {
                    "bound_box": [
                        701,
                        1760,
                        1155,
                        1952
                    ]
                }
            ]
        }
    ]
}