diff --git a/CHANGELOG.md b/CHANGELOG.md index c7b40bae1..00d3293b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ Change Log ========== +## Version 0.10.0 +_2016_09_23_ + +* New: Added `similarity search` to the `Visual Recognition` service. +* Fix: `Touch Widget` improvmements. +* Fix: Disabled 3rd Party plugin warnings. +* Fix: Removed `Conversation` Message overload method that takes only input and conversationID. +* Fix: Rewrote `Conversation` example script to show how to create MessageRequest object. + ## Version 0.9.0 _2016-08-26_ diff --git a/README.md b/README.md index 5b8d79635..4b418dd80 100644 --- a/README.md +++ b/README.md @@ -729,6 +729,251 @@ private void OnRecognizeText(TextRecogTopLevelMultiple multipleImages) } ``` +#### Similarity Search +Beta. You can create and add images to a collection and then search that collection with your own image to find similar images. + +##### List Collections +Beta. List all custom collections. + +```cs +void Start() +{ + m_VisualRecognition.GetCollections(OnGetCollections); +} + +private void OnGetCollections(GetCollections collections, string customData) +{ + if(collections != null) + { + foreach (CreateCollection collection in collections.collections) + { + Log.Debug("VisualRecognitionExample", "collectionID: {0} | collection name: {1} | number of images: {2}", collection.collection_id, collection.name, collection.images); + } + } + else + { + Log.Debug("VisualRecognitionExample", "Get Collections failed!"); + } +} +``` + +##### Create Collection +Beta. Create a new collection of images to search. You can create a maximum of 5 collections. + +```cs +void Start() +{ + m_VisualRecognition.CreateCollection(OnCreateCollection, "unity-integration-test-collection"); +} + +private void OnCreateCollection(CreateCollection collection, string customData) +{ + if(collection != null) + { + Log.Debug("VisualRecognitionExample", "Create Collection succeeded!"); + Log.Debug("VisualRecognitionExample", "collectionID: {0} | collection name: {1} | collection images: {2}", collection.collection_id, collection.name, collection.images); + } + else + { + Log.Debug("VisualRecognitionExample", "Create Collection failed!"); + } +} +``` + +##### Get collection details +Beta. Retrieve information about a specific collection. + +```cs +void Start() +{ + m_VisualRecognition.GetCollection(OnGetCollection, m_CreatedCollectionID); +} + +private void OnGetCollection(CreateCollection collection, string customData) +{ + if (collection != null) + { + Log.Debug("VisualRecognitionExample", "Get Collection succeded!"); + Log.Debug("VisualRecognitionExample", "collectionID: {0} | collection name: {1} | collection images: {2}", collection.collection_id, collection.name, collection.images); + } + else + { + Log.Debug("VisualRecognitionExample", "Get Collection failed!"); + + } +} +``` + +##### Add images to a collection +Beta. Add images to a collection. Each collection can contain 1000000 images. + +```cs +void Start() +{ + string m_collectionImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_to_classify.jpg"; + Dictionary imageMetadata = new Dictionary(); + imageMetadata.Add("key1", "value1"); + imageMetadata.Add("key2", "value2"); + imageMetadata.Add("key3", "value3"); + m_VisualRecognition.AddCollectionImage(OnAddImageToCollection, m_CreatedCollectionID, m_collectionImagePath, imageMetadata); +} +private void OnAddImageToCollection(CollectionsConfig images, string customData) +{ + if(images != null) + { + Log.Debug("VisualRecognitionExample", "Add image to collection succeeded!"); + m_CreatedCollectionImage = images.images[0].image_id; + Log.Debug("VisualRecognitionExample", "images processed: {0}", images.images_processed); + foreach (CollectionImagesConfig image in images.images) + Log.Debug("VisualRecognitionExample", "imageID: {0} | image_file: {1} | image metadata: {1}", image.image_id, image.image_file, image.metadata.ToString()); + } + else + { + Log.Debug("VisualRecognitionExample", "Add image to collection failed!"); + } +} +``` + +##### List images in a collection +Beta. List the first 100 images in a collection. Each collection can contain 1000000 images. + +```cs +void Start() +{ + m_VisualRecognition.GetCollectionImages(OnGetCollectionImages, m_CreatedCollectionID); +} + +private void OnGetCollectionImages(GetCollectionImages collections, string customData) +{ + if(collections != null) + { + Log.Debug("VisualRecognitionExample", "Get Collections succeded!"); + foreach(GetCollectionsBrief collection in collections.images) + Log.Debug("VisualRecognitionExample", "imageID: {0} | image file: {1} | image metadataOnGetCollections: {2}", collection.image_id, collection.image_file, collection.metadata.ToString()); + } + else + { + Log.Debug("VisualRecognitionExample", "Get Collections failed!"); + } +} +``` + +##### List image details +Beta. List details about a specific image in a collection. +```cs +void Start() +{ + m_VisualRecognition.GetImage(OnGetImage, m_CreatedCollectionID, m_CreatedCollectionImage); +} + +private void OnGetImage(GetCollectionsBrief image, string customData) +{ + if(image != null) + { + Log.Debug("VisualRecognitionExample", "GetImage succeeded!"); + Log.Debug("VisualRecognitionExample", "imageID: {0} | created: {1} | image_file: {2} | metadata: {3}", image.image_id, image.created, image.image_file, image.metadata); + } + else + { + Log.Debug("VisualRecognitionExample", "GetImage failed!"); + } +} +``` + +##### List image metadata +Beta. View the metadata for a specific image in a collection. + +```cs +void Start() +{ + m_VisualRecognition.GetMetadata(OnGetMetadata, m_CreatedCollectionID, m_CreatedCollectionImage); +} + +private void OnGetMetadata(object responseObject, string customData) +{ + if(responseObject != null) + Log.Debug("VisualRecognitionExample", "ResponseObject: {0}", responseObject); +} +``` + +##### Find similar images +Beta. Upload an image to find similar images in your custom collection. + +```cs +void Start() +{ + m_VisualRecognition.FindSimilar(OnFindSimilar, m_CreatedCollectionID, m_collectionImagePath); +} + +private void OnFindSimilar(SimilarImagesConfig images, string customData) +{ + if(images != null) + { + Log.Debug("VisualRecognitionExample", "GetSimilar succeeded!"); + Log.Debug("VisualRecognitionExample", "images processed: {0}", images.images_processed); + foreach (SimilarImageConfig image in images.similar_images) + Log.Debug("VisualRecognitionExample", "image ID: {0} | image file: {1} | score: {2} | metadata: {3}", image.image_id, image.image_file, image.score, image.metadata.ToString()); + } + else + { + Log.Debug("VisualRecognitionExample", "GetSimilar failed!"); + } +} +``` + +##### Delete image metadata +Beta. Delete all metadata associated with an image. + +```cs +void Start() +{ + m_VisualRecognition.DeleteCollectionImageMetadata(OnDeleteMetadata, m_CreatedCollectionID, m_CreatedCollectionImage); +} + +private void OnDeleteMetadata(bool success, string customData) +{ + if (success) + Log.Debug("VisualRecognitionExample", "Delete image metadata succeeded!"); + else + Log.Debug("VisualRecognitionExample", "Delete image metadata failed!"); +} +``` + +##### Delete an image +Beta. Delete an image from a collection. + +```cs +void Start() +{ + m_VisualRecognition.DeleteCollectionImage(OnDeleteCollectionImage, m_CreatedCollectionID, m_CreatedCollectionImage); +} + +private void OnDeleteCollectionImage(bool success, string customData) +{ + if (success) + Log.Debug("VisualRecognitionExample", "Delete collection image succeeded!"); + else + Log.Debug("VisualRecognitionExample", "Delete collection image failed!"); +} +``` + +##### Delete a collection +Beta. Delete a user created collection. + +```cs +void Start() +{ + m_VisualRecognition.DeleteCollection(OnDeleteCollection, m_CreatedCollectionID); +} + +private void OnDeleteCollection(bool success, string customData) +{ + if(success) + Log.Debug("VisualRecognitionExample", "Delete Collection succeeded!"); + else + Log.Debug("VisualRecognitionExample", "Delete Collection failed!"); +} +``` ### Alchemy Language Use the [Alchemy Language][alchemy_language] service to extract semantic meta-data from content such as information on people, places, companies, topics, facts, relationships, authors and languages. diff --git a/Scripts/Services/VisualRecognition/DataModels.cs b/Scripts/Services/VisualRecognition/DataModels.cs index 68319db46..563a8d63d 100755 --- a/Scripts/Services/VisualRecognition/DataModels.cs +++ b/Scripts/Services/VisualRecognition/DataModels.cs @@ -19,403 +19,569 @@ namespace IBM.Watson.DeveloperCloud.Services.VisualRecognition.v3 { #region Classify - /// - /// Holds multiple classifications. - /// + /// + /// Holds multiple classifications. + /// [fsObject] public class ClassifyTopLevelMultiple { - /// - /// The number of images processed. - /// + /// + /// The number of images processed. + /// public int images_processed { get; set; } - /// - /// Array of classified images. - /// + /// + /// Array of classified images. + /// public ClassifyTopLevelSingle[] images { get; set; } - /// - /// Array of warnings. - /// + /// + /// Array of warnings. + /// public WarningInfo[] warnings { get; set; } } - /// - /// One classification. - /// + /// + /// One classification. + /// [fsObject] public class ClassifyTopLevelSingle { - /// - /// The source URL. - /// + /// + /// The source URL. + /// public string source_url { get; set; } - /// - /// The resolved URL. - /// + /// + /// The resolved URL. + /// public string resolved_url { get; set; } - /// - /// The Image. - /// + /// + /// The Image. + /// public string image { get; set; } - /// - /// The error. - /// + /// + /// The error. + /// public ErrorInfoNoCode error { get; set; } - /// - /// The classification results. - /// + /// + /// The classification results. + /// public ClassifyPerClassifier[] classifiers { get; set; } } - /// - /// One classifier. - /// + /// + /// One classifier. + /// [fsObject] public class ClassifyPerClassifier { - /// - /// The name. - /// + /// + /// The name. + /// public string name { get; set; } - /// - /// The classifier identifier. - /// + /// + /// The classifier identifier. + /// public string classifier_id { get; set; } - /// - /// Array of classification results. - /// + /// + /// Array of classification results. + /// public ClassResult[] classes { get; set; } } - /// - /// One class result. - /// + /// + /// One class result. + /// [fsObject] public class ClassResult { - /// - /// The class result. - /// + /// + /// The class result. + /// [fsProperty("class")] public string m_class { get; set; } - /// - /// The score. - /// + /// + /// The score. + /// public double score { get; set; } - /// - /// The type hierarchy. - /// + /// + /// The type hierarchy. + /// public string type_hierarchy { get; set; } } - /// - /// The classify parameters. - /// + /// + /// The classify parameters. + /// [fsObject] public class ClassifyParameters { - /// - /// The URL. - /// + /// + /// The URL. + /// public string url { get; set; } - /// - /// The clasifier identifiers. - /// + /// + /// The clasifier identifiers. + /// public string[] classifier_ids { get; set; } - /// - /// The owners. - /// + /// + /// The owners. + /// public string[] owners { get; set; } - /// - /// The classification threshold. - /// + /// + /// The classification threshold. + /// public float threshold { get; set; } } #endregion #region Detect Faces - /// - /// Multiple faces. - /// + /// + /// Multiple faces. + /// [fsObject] public class FacesTopLevelMultiple { - /// - /// Number of images processed. - /// + /// + /// Number of images processed. + /// public int images_processed { get; set; } - /// - /// Array of face classifications. - /// + /// + /// Array of face classifications. + /// public FacesTopLevelSingle[] images { get; set; } - /// - /// Warning info. - /// + /// + /// Warning info. + /// public WarningInfo[] warnings { get; set; } } - /// - /// One face classification. - /// + /// + /// One face classification. + /// [fsObject] public class FacesTopLevelSingle { - /// - /// The source URL. - /// + /// + /// The source URL. + /// public string source_url { get; set; } - /// - /// The resolved URL. - /// + /// + /// The resolved URL. + /// public string resolved_url { get; set; } - /// - /// The image. - /// + /// + /// The image. + /// public string image { get; set; } - /// - /// The error. - /// + /// + /// The error. + /// public ErrorInfoNoCode error { get; set; } - /// - /// The face results. - /// + /// + /// The face results. + /// public OneFaceResult[] faces { get; set; } } - /// - /// One face result. - /// + /// + /// One face result. + /// [fsObject] public class OneFaceResult { - /// - /// The face age. - /// + /// + /// The face age. + /// public Age age { get; set; } - /// - /// The face gender. - /// + /// + /// The face gender. + /// public Gender gender { get; set; } - /// - /// The face location in pixels. - /// + /// + /// The face location in pixels. + /// public FaceLocation face_location { get; set; } - /// - /// The face identity. - /// + /// + /// The face identity. + /// public Identity identity { get; set; } } - /// - /// Detect faces parameters. - /// + /// + /// Detect faces parameters. + /// [fsObject] public class DetectFacesParameters { - /// - /// The face URL. - /// + /// + /// The face URL. + /// public string url { get; set; } } #endregion #region Recognize Text - /// - /// Mulitple text pages. - /// + /// + /// Mulitple text pages. + /// [fsObject] public class TextRecogTopLevelMultiple { - /// - /// Number of images processed. - /// + /// + /// Number of images processed. + /// public int images_processed { get; set; } - /// - /// Array of text image classifications. - /// + /// + /// Array of text image classifications. + /// public TextRecogTopLevelSingle[] images { get; set; } - /// - /// The warnings. - /// + /// + /// The warnings. + /// public WarningInfo[] warnings { get; set; } } - /// - /// One text page. - /// + /// + /// One text page. + /// [fsObject] public class TextRecogTopLevelSingle { - /// - /// The source URL. - /// + /// + /// The source URL. + /// public string source_url { get; set; } - /// - /// The resolved URL. - /// + /// + /// The resolved URL. + /// public string resolved_url { get; set; } - /// - /// The image. - /// + /// + /// The image. + /// public string image { get; set; } - /// - /// The error. - /// + /// + /// The error. + /// public ErrorInfoNoCode error { get; set; } - /// - /// The text. - /// + /// + /// The text. + /// public string text { get; set; } - /// - /// The words. - /// + /// + /// The words. + /// public TextRecogOneWord[] words { get; set; } } - /// - /// One word. - /// + /// + /// One word. + /// [fsObject] public class TextRecogOneWord { - /// - /// The word. - /// + /// + /// The word. + /// public string word { get; set; } - /// - /// The word location in pixels. - /// + /// + /// The word location in pixels. + /// public Location location { get; set; } - /// - /// The classification score. - /// + /// + /// The classification score. + /// public double score { get; set; } - /// - /// The line number. - /// + /// + /// The line number. + /// public double line_number { get; set; } } - /// - /// Word location. - /// + /// + /// Word location. + /// [fsObject] public class Location { - /// - /// The location width. - /// + /// + /// The location width. + /// public double width { get; set; } - /// - /// The location height. - /// + /// + /// The location height. + /// public double height { get; set; } - /// - /// The location left. - /// + /// + /// The location left. + /// public double left { get; set; } - /// - /// The loction top. - /// + /// + /// The loction top. + /// public double top { get; set; } } - /// - /// Recognize text parameters. - /// + /// + /// Recognize text parameters. + /// [fsObject] public class RecognizeTextParameters { - /// - /// The URL. - /// + /// + /// The URL. + /// public string url { get; set; } } #endregion #region Classifiers - /// - /// Classifiers breif. - /// + /// + /// Classifiers breif. + /// [fsObject] public class GetClassifiersTopLevelBrief { - /// - /// Array of classifiers. - /// + /// + /// Array of classifiers. + /// public GetClassifiersPerClassifierBrief[] classifiers { get; set; } } - /// - /// Classifier breif. - /// + /// + /// Classifier breif. + /// [fsObject] public class GetClassifiersPerClassifierBrief { - /// - /// The classifier identifier. - /// + /// + /// The classifier identifier. + /// public string classifier_id { get; set; } - /// - /// The classifier name. - /// + /// + /// The classifier name. + /// public string name { get; set; } } - /// - /// Classifier verbose. - /// + /// + /// Classifier verbose. + /// [fsObject] public class GetClassifiersPerClassifierVerbose { - /// - /// The classifier identifier. - /// + /// + /// The classifier identifier. + /// public string classifier_id { get; set; } - /// - /// The classifier name. - /// + /// + /// The classifier name. + /// public string name { get; set; } - /// - /// The classifier owner. - /// + /// + /// The classifier owner. + /// public string owner { get; set; } - /// - /// The classifier status. - /// + /// + /// The classifier status. + /// public string status { get; set; } - /// - /// The classifier explanation. - /// + /// + /// The classifier explanation. + /// public string explanation { get; set; } - /// - /// The classifier created. - /// + /// + /// The classifier created. + /// public string created { get; set; } - /// - /// Array of classes. - /// + /// + /// Array of classes. + /// public Class[] classes { get; set; } } - /// - /// The class. - /// + /// + /// The class. + /// [fsObject] public class Class { - /// - /// The class. - /// + /// + /// The class. + /// [fsProperty("class")] public string m_Class { get; set; } } #endregion + #region Similarity Search + /// + /// Collecitons response object. + /// + [fsObject] + public class GetCollections + { + /// + /// Array of collections. + /// + public CreateCollection[] collections; + } + + /// + /// A collection. + /// + [fsObject] + public class CreateCollection + { + /// + /// The ID of the new collection. + /// + public string collection_id { get; set; } + /// + /// The ID of the new collection. + /// + public string name { get; set; } + /// + /// The ID of the new collection. + /// + public string created { get; set; } + /// + /// The ID of the new collection. + /// + public int images { get; set; } + /// + /// The status of collection creation. Returns available when the collection is available to add images, and unavailable when the collection is being created or trained. + /// + public string status { get; set; } + /// + /// The number of images possible in the collection. Each collection can contain 1000000 images. + /// + public string capacity { get; set; } + } + + /// + /// Collections brief object. + /// + [fsObject] + public class GetCollectionImages + { + /// + /// Array of collections. + /// + public GetCollectionsBrief[] images { get; set; } + } + + /// + /// Collection brief object. + /// + [fsObject] + public class GetCollectionsBrief + { + /// + /// The unique ID of the image. Save this to add or remove it from the collection. + /// + public string image_id { get; set; } + /// + /// Date the image was added to the collection. + /// + public string created { get; set; } + /// + /// File name of the image. + /// + public string image_file { get; set; } + /// + /// Metadat JSON object (key value pairs). + /// + public object metadata { get; set; } + } + + /// + /// The collections config + /// + [fsObject] + public class CollectionsConfig + { + /// + /// Array of collection images config. + /// + public CollectionImagesConfig[] images { get; set; } + /// + /// The number of images processed in this call. + /// + public int images_processed { get; set; } + } + + /// + /// The collection config. + /// + [fsObject] + public class CollectionImagesConfig + { + /// + /// The unique ID of the image. Save this to add or remove it from the collection. + /// + public string image_id { get; set; } + /// + /// Date the image was added to the collection. + /// + public string created { get; set; } + /// + /// File name of the image. + /// + public string image_file { get; set; } + /// + /// Metadat JSON object (key value pairs). + /// + public object metadata { get; set; } + } + + /// + /// Similar images result. + /// + [fsObject] + public class SimilarImagesConfig + { + /// + /// The similar images. + /// + public SimilarImageConfig[] similar_images { get; set; } + /// + /// The number of images processed in this call. + /// + public int images_processed { get; set; } + } + + /// + /// Similar image result. + /// + [fsObject] + public class SimilarImageConfig + { + /// + /// The unique ID of the image. Save this to add or remove it from the collection. + /// + public string image_id { get; set; } + /// + /// Date the image was added to the collection. + /// + public string created { get; set; } + /// + /// File name of the image. + /// + public string image_file { get; set; } + /// + /// Metadat JSON object (key value pairs). + /// + public object metadata { get; set; } + /// + /// Confidence in the match. + /// + public float score { get; set; } + } + #endregion + #region Common - /// - /// Warning info. - /// + /// + /// Warning info. + /// [fsObject] public class WarningInfo { diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index f35a24a1d..50f82b643 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -41,42 +41,117 @@ public class VisualRecognition : IWatsonService /// Callback used by FindClassifier(). /// /// The classifer found by name. + /// Optional data public delegate void OnFindClassifier(GetClassifiersPerClassifierVerbose classifier, string data); /// /// The callback used by the GetClassifiers() method. /// - /// + /// A brief description of classifiers. + /// Optional data public delegate void OnGetClassifiers(GetClassifiersTopLevelBrief classifiers, string data); /// /// Callback used by the GetClassifier() method. /// /// The classifier found by ID. + /// Optional data public delegate void OnGetClassifier(GetClassifiersPerClassifierVerbose classifier, string data); /// /// This callback is used by the DeleteClassifier() method. /// - /// + /// Success or failure of the delete call. + /// Optional data public delegate void OnDeleteClassifier(bool success, string data); /// /// Callback used by the TrainClassifier() method. /// /// The classifier created. + /// Optional data public delegate void OnTrainClassifier(GetClassifiersPerClassifierVerbose classifier, string data); /// /// This callback is used by the Classify() method. /// - /// + /// Returned classification. + /// Optional data public delegate void OnClassify(ClassifyTopLevelMultiple classify, string data); /// /// This callback is used by the DetectFaces() method. /// - /// + /// Faces Detected. + /// Optional data public delegate void OnDetectFaces(FacesTopLevelMultiple faces, string data); /// /// This callback is used by the RecognizeText() method. /// - /// + /// Text Recognized. + /// Optional data public delegate void OnRecognizeText(TextRecogTopLevelMultiple text, string data); + /// + /// This callback is used by the GetCollections() method. + /// + /// Collections. + /// Optional data + public delegate void OnGetCollections(GetCollections collections, string data); + /// + /// This callback is used by the CreateCollection() method. + /// + /// The created collection. + /// Optional data + public delegate void OnCreateCollection(CreateCollection collection, string data); + /// + /// This callback is used by the DeleteCollection() method. + /// + /// Success of the delete call. + /// Optional data + public delegate void OnDeleteCollection(bool success, string data); + /// + /// This callback is used y the GetCollection() method. + /// + /// The collection. + /// Optional data + public delegate void OnGetCollection(CreateCollection collection, string data); + /// + /// This callback is used by the GetCollectionImages() method. + /// + /// Collection images. + /// Optional data + public delegate void OnGetCollectionImages(GetCollectionImages images, string data); + /// + /// This callback is used by the AddCollectionImage() method. + /// + /// The collection config. + /// Optional data + public delegate void OnAddCollectionImage(CollectionsConfig config, string data); + /// + /// This callback is used by the DeleteCollectionImage() method. + /// + /// Success or failure of deleting collection image. + /// Optional data + public delegate void OnDeleteCollectionImage(bool success, string data); + /// + /// This callback is used by the GetImageDetails() method. + /// + /// The image details. + /// Optional data + public delegate void OnGetImageDetails(GetCollectionsBrief image, string data); + /// + /// This callback is used by the DeleteImageMetadata() method. + /// + /// Success of the delete call. + /// Optional data + public delegate void OnDeleteImageMetadata(bool success, string data); + /// + /// This callback is used by the GetImageMetadata() method. + /// + /// + /// Optional data + public delegate void OnGetImageMetadata(object metadata, string data); + /// + /// This callback is used by the FindSimilar() method. + /// + /// + /// Optional data + public delegate void OnFindSimilar(SimilarImagesConfig similarImages, string data); + /// /// The delegate for loading a file, used by TrainClassifier(). /// @@ -95,6 +170,12 @@ public class VisualRecognition : IWatsonService private const string SERVICE_DETECT_FACES = "/v3/detect_faces"; private const string SERVICE_RECOGNIZE_TEXT = "/v3/recognize_text"; private const string SERVICE_CLASSIFIERS = "/v3/classifiers"; + private const string SERVICE_COLLECTIONS = "/v3/collections"; + private const string SERVICE_COLLECTION = "/v3/collections/{0}"; + private const string SERVICE_COLLECTION_IMAGES = "/v3/collections/{0}/images"; + private const string SERVICE_COLLECTION_IMAGE = "/v3/collections/{0}/images/{1}"; + private const string SERVICE_COLLECTION_IMAGE_METADATA = "/v3/collections/{0}/images/{1}/metadata"; + private const string SERVICE_COLLECTION_FIND_SIMILAR = "/v3/collections/{0}/find_similar"; private static string mp_ApiKey = null; private static fsSerializer sm_Serializer = new fsSerializer(); private const float REQUEST_TIMEOUT = 10.0f * 60.0f; @@ -1087,30 +1168,1067 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res } #endregion - #region private methods - private string GetMimeType(string imagePath) + #region Get Collections + /// + /// Get all collections. + /// + /// The callback. + /// Custom data. + /// Returns true if succeess, false if failure. + public bool GetCollections(OnGetCollections callback, string customData = default(string)) { - string mimeType = ""; - switch(Path.GetExtension(imagePath)) + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, SERVICE_COLLECTIONS); + if (connector == null) + return false; + + GetCollectionsReq req = new GetCollectionsReq(); + req.Callback = callback; + req.Data = customData; + + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetCollectionsResp; + + return connector.Send(req); + } + + private class GetCollectionsReq : RESTConnector.Request + { + /// + /// OnGetCollections callback. + /// + public OnGetCollections Callback { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnGetCollectionsResp(RESTConnector.Request req, RESTConnector.Response resp) + { + GetCollections collections = new GetCollections(); + if(resp.Success) { - case ".jpg": - case ".jpeg": - mimeType = "image/jpeg"; - break; - case ".png": - mimeType = "image/png"; - break; - case ".gif": - mimeType = "image/gif"; - break; - case ".zip": - mimeType = "application/zip"; - break; - default: - throw new WatsonException("Cannot classify unsupported file format " + Path.GetExtension(imagePath) + ". Please use jpg, gif, png or zip!"); + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = collections; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch(Exception e) + { + Log.Error("VisualRecognition", "GetCollections Exception: {0}", e.ToString()); + resp.Success = false; + } } - return mimeType; + if (((GetCollectionsReq)req).Callback != null) + ((GetCollectionsReq)req).Callback(resp.Success ? collections : null, ((GetCollectionsReq)req).Data); + } + #endregion + + #region Create collection + /// + /// Create a new collection of images to search. You can create a maximum of 5 collections. + /// + /// The callback. + /// The name of the created collection. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool CreateCollection(OnCreateCollection callback, string name, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(name)) + throw new ArgumentNullException("name"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, SERVICE_COLLECTIONS); + if (connector == null) + return false; + + CreateCollectionReq req = new CreateCollectionReq(); + req.Callback = callback; + req.Name = name; + req.Data = customData; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Forms = new Dictionary(); + req.Forms["name"] = new RESTConnector.Form(name); + req.Forms["disregard"] = new RESTConnector.Form(new byte[4]); + + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnCreateCollectionResp; + + return connector.Send(req); + } + + private class CreateCollectionReq : RESTConnector.Request + { + /// + /// OnCreateCollection callback. + /// + public OnCreateCollection Callback { get; set; } + /// + /// Name of the collection to create. + /// + public string Name { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnCreateCollectionResp(RESTConnector.Request req, RESTConnector.Response resp) + { + CreateCollection collection = new CreateCollection(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = collection; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "OnCreateCollectionResp Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((CreateCollectionReq)req).Callback != null) + ((CreateCollectionReq)req).Callback(resp.Success ? collection : null, ((CreateCollectionReq)req).Data); + } + #endregion + + #region Delete Collection + /// + /// Deletes a collection. + /// + /// The OnDeleteCollection callback. + /// The collection identifier to delete. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool DeleteCollection(OnDeleteCollection callback, string collectionID, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION, collectionID)); + if (connector == null) + return false; + + DeleteCollectionReq req = new DeleteCollectionReq(); + req.Callback = callback; + req.CollectionID = collectionID; + req.Data = customData; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Delete = true; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnDeleteCollectionResp; + + return connector.Send(req); + } + + private class DeleteCollectionReq : RESTConnector.Request + { + /// + /// OnDeleteCollection callback. + /// + public OnDeleteCollection Callback { get; set; } + /// + /// Collection identifier of the collection to be deleted. + /// + public string CollectionID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnDeleteCollectionResp(RESTConnector.Request req, RESTConnector.Response resp) + { + if (((DeleteCollectionReq)req).Callback != null) + ((DeleteCollectionReq)req).Callback(resp.Success, ((DeleteCollectionReq)req).Data); + } + #endregion + + #region Get Collection + /// + /// Retrieve information about a specific collection. Only user-created collections can be specified. + /// + /// The callback. + /// The requested collection identifier. + /// Custom data. + /// Returns true if succeess, false if failure. + public bool GetCollection(OnGetCollection callback, string collectionID, string customData = default(string)) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException(collectionID); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION, collectionID)); + if (connector == null) + return false; + + GetCollectionReq req = new GetCollectionReq(); + req.Callback = callback; + req.Data = customData; + req.CollectionID = collectionID; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetCollectionResp; + + return connector.Send(req); + } + + private class GetCollectionReq : RESTConnector.Request + { + /// + /// OnGetCollections callback. + /// + public OnGetCollection Callback { get; set; } + /// + /// Collection identifier of the requested collection. + /// + public string CollectionID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnGetCollectionResp(RESTConnector.Request req, RESTConnector.Response resp) + { + CreateCollection collection = new CreateCollection(); + if(resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = collection; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch(Exception e) + { + Log.Error("VisualRecognition", "GetCollection Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((GetCollectionReq)req).Callback != null) + ((GetCollectionReq)req).Callback(resp.Success ? collection : null, ((GetCollectionReq)req).Data); + } + #endregion + + #region Get Collection Images + /// + /// List 100 images in a collection + /// + /// The callback. + /// The requested collection identifier. + /// Custom data. + /// Returns true if succeess, false if failure. + public bool GetCollectionImages(OnGetCollectionImages callback, string collectionID, string customData = default(string)) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException(collectionID); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGES, collectionID)); + if (connector == null) + return false; + + GetCollectionImagesReq req = new GetCollectionImagesReq(); + req.Callback = callback; + req.Data = customData; + req.CollectionID = collectionID; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetCollectionImagesResp; + + return connector.Send(req); + } + + private class GetCollectionImagesReq : RESTConnector.Request + { + /// + /// OnGetCollections callback. + /// + public OnGetCollectionImages Callback { get; set; } + /// + /// Collection identifier of the requested collection. + /// + public string CollectionID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnGetCollectionImagesResp(RESTConnector.Request req, RESTConnector.Response resp) + { + GetCollectionImages collectionImages = new GetCollectionImages(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = collectionImages; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "GetCollectionImages Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((GetCollectionImagesReq)req).Callback != null) + ((GetCollectionImagesReq)req).Callback(resp.Success ? collectionImages : null, ((GetCollectionImagesReq)req).Data); + } + #endregion + + #region Add Collection Images + /// + /// Add an image to a collection via image path on file system and metadata as dictionary. + /// + /// The callback. + /// The identifier of the collection to add images to. + /// The path in the filesystem of the image to add. + /// Optional Dictionary key value pairs of metadata associated with the specified image. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool AddCollectionImage(OnAddCollectionImage callback, string collectionID, string imagePath, Dictionary metadata = null, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(imagePath)) + throw new ArgumentNullException("imagePath"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + byte[] imageData = null; + if (!string.IsNullOrEmpty(imagePath)) + { + if (LoadFile != null) + { + imageData = LoadFile(imagePath); + } + else + { +#if !UNITY_WEBPLAYER + imageData = File.ReadAllBytes(imagePath); +#endif + } + + if (imageData == null) + Log.Error("VisualRecognition", "Failed to upload {0}!", imagePath); + } + + return AddCollectionImage(callback, collectionID, imageData, Path.GetFileName(imagePath), GetMetadataJson(metadata), customData); + } + + /// + /// Add an image to a collection via image path on file system and metadata path on file system. + /// + /// The callback. + /// The identifier of the collection to add images to. + /// The path in the filesystem of the image to add. + /// Optional path to metadata json associated with the specified image. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool AddCollectionImage(OnAddCollectionImage callback, string collectionID, string imagePath, string metadataPath = null, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(imagePath)) + throw new ArgumentNullException("imagePath"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + byte[] imageData = null; + if (!string.IsNullOrEmpty(imagePath)) + { + if (LoadFile != null) + { + imageData = LoadFile(imagePath); + } + else + { +#if !UNITY_WEBPLAYER + imageData = File.ReadAllBytes(imagePath); +#endif + } + + if (imageData == null) + Log.Error("VisualRecognition", "Failed to upload {0}!", imagePath); + } + + string metadata = null; + if (!string.IsNullOrEmpty(metadataPath)) + { + metadata = File.ReadAllText(metadataPath); + + if (string.IsNullOrEmpty(metadata)) + Log.Error("VisualRecognition", "Failed to read {0}!", imagePath); + } + + return AddCollectionImage(callback, collectionID, imageData, Path.GetFileName(imagePath), metadata, customData); + } + + /// + /// Add an image to a collection. + /// + /// The callback. + /// The identifier of the collection to add images to. + /// The byte[] data of the image to add. + /// Optional json metadata associated with the specified image. + /// Optional custom data. + /// + public bool AddCollectionImage(OnAddCollectionImage callback, string collectionID, byte[] imageData, string filename, string metadata = null, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (imageData == default(byte[])) + throw new WatsonException("Image data is required!"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGES, collectionID)); + if (connector == null) + return false; + + AddCollectionImageReq req = new AddCollectionImageReq(); + req.Callback = callback; + req.CollectionID = collectionID; + req.ImageData = imageData; + req.Metadata = metadata; + req.Data = customData; + + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Forms = new Dictionary(); + req.Forms["image_file"] = new RESTConnector.Form(imageData, filename, GetMimeType(filename)); + req.Forms["metadata"] = new RESTConnector.Form(Encoding.UTF8.GetBytes(metadata), "application/json"); + + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnAddCollectionImageResp; + + return connector.Send(req); + } + + private class AddCollectionImageReq : RESTConnector.Request + { + /// + /// OnCreateCollection callback. + /// + public OnAddCollectionImage Callback { get; set; } + /// + /// The collection identifier to add images to. + /// + public string CollectionID { get; set; } + /// + /// Byte array of Image Data to add to the collection. + /// + public byte[] ImageData { get; set; } + /// + /// Json metadata associated with this image. + /// + public string Metadata { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnAddCollectionImageResp(RESTConnector.Request req, RESTConnector.Response resp) + { + CollectionsConfig collectionsConfig = new CollectionsConfig(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = collectionsConfig; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "OnCreateCollectionResp Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((AddCollectionImageReq)req).Callback != null) + ((AddCollectionImageReq)req).Callback(resp.Success ? collectionsConfig : null, ((AddCollectionImageReq)req).Data); + } + #endregion + + #region Delete Image + /// + /// Deletes an image from a collection. + /// + /// The OnDeleteCollection callback. + /// The collection identifier holding the image to delete. + /// The identifier of the image to delete. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool DeleteCollectionImage(OnDeleteCollectionImage callback, string collectionID, string imageID, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(imageID)) + throw new ArgumentNullException("imageID"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGE, collectionID, imageID)); + if (connector == null) + return false; + + DeleteCollectionImageReq req = new DeleteCollectionImageReq(); + req.Callback = callback; + req.CollectionID = collectionID; + req.ImageID = imageID; + req.Data = customData; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Delete = true; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnDeleteCollectionImageResp; + + return connector.Send(req); + } + + private class DeleteCollectionImageReq : RESTConnector.Request + { + /// + /// OnDeleteCollection callback. + /// + public OnDeleteCollectionImage Callback { get; set; } + /// + /// Collection identifier containing the image to be deleted. + /// + public string CollectionID { get; set; } + /// + /// The identifier of the image to be deleted. + /// + public string ImageID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnDeleteCollectionImageResp(RESTConnector.Request req, RESTConnector.Response resp) + { + if (((DeleteCollectionImageReq)req).Callback != null) + ((DeleteCollectionImageReq)req).Callback(resp.Success, ((DeleteCollectionImageReq)req).Data); + } + #endregion + + #region Get Image + /// + /// List an image's details. + /// + /// The callback. + /// The requested collection identifier. + /// Custom data. + /// Returns true if succeess, false if failure. + public bool GetImage(OnGetImageDetails callback, string collectionID, string imageID, string customData = default(string)) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException(collectionID); + if (string.IsNullOrEmpty(imageID)) + throw new ArgumentNullException(imageID); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGE, collectionID, imageID)); + if (connector == null) + return false; + + GetCollectionImageReq req = new GetCollectionImageReq(); + req.Callback = callback; + req.Data = customData; + req.CollectionID = collectionID; + req.ImageID = imageID; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetCollectionImageResp; + + return connector.Send(req); + } + + private class GetCollectionImageReq : RESTConnector.Request + { + /// + /// OnGetCollections callback. + /// + public OnGetImageDetails Callback { get; set; } + /// + /// Collection identifier of the requested collection. + /// + public string CollectionID { get; set; } + /// + /// Image identifier for the requested collection. + /// + public string ImageID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnGetCollectionImageResp(RESTConnector.Request req, RESTConnector.Response resp) + { + GetCollectionsBrief image = new GetCollectionsBrief(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = image; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "GetCollectionImage Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((GetCollectionImageReq)req).Callback != null) + ((GetCollectionImageReq)req).Callback(resp.Success ? image : null, ((GetCollectionImageReq)req).Data); + } + #endregion + + #region Delete Image Metadata + /// + /// Deletes an image metadata. + /// + /// The Callback. + /// The collection identifier holding the image metadata to delete. + /// The identifier of the image metadata to delete. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool DeleteCollectionImageMetadata(OnDeleteImageMetadata callback, string collectionID, string imageID, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(imageID)) + throw new ArgumentNullException("imageID"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGE_METADATA, collectionID, imageID)); + if (connector == null) + return false; + + DeleteCollectionImageMetadataReq req = new DeleteCollectionImageMetadataReq(); + req.Callback = callback; + req.CollectionID = collectionID; + req.ImageID = imageID; + req.Data = customData; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Delete = true; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnDeleteCollectionImageMetadataResp; + + return connector.Send(req); + } + + private class DeleteCollectionImageMetadataReq : RESTConnector.Request + { + /// + /// OnDeleteCollection callback. + /// + public OnDeleteImageMetadata Callback { get; set; } + /// + /// Collection identifier containing the image to be deleted. + /// + public string CollectionID { get; set; } + /// + /// The identifier of the image to be deleted. + /// + public string ImageID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnDeleteCollectionImageMetadataResp(RESTConnector.Request req, RESTConnector.Response resp) + { + if (((DeleteCollectionImageMetadataReq)req).Callback != null) + ((DeleteCollectionImageMetadataReq)req).Callback(resp.Success, ((DeleteCollectionImageMetadataReq)req).Data); + } + #endregion + + #region List Image Metadata + /// + /// List image metadata.. + /// + /// The callback. + /// The requested collection identifier. + /// The requested image identifier. + /// Custom data. + /// Returns true if succeess, false if failure. + public bool GetMetadata(OnGetImageMetadata callback, string collectionID, string imageID, string customData = default(string)) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException(collectionID); + if (string.IsNullOrEmpty(imageID)) + throw new ArgumentNullException(imageID); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGE_METADATA, collectionID, imageID)); + if (connector == null) + return false; + + GetCollectionImageMetadataReq req = new GetCollectionImageMetadataReq(); + req.Callback = callback; + req.Data = customData; + req.CollectionID = collectionID; + req.ImageID = imageID; + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetCollectionImageMetadataResp; + + return connector.Send(req); + } + + private class GetCollectionImageMetadataReq : RESTConnector.Request + { + /// + /// OnGetCollections callback. + /// + public OnGetImageMetadata Callback { get; set; } + /// + /// Collection identifier of the requested metadata. + /// + public string CollectionID { get; set; } + /// + /// Image identifier for the requested metadata. + /// + public string ImageID { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnGetCollectionImageMetadataResp(RESTConnector.Request req, RESTConnector.Response resp) + { + GetCollectionsBrief image = new GetCollectionsBrief(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = image; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "GetCollectionImage Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((GetCollectionImageMetadataReq)req).Callback != null) + ((GetCollectionImageMetadataReq)req).Callback(resp.Success ? image : null, ((GetCollectionImageMetadataReq)req).Data); + } + #endregion + + #region Find Similar Images + /// + /// Find Similar Images by image path. + /// + /// The callback. + /// The identifier of the collection to add images to. + /// The path in the filesystem of the image to query. + /// The number of similar results you want returned. Default limit is 10 results, you can specify a maximum limit of 100 results. + /// Optional custom data. + /// Returns true if succeess, false if failure. + public bool FindSimilar(OnFindSimilar callback, string collectionID, string imagePath, int limit = 10, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (string.IsNullOrEmpty(imagePath)) + throw new ArgumentNullException("imagePath"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + byte[] imageData = null; + if (!string.IsNullOrEmpty(imagePath)) + { + if (LoadFile != null) + { + imageData = LoadFile(imagePath); + } + else + { +#if !UNITY_WEBPLAYER + imageData = File.ReadAllBytes(imagePath); +#endif + } + + if (imageData == null) + Log.Error("VisualRecognition", "Failed to upload {0}!", imagePath); + } + + return FindSimilar(callback, collectionID, imageData, limit, customData); + } + + /// + /// Find Similar Images by byte[]. + /// + /// The callback. + /// The identifier of the collection to add images to. + /// The byte[] data of the image to query. + /// The number of similar results you want returned. Default limit is 10 results, you can specify a maximum limit of 100 results. + /// Optional custom data. + /// + public bool FindSimilar(OnFindSimilar callback, string collectionID, byte[] imageData, int limit = 10, string customData = null) + { + if (callback == null) + throw new ArgumentNullException("callback"); + if (string.IsNullOrEmpty(collectionID)) + throw new ArgumentNullException("collectionID"); + if (imageData == default(byte[])) + throw new WatsonException("Image data is required!"); + if (string.IsNullOrEmpty(mp_ApiKey)) + mp_ApiKey = Config.Instance.GetAPIKey(SERVICE_ID); + if (string.IsNullOrEmpty(mp_ApiKey)) + throw new WatsonException("No API Key was found!"); + + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_FIND_SIMILAR, collectionID)); + if (connector == null) + return false; + + FindSimilarReq req = new FindSimilarReq(); + req.Callback = callback; + req.CollectionID = collectionID; + req.ImageData = imageData; + req.Limit = limit; + req.Data = customData; + + req.Parameters["api_key"] = mp_ApiKey; + req.Parameters["version"] = VisualRecognitionVersion.Version; + req.Forms = new Dictionary(); + req.Forms["image_file"] = new RESTConnector.Form(imageData); + + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnFindSimilarResp; + + return connector.Send(req); + } + + private class FindSimilarReq : RESTConnector.Request + { + /// + /// OnCreateCollection callback. + /// + public OnFindSimilar Callback { get; set; } + /// + /// The collection identifier to add images to. + /// + public string CollectionID { get; set; } + /// + /// Byte array of Image Data to add to the collection. + /// + public byte[] ImageData { get; set; } + /// + /// Json metadata associated with this image. + /// + public int Limit { get; set; } + /// + /// Optional data. + /// + public string Data { get; set; } + } + + private void OnFindSimilarResp(RESTConnector.Request req, RESTConnector.Response resp) + { + SimilarImagesConfig config = new SimilarImagesConfig(); + if (resp.Success) + { + try + { + fsData data = null; + fsResult r = fsJsonParser.Parse(Encoding.UTF8.GetString(resp.Data), out data); + + object obj = config; + r = sm_Serializer.TryDeserialize(data, obj.GetType(), ref obj); + + if (!r.Succeeded) + throw new WatsonException(r.FormattedMessages); + } + catch (Exception e) + { + Log.Error("VisualRecognition", "OnCreateCollectionResp Exception: {0}", e.ToString()); + resp.Success = false; + } + } + + if (((FindSimilarReq)req).Callback != null) + ((FindSimilarReq)req).Callback(resp.Success ? config : null, ((FindSimilarReq)req).Data); + } + #endregion + + #region private methods + private string GetMimeType(string imagePath) + { + string mimeType = ""; + switch(Path.GetExtension(imagePath)) + { + case ".jpg": + case ".jpeg": + mimeType = "image/jpeg"; + break; + case ".png": + mimeType = "image/png"; + break; + case ".gif": + mimeType = "image/gif"; + break; + case ".zip": + mimeType = "application/zip"; + break; + default: + throw new WatsonException("Cannot classify unsupported file format " + Path.GetExtension(imagePath) + ". Please use jpg, gif, png or zip!"); + } + + return mimeType; + } + + private string GetMetadataJson(Dictionary metadata) + { + string json = "{"; + string metadataItem = "\n\t\"{0}\":\"{1}\""; + + int i = 0; + foreach (KeyValuePair kv in metadata) + { + i++; + string comma = i < metadata.Count ? "," : ""; + json += string.Format(metadataItem, kv.Key, kv.Value) + comma; + } + + //for(int i = 0; i < metadata.Count; i++) + //{ + // KeyValuePair kv = metadata.; + // string comma = i < metadata.Count - 1 ? "," : ""; + // json += string.Format(metadataItem, kv.Key, kv.Value) + comma; + //} + + json += "\n}"; + + return json; } #endregion diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognition.cs index 650bc5de9..864edf964 100755 --- a/Scripts/UnitTests/TestVisualRecognition.cs +++ b/Scripts/UnitTests/TestVisualRecognition.cs @@ -42,8 +42,21 @@ public class TestVisualRecognition : UnitTest bool m_DetectFacesPOSTTested = false; bool m_RecognizeTextGETTested = false; bool m_RecognizeTextPOSTTested = false; - bool m_DeleteTested = false; - + bool m_DeleteClassifierTested = false; + + bool m_ListCollectionsTested = false; + bool m_CreateCollectionTested = false; + bool m_DeleteCollectionTested = false; + bool m_RetrieveCollectionDetailsTested = false; + bool m_ListImagesTested = false; + bool m_AddImagesToCollectionTested = false; + bool m_DeleteImageFromCollectionTested = false; + bool m_ListImageDetailsTested = false; + bool m_DeleteImageMetadataTested = false; + bool m_ListImageMetadataTested = false; + bool m_FindSimilarTested = false; + + bool m_TrainClassifier = false; bool m_IsClassifierReady = false; bool m_HasUpdatedClassifier = false; @@ -56,123 +69,196 @@ public class TestVisualRecognition : UnitTest private string m_ImageFaceURL = "https://upload.wikimedia.org/wikipedia/commons/e/e9/Official_portrait_of_Barack_Obama.jpg"; // Obama image private string m_ImageTextURL = "http://i.stack.imgur.com/ZS6nH.png"; // image with text + private string m_CreatedCollectionID; + private string m_CreatedCollectionImage; + public override IEnumerator RunTest() { - // test get classifiers - Log.Debug("TestVisualRecognition", "Getting all classifiers!"); - m_VisualRecognition.GetClassifiers(OnGetClassifiers); - while (!m_GetClassifiersTested) + // test get classifiers + Log.Debug("TestVisualRecognition", "Getting all classifiers!"); + m_VisualRecognition.GetClassifiers(OnGetClassifiers); + while (!m_GetClassifiersTested) + yield return null; + + // test find classifier + Log.Debug("TestVisualRecognition", "Finding classifier {0}!", m_ClassifierName); + m_VisualRecognition.FindClassifier(OnFindClassifier, m_ClassifierName); + while (!m_FindClassifierTested) + yield return null; + + if (m_TrainClassifier) + { + // test train classifier + Log.Debug("TestVisualRecognition", "Training classifier!"); + string m_positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip"; + string m_negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip"; + Dictionary positiveExamples = new Dictionary(); + positiveExamples.Add(m_ClassName_Giraffe, m_positiveExamplesPath); + Test(m_VisualRecognition.TrainClassifier(OnTrainClassifier, m_ClassifierName, positiveExamples, m_negativeExamplesPath)); + while (!m_TrainClasifierTested) + yield return null; + } + + // Wait until classifier is ready + if (!m_IsClassifierReady) + { + Log.Debug("TestVisualRecognition", "Checking classifier {0} status!", m_ClassifierId); + CheckClassifierStatus(OnCheckClassifierStatus); + while (!m_IsClassifierReady) + yield return null; + } + + if (!string.IsNullOrEmpty(m_ClassifierId)) + { + // test get classifier + Log.Debug("TestVisualRecognition", "Getting classifier {0}!", m_ClassifierId); + m_VisualRecognition.GetClassifier(OnGetClassifier, m_ClassifierId); + while (!m_GetClassifierTested) + yield return null; + + // Update classifier + Log.Debug("TestVisualRecognition", "Updating classifier {0}", m_ClassifierId); + string m_positiveUpdated = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/turtle_positive_examples.zip"; + Dictionary positiveUpdatedExamples = new Dictionary(); + positiveUpdatedExamples.Add(m_ClassName_Turtle, m_positiveUpdated); + m_VisualRecognition.UpdateClassifier(OnUpdateClassifier, m_ClassifierId, m_ClassifierName, positiveUpdatedExamples); + while (!m_UpdateClassifierTested) + yield return null; + + // Wait for updated classifier to be ready. + Log.Debug("TestVisualRecognition", "Checking updated classifier {0} status!", m_ClassifierId); + CheckClassifierStatus(OnCheckUpdatedClassifierStatus); + while (!m_IsUpdatedClassifierReady) + yield return null; + + string[] m_owners = { "IBM", "me" }; + string[] m_classifierIds = { "default", m_ClassifierId }; + + // test classify image get + Log.Debug("TestVisualRecognition", "Classifying image using GET!"); + m_VisualRecognition.Classify(OnClassifyGet, m_ImageURL, m_owners, m_classifierIds); + while (!m_ClassifyGETTested) + yield return null; + + // test classify image post + Log.Debug("TestVisualRecognition", "Classifying image using POST!"); + string m_classifyImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_to_classify.jpg"; + m_VisualRecognition.Classify(m_classifyImagePath, OnClassifyPost, m_owners, m_classifierIds); + while (!m_ClassifyPOSTTested) + yield return null; + } + + // test detect faces get + Log.Debug("TestVisualRecognition", "Detecting face image using GET!"); + m_VisualRecognition.DetectFaces(OnDetectFacesGet, m_ImageFaceURL); + while (!m_DetectFacesGETTested) + yield return null; + + // test detect faces post + Log.Debug("TestVisualRecognition", "Detecting face image using POST!"); + string m_detectFaceImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/obama.jpg"; + m_VisualRecognition.DetectFaces(m_detectFaceImagePath, OnDetectFacesPost); + while (!m_DetectFacesPOSTTested) + yield return null; + + // test recognize text get + Log.Debug("TestVisualRecognition", "Recognizing text image using GET!"); + m_VisualRecognition.RecognizeText(OnRecognizeTextGet, m_ImageTextURL); + while (!m_RecognizeTextGETTested) + yield return null; + + // test recognize text post + Log.Debug("TestVisualRecognition", "Recognizing text image using POST!"); + string m_recognizeTextImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/from_platos_apology.png"; + m_VisualRecognition.RecognizeText(m_recognizeTextImagePath, OnRecognizeTextPost); + while (!m_RecognizeTextPOSTTested) + yield return null; + + // test delete classifier + Log.Debug("TestVisualRecognition", "Deleting classifier {0}!", m_ClassifierId); + m_VisualRecognition.DeleteClassifier(OnDeleteClassifier, m_ClassifierId); + while (!m_DeleteClassifierTested) + yield return null; + + // test list collections + Log.Debug("TestVisualRecognition", "Attempting to list collections!"); + m_VisualRecognition.GetCollections(OnGetCollections); + while (!m_ListCollectionsTested) yield return null; - - // test find classifier - Log.Debug("TestVisualRecognition", "Finding classifier {0}!", m_ClassifierName); - m_VisualRecognition.FindClassifier(OnFindClassifier, m_ClassifierName); - while(!m_FindClassifierTested) + + // test create collection + Log.Debug("TestVisualRecognition", "Attempting to create collection!"); + m_VisualRecognition.CreateCollection(OnCreateCollection, "unity-integration-test-collection"); + while (!m_CreateCollectionTested) yield return null; - - if(m_TrainClassifier) - { - // test train classifier - Log.Debug("TestVisualRecognition", "Training classifier!"); - string m_positiveExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_positive_examples.zip"; - string m_negativeExamplesPath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/negative_examples.zip"; - Dictionary positiveExamples = new Dictionary(); - positiveExamples.Add(m_ClassName_Giraffe, m_positiveExamplesPath); - Test(m_VisualRecognition.TrainClassifier(OnTrainClassifier, m_ClassifierName, positiveExamples, m_negativeExamplesPath)); - while(!m_TrainClasifierTested) - yield return null; - } - // Wait until classifier is ready - if(!m_IsClassifierReady) - { - Log.Debug("TestVisualRecognition", "Checking classifier {0} status!", m_ClassifierId); - CheckClassifierStatus(OnCheckClassifierStatus); - while (!m_IsClassifierReady) - yield return null; - } - - if(!string.IsNullOrEmpty(m_ClassifierId)) - { - // test get classifier - Log.Debug("TestVisualRecognition", "Getting classifier {0}!", m_ClassifierId); - m_VisualRecognition.GetClassifier(OnGetClassifier, m_ClassifierId); - while(!m_GetClassifierTested) - yield return null; - - // Update classifier - Log.Debug("TestVisualRecognition", "Updating classifier {0}", m_ClassifierId); - string m_positiveUpdated = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/turtle_positive_examples.zip"; - Dictionary positiveUpdatedExamples = new Dictionary(); - positiveUpdatedExamples.Add(m_ClassName_Turtle, m_positiveUpdated); - m_VisualRecognition.UpdateClassifier(OnUpdateClassifier, m_ClassifierId, m_ClassifierName, positiveUpdatedExamples); - while (!m_UpdateClassifierTested) - yield return null; - - // Wait for updated classifier to be ready. - Log.Debug("TestVisualRecognition", "Checking updated classifier {0} status!", m_ClassifierId); - CheckClassifierStatus(OnCheckUpdatedClassifierStatus); - while (!m_IsUpdatedClassifierReady) - yield return null; - - string[] m_owners = {"IBM", "me"}; - string[] m_classifierIds = {"default", m_ClassifierId}; - - // test classify image get - Log.Debug("TestVisualRecognition", "Classifying image using GET!"); - m_VisualRecognition.Classify(OnClassifyGet, m_ImageURL, m_owners, m_classifierIds); - while(!m_ClassifyGETTested) - yield return null; - - // test classify image post - Log.Debug("TestVisualRecognition", "Classifying image using POST!"); - string m_classifyImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_to_classify.jpg"; - m_VisualRecognition.Classify(m_classifyImagePath, OnClassifyPost, m_owners, m_classifierIds); - while(!m_ClassifyPOSTTested) - yield return null; - } + // test retrive collection details + Log.Debug("TestVisualRecognition", "Attempting to retrieve collection details!"); + m_VisualRecognition.GetCollection(OnGetCollection, m_CreatedCollectionID); + while (!m_RetrieveCollectionDetailsTested) + yield return null; - // test detect faces get - Log.Debug("TestVisualRecognition", "Detecting face image using GET!"); - m_VisualRecognition.DetectFaces(OnDetectFacesGet, m_ImageFaceURL); - while(!m_DetectFacesGETTested) + // test add images to collection + Log.Debug("TestVisualRecognition", "Attempting to add images to collection!"); + string m_collectionImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/giraffe_to_classify.jpg"; + Dictionary imageMetadata = new Dictionary(); + imageMetadata.Add("key1", "value1"); + imageMetadata.Add("key2", "value2"); + imageMetadata.Add("key3", "value3"); + m_VisualRecognition.AddCollectionImage(OnAddImageToCollection, m_CreatedCollectionID, m_collectionImagePath, imageMetadata); + while (!m_AddImagesToCollectionTested) yield return null; - // test detect faces post - Log.Debug("TestVisualRecognition", "Detecting face image using POST!"); - string m_detectFaceImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/obama.jpg"; - m_VisualRecognition.DetectFaces(m_detectFaceImagePath, OnDetectFacesPost); - while(!m_DetectFacesPOSTTested) + // test list images + Log.Debug("TestVisualRecognition", "Attempting to list images!"); + m_VisualRecognition.GetCollectionImages(OnGetCollectionImages, m_CreatedCollectionID); + while (!m_ListImagesTested) yield return null; - // test recognize text get - Log.Debug("TestVisualRecognition", "Recognizing text image using GET!"); - m_VisualRecognition.RecognizeText(OnRecognizeTextGet, m_ImageTextURL); - while(!m_RecognizeTextGETTested) + // test list image details + Log.Debug("TestVisualRecognition", "Attempting to list image details!"); + m_VisualRecognition.GetImage(OnGetImage, m_CreatedCollectionID, m_CreatedCollectionImage); + while (!m_ListImageDetailsTested) yield return null; - // test recognize text post - Log.Debug("TestVisualRecognition", "Recognizing text image using POST!"); - string m_recognizeTextImagePath = Application.dataPath + "/Watson/Examples/ServiceExamples/TestData/visual-recognition-classifiers/from_platos_apology.png"; - m_VisualRecognition.RecognizeText(m_recognizeTextImagePath, OnRecognizeTextPost); - while(!m_RecognizeTextPOSTTested) + // test list image metadata + Log.Debug("TestVisualRecognition", "Attempting to list image metadata!"); + m_VisualRecognition.GetMetadata(OnGetMetadata, m_CreatedCollectionID, m_CreatedCollectionImage); + while (!m_ListImageMetadataTested) yield return null; - // test delete classifier - Log.Debug("TestVisualRecognition", "Deleting classifier {0}!", m_ClassifierId); - m_VisualRecognition.DeleteClassifier(OnDeleteClassifier, m_ClassifierId); - while(!m_DeleteTested) + // test find similar + Log.Debug("TestVisualRecognition", "Attempting to find similar!"); + m_VisualRecognition.FindSimilar(OnFindSimilar, m_CreatedCollectionID, m_collectionImagePath); + while (!m_FindSimilarTested) yield return null; + // test delete image metadata + Log.Debug("TestVisualRecognition", "Attempting to delete metadata!"); + m_VisualRecognition.DeleteCollectionImageMetadata(OnDeleteMetadata, m_CreatedCollectionID, m_CreatedCollectionImage); + while (!m_DeleteImageMetadataTested) + yield return null; + + // test delete image from collection + Log.Debug("TestVisualRecognition", "Attempting to delete image from collection!"); + m_VisualRecognition.DeleteCollectionImage(OnDeleteCollectionImage, m_CreatedCollectionID, m_CreatedCollectionImage); + while (!m_DeleteImageFromCollectionTested) + yield return null; + + // test delete collection + Log.Debug("TestVisualRecognition", "Attempting to delete collection!"); + m_VisualRecognition.DeleteCollection(OnDeleteCollection, m_CreatedCollectionID); + while (!m_DeleteCollectionTested) + yield return null; yield break; } - + private void OnFindClassifier(GetClassifiersPerClassifierVerbose classifier, string customData) { if (classifier != null) { Log.Status("TestVisualRecognition", "Find Result, Classifier ID: {0}, Status: {1}", classifier.classifier_id, classifier.status); - if(classifier.status == "ready") + if (classifier.status == "ready") { m_TrainClassifier = false; m_IsClassifierReady = true; @@ -204,16 +290,16 @@ private void OnTrainClassifier(GetClassifiersPerClassifierVerbose classifier, st m_TrainClasifierTested = true; } - private void OnGetClassifiers (GetClassifiersTopLevelBrief classifiers, string customData) + private void OnGetClassifiers(GetClassifiersTopLevelBrief classifiers, string customData) { Test(classifiers != null); - if(classifiers != null && classifiers.classifiers.Length > 0) + if (classifiers != null && classifiers.classifiers.Length > 0) { Log.Debug("TestVisualRecognition", "{0} classifiers found!", classifiers.classifiers.Length); -// foreach(GetClassifiersPerClassifierBrief classifier in classifiers.classifiers) -// { -// Log.Debug("TestVisualRecognition", "Classifier: " + classifier.name + ", " + classifier.classifier_id); -// } + // foreach(GetClassifiersPerClassifierBrief classifier in classifiers.classifiers) + // { + // Log.Debug("TestVisualRecognition", "Classifier: " + classifier.name + ", " + classifier.classifier_id); + // } } else { @@ -226,7 +312,7 @@ private void OnGetClassifiers (GetClassifiersTopLevelBrief classifiers, string c private void OnGetClassifier(GetClassifiersPerClassifierVerbose classifier, string customData) { Test(classifier != null); - if(classifier != null) + if (classifier != null) { Log.Debug("TestVisualRecognition", "Classifier {0} found! Classifier name: {1}", classifier.classifier_id, classifier.name); foreach (Class classifierClass in classifier.classes) @@ -255,16 +341,16 @@ private void OnUpdateClassifier(GetClassifiersPerClassifierVerbose classifier, s private void OnClassifyGet(ClassifyTopLevelMultiple classify, string customData) { Test(classify != null); - if(classify != null) + if (classify != null) { Log.Debug("TestVisualRecognition", "ClassifyImage GET images processed: " + classify.images_processed); - foreach(ClassifyTopLevelSingle image in classify.images) + foreach (ClassifyTopLevelSingle image in classify.images) { Log.Debug("TestVisualRecognition", "\tClassifyImage GET source_url: " + image.source_url + ", resolved_url: " + image.resolved_url); - foreach(ClassifyPerClassifier classifier in image.classifiers) + foreach (ClassifyPerClassifier classifier in image.classifiers) { Log.Debug("TestVisualRecognition", "\t\tClassifyImage GET classifier_id: " + classifier.classifier_id + ", name: " + classifier.name); - foreach(ClassResult classResult in classifier.classes) + foreach (ClassResult classResult in classifier.classes) Log.Debug("TestVisualRecognition", "\t\t\tClassifyImage GET class: " + classResult.m_class + ", score: " + classResult.score + ", type_hierarchy: " + classResult.type_hierarchy); } } @@ -280,16 +366,16 @@ private void OnClassifyGet(ClassifyTopLevelMultiple classify, string customData) private void OnClassifyPost(ClassifyTopLevelMultiple classify, string customData) { Test(classify != null); - if(classify != null) + if (classify != null) { Log.Debug("TestVisualRecognition", "ClassifyImage POST images processed: " + classify.images_processed); - foreach(ClassifyTopLevelSingle image in classify.images) + foreach (ClassifyTopLevelSingle image in classify.images) { Log.Debug("TestVisualRecognition", "\tClassifyImage POST source_url: " + image.source_url + ", resolved_url: " + image.resolved_url); - foreach(ClassifyPerClassifier classifier in image.classifiers) + foreach (ClassifyPerClassifier classifier in image.classifiers) { Log.Debug("TestVisualRecognition", "\t\tClassifyImage POST classifier_id: " + classifier.classifier_id + ", name: " + classifier.name); - foreach(ClassResult classResult in classifier.classes) + foreach (ClassResult classResult in classifier.classes) Log.Debug("TestVisualRecognition", "\t\t\tClassifyImage POST class: " + classResult.m_class + ", score: " + classResult.score + ", type_hierarchy: " + classResult.type_hierarchy); } } @@ -305,13 +391,13 @@ private void OnClassifyPost(ClassifyTopLevelMultiple classify, string customData private void OnDetectFacesGet(FacesTopLevelMultiple multipleImages, string customData) { Test(multipleImages != null); - if(multipleImages != null) + if (multipleImages != null) { Log.Debug("TestVisualRecognition", "DetectFaces GET images processed: {0}", multipleImages.images_processed); - foreach(FacesTopLevelSingle faces in multipleImages.images) + foreach (FacesTopLevelSingle faces in multipleImages.images) { Log.Debug("TestVisualRecognition", "\tDetectFaces GET source_url: {0}, resolved_url: {1}", faces.source_url, faces.resolved_url); - foreach(OneFaceResult face in faces.faces) + foreach (OneFaceResult face in faces.faces) { Log.Debug("TestVisualRecognition", "\t\tDetectFaces GET Face location: {0}, {1}, {2}, {3}", face.face_location.left, face.face_location.top, face.face_location.width, face.face_location.height); Log.Debug("TestVisualRecognition", "\t\tDetectFaces GET Gender: {0}, Score: {1}", face.gender.gender, face.gender.score); @@ -331,13 +417,13 @@ private void OnDetectFacesGet(FacesTopLevelMultiple multipleImages, string custo private void OnDetectFacesPost(FacesTopLevelMultiple multipleImages, string customData) { Test(multipleImages != null); - if(multipleImages != null) + if (multipleImages != null) { Log.Debug("TestVisualRecognition", "DetectFaces POST images processed: {0}", multipleImages.images_processed); - foreach(FacesTopLevelSingle faces in multipleImages.images) + foreach (FacesTopLevelSingle faces in multipleImages.images) { Log.Debug("TestVisualRecognition", "\tDetectFaces POST source_url: {0}, resolved_url: {1}", faces.source_url, faces.resolved_url); - foreach(OneFaceResult face in faces.faces) + foreach (OneFaceResult face in faces.faces) { Log.Debug("TestVisualRecognition", "\t\tDetectFaces POST Face location: {0}, {1}, {2}, {3}", face.face_location.left, face.face_location.top, face.face_location.width, face.face_location.height); Log.Debug("TestVisualRecognition", "\t\tDetectFaces POST Gender: {0}, Score: {1}", face.gender.gender, face.gender.score); @@ -357,19 +443,19 @@ private void OnDetectFacesPost(FacesTopLevelMultiple multipleImages, string cust private void OnRecognizeTextGet(TextRecogTopLevelMultiple multipleImages, string customData) { Test(multipleImages != null); - if(multipleImages != null) + if (multipleImages != null) { Log.Debug("TestVisualRecognition", "RecognizeText GET images processed: {0}", multipleImages.images_processed); - foreach(TextRecogTopLevelSingle texts in multipleImages.images) + foreach (TextRecogTopLevelSingle texts in multipleImages.images) { Log.Debug("TestVisualRecognition", "\tRecognizeText GET source_url: {0}, resolved_url: {1}", texts.source_url, texts.resolved_url); Log.Debug("TestVisualRecognition", "\tRecognizeText GET text: {0}", texts.text); -// foreach(TextRecogOneWord text in texts.words) -// { -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET text location: {0}, {1}, {2}, {3}", text.location.left, text.location.top, text.location.width, text.location.height); -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET Line number: {0}", text.line_number); -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET word: {0}, Score: {1}", text.word, text.score); -// } + // foreach(TextRecogOneWord text in texts.words) + // { + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET text location: {0}, {1}, {2}, {3}", text.location.left, text.location.top, text.location.width, text.location.height); + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET Line number: {0}", text.line_number); + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText GET word: {0}, Score: {1}", text.word, text.score); + // } } m_RecognizeTextGETTested = true; @@ -383,19 +469,19 @@ private void OnRecognizeTextGet(TextRecogTopLevelMultiple multipleImages, string private void OnRecognizeTextPost(TextRecogTopLevelMultiple multipleImages, string customData) { Test(multipleImages != null); - if(multipleImages != null) + if (multipleImages != null) { Log.Debug("TestVisualRecognition", "RecognizeText POST images processed: {0}", multipleImages.images_processed); - foreach(TextRecogTopLevelSingle texts in multipleImages.images) + foreach (TextRecogTopLevelSingle texts in multipleImages.images) { Log.Debug("TestVisualRecognition", "\tRecognizeText POST source_url: {0}, resolved_url: {1}", texts.source_url, texts.resolved_url); Log.Debug("TestVisualRecognition", "\tRecognizeText POST text: {0}", texts.text); -// foreach(TextRecogOneWord text in texts.words) -// { -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST text location: {0}, {1}, {2}, {3}", text.location.left, text.location.top, text.location.width, text.location.height); -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST Line number: {0}", text.line_number); -// Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST word: {0}, Score: {1}", text.word, text.score); -// } + // foreach(TextRecogOneWord text in texts.words) + // { + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST text location: {0}, {1}, {2}, {3}", text.location.left, text.location.top, text.location.width, text.location.height); + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST Line number: {0}", text.line_number); + // Log.Debug("TestVisualRecognition", "\t\tRecognizeText POST word: {0}, Score: {1}", text.word, text.score); + // } } m_RecognizeTextPOSTTested = true; @@ -408,38 +494,37 @@ private void OnRecognizeTextPost(TextRecogTopLevelMultiple multipleImages, strin private void OnDeleteClassifier(bool success, string customData) { - if(success) + if (success) { m_VisualRecognition.FindClassifier(OnDeleteClassifierFinal, m_ClassifierName); } - m_DeleteTested = true; + m_DeleteClassifierTested = true; Test(success); } private void CheckClassifierStatus(VisualRecognition.OnGetClassifier callback, string customData = default(string)) { - if(!m_VisualRecognition.GetClassifier(callback, m_ClassifierId)) + if (!m_VisualRecognition.GetClassifier(callback, m_ClassifierId)) Log.Debug("TestVisualRecognition", "Get classifier failed!"); } private void OnCheckClassifierStatus(GetClassifiersPerClassifierVerbose classifier, string customData) { Log.Debug("TestVisualRecognition", "classifier {0} is {1}!", classifier.classifier_id, classifier.status); - - if(classifier.status == "unavailable" || classifier.status == "failed") + if (classifier.status == "unavailable" || classifier.status == "failed") { Log.Debug("TestVisualRecognition", "Deleting classifier!"); // classifier failed - delete! - if(!m_VisualRecognition.DeleteClassifier(OnCheckClassifierStatusDelete, classifier.classifier_id)) + if (!m_VisualRecognition.DeleteClassifier(OnCheckClassifierStatusDelete, classifier.classifier_id)) Log.Debug("TestVisualRecognition", "Failed to delete classifier {0}!", m_ClassifierId); } - else if(classifier.status == "training") + else if (classifier.status == "training") { CheckClassifierStatus(OnCheckClassifierStatus); } - else if(classifier.status == "ready") + else if (classifier.status == "ready") { m_IsClassifierReady = true; m_ClassifierId = classifier.classifier_id; @@ -462,7 +547,7 @@ private void OnCheckClassifierStatus(GetClassifiersPerClassifierVerbose classifi private void OnCheckClassifierStatusDelete(bool success, string customData) { - if(success) + if (success) { // train classifier again! m_TrainClasifierTested = false; @@ -471,7 +556,7 @@ private void OnCheckClassifierStatusDelete(bool success, string customData) private void OnDeleteClassifierFinal(GetClassifiersPerClassifierVerbose classifier, string customData) { - if(classifier == null) + if (classifier == null) { Log.Debug("TestVisualRecognition", "Classifier not found! Delete sucessful!"); } @@ -479,6 +564,174 @@ private void OnDeleteClassifierFinal(GetClassifiersPerClassifierVerbose classifi { Log.Debug("TestVisualRecognition", "Classifier {0} found! Delete failed!", classifier.name); } + Test(classifier == null); + } + + private void OnGetCollections(GetCollections collections, string customData) + { + if(collections != null) + { + Log.Debug("TestVisualRecognition", "Get Collections succeeded!"); + foreach (CreateCollection collection in collections.collections) + { + Log.Debug("TestVisualRecognition", "collectionID: {0} | collection name: {1} | number of images: {2}", collection.collection_id, collection.name, collection.images); + } + } + else + { + Log.Debug("TestVisualRecognition", "Get Collections failed!"); + } + + m_ListCollectionsTested = true; + Test(collections != null); + } + + private void OnCreateCollection(CreateCollection collection, string customData) + { + if(collection != null) + { + Log.Debug("TestVisualRecognition", "Create Collection succeeded!"); + Log.Debug("TestVisualRecognition", "collectionID: {0} | collection name: {1} | collection images: {2}", collection.collection_id, collection.name, collection.images); + + m_CreatedCollectionID = collection.collection_id; + } + else + { + Log.Debug("TestVisualRecognition", "Create Collection failed!"); + } + + m_CreateCollectionTested = true; + Test(collection != null); + } + + private void OnDeleteCollection(bool success, string customData) + { + if(success) + Log.Debug("TestVisualRecognition", "Delete Collection succeeded!"); + else + Log.Debug("TestVisualRecognition", "Delete Collection failed!"); + + m_DeleteCollectionTested = true; + Test(success); + } + + private void OnGetCollection(CreateCollection collection, string customData) + { + if (collection != null) + { + Log.Debug("TestVisualRecognition", "Get Collection succeded!"); + Log.Debug("TestVisualRecognition", "collectionID: {0} | collection name: {1} | collection images: {2}", collection.collection_id, collection.name, collection.images); + } + else + { + Log.Debug("TestVisualRecognition", "Get Collection failed!"); + + } + + m_RetrieveCollectionDetailsTested = true; + Test(collection != null); + } + + private void OnGetCollectionImages(GetCollectionImages collections, string customData) + { + if(collections != null) + { + Log.Debug("TestVisualRecognition", "Get Collections succeded!"); + foreach(GetCollectionsBrief collection in collections.images) + Log.Debug("TestVisualRecognition", "imageID: {0} | image file: {1} | image metadataOnGetCollections: {2}", collection.image_id, collection.image_file, collection.metadata.ToString()); + } + else + { + Log.Debug("TestVisualRecognition", "Get Collections failed!"); + } + + Test(collections != null); + m_ListImagesTested = true; + } + + private void OnAddImageToCollection(CollectionsConfig images, string customData) + { + if(images != null) + { + Log.Debug("TestVisualRecognition", "Add image to collection succeeded!"); + m_CreatedCollectionImage = images.images[0].image_id; + Log.Debug("TestVisualRecognition", "images processed: {0}", images.images_processed); + foreach (CollectionImagesConfig image in images.images) + Log.Debug("TestVisualRecognition", "imageID: {0} | image_file: {1} | image metadata: {1}", image.image_id, image.image_file, image.metadata.ToString()); + } + else + { + Log.Debug("TestVisualRecognition", "Add image to collection failed!"); + } + + Test(images != null); + m_AddImagesToCollectionTested = true; + } + + private void OnDeleteCollectionImage(bool success, string customData) + { + if (success) + Log.Debug("TestVisualRecognition", "Delete collection image succeeded!"); + else + Log.Debug("TestVisualRecognition", "Delete collection image failed!"); + + Test(success); + m_DeleteImageFromCollectionTested = true; + } + + private void OnGetImage(GetCollectionsBrief image, string customData) + { + if(image != null) + { + Log.Debug("TestVisualRecognition", "GetImage succeeded!"); + Log.Debug("TestVisualRecognition", "imageID: {0} | created: {1} | image_file: {2} | metadata: {3}", image.image_id, image.created, image.image_file, image.metadata); + } + else + { + Log.Debug("TestVisualRecognition", "GetImage failed!"); + } + + Test(image != null); + m_ListImageDetailsTested = true; + + } + + private void OnDeleteMetadata(bool success, string customData) + { + if (success) + Log.Debug("TestVisualRecognition", "Delete image metadata succeeded!"); + else + Log.Debug("TestVisualRecognition", "Delete image metadata failed!"); + + Test(success); + m_DeleteImageMetadataTested = true; + } + + private void OnGetMetadata(object responseObject, string customData) + { + if(responseObject != null) + Log.Debug("TestVisualRecognition", "ResponseObject: {0}", responseObject); + + Test(responseObject != null); + m_ListImageMetadataTested = true; + } + + private void OnFindSimilar(SimilarImagesConfig images, string customData) + { + if(images != null) + { + Log.Debug("TestVisualRecognition", "GetSimilar succeeded!"); + Log.Debug("TestVisualRecognition", "images processed: {0}", images.images_processed); + foreach (SimilarImageConfig image in images.similar_images) + Log.Debug("TestVisualRecognition", "image ID: {0} | image file: {1} | score: {2} | metadata: {3}", image.image_id, image.image_file, image.score, image.metadata.ToString()); + } + else + { + Log.Debug("TestVisualRecognition", "GetSimilar failed!"); + } + + Test(images != null); + m_FindSimilarTested = true; } } }