From ca7eed21296535560c571d5cd2654cea91fbc924 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 13:29:53 -0500 Subject: [PATCH 01/18] added similarity search endpoints to visualrecognition service --- Scripts/Services/VisualRecognition/VisualRecognition.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index f35a24a1d..8a6396346 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -95,6 +95,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; From cab4df00d3f618478662eee425058cafe50b168e Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 13:58:42 -0500 Subject: [PATCH 02/18] Similarity search data models --- .../Services/VisualRecognition/DataModels.cs | 640 +++++++++++------- 1 file changed, 403 insertions(+), 237 deletions(-) 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 { From 1f8368f0f42e50e777247daf5abb57c9f81baa70 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 14:16:49 -0500 Subject: [PATCH 03/18] comment out endpoints to hit in VisualRecognition --- .../VisualRecognition/VisualRecognition.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 8a6396346..cfed164c5 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1093,6 +1093,50 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res } #endregion + #region Get Collections + //Get all collections. + #endregion + + #region Create collection + //Create a new collection of images to search. You can create a maximum of 5 collections. + #endregion + + #region Delete Collection + //Deletes a collection. + #endregion + + #region Get Collection + //Retrieve information about a specific collection. Only user-created collections can be specified. + #endregion + + #region Get Collection Images + //List 100 images in a collection + #endregion + + #region Add Collection Images + //Add images to a collection + #endregion + + #region Delete Image + //Delete an image + #endregion + + #region Get Image + //List image details + #endregion + + #region Delete Image Metadata + //Delete image metadata + #endregion + + #region List Image Metadata + //List image metadata. + #endregion + + #region Find Similar Images + //Find Similar Images + #endregion + #region private methods private string GetMimeType(string imagePath) { From 48a719d5b4b782afb0c87f6e243f84709ec0bc5d Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 14:59:31 -0500 Subject: [PATCH 04/18] added callback delegates for each similarity search endpoint --- .../VisualRecognition/VisualRecognition.cs | 89 +++++++++++++++++-- 1 file changed, 84 insertions(+), 5 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index cfed164c5..b6462fb3f 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 OnAddCollectionimages(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(). /// @@ -1095,6 +1170,10 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res #region Get Collections //Get all collections. + //public bool GetCollections() + //{ + + //} #endregion #region Create collection From d13cd602e45534b92760f12d0b8cd68b53dabdef Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 15:37:18 -0500 Subject: [PATCH 05/18] GetCollections --- .../VisualRecognition/VisualRecognition.cs | 73 ++++++++++++++++++- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index b6462fb3f..59a0b320d 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1169,15 +1169,80 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res #endregion #region Get Collections - //Get all collections. - //public bool GetCollections() - //{ + /// + /// Get all collections. + /// + /// The callback. + /// Custom data. + /// + public bool GetCollections(OnGetCollections callback, string customData = default(string)) + { + 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 = OnGetClassifiersResp; + + 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 OnGetCollectionsRest(RESTConnector.Request req, RESTConnector.Response resp) + { + GetCollections collections = new GetCollections(); + if(resp.Success) + { + 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; + } + } + + 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. + #endregion #region Delete Collection From 90c0c88da5761f40314f1099e7a395c6e92f8e00 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 15:54:41 -0500 Subject: [PATCH 06/18] CreateCollection --- .../VisualRecognition/VisualRecognition.cs | 84 ++++++++++++++++++- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 59a0b320d..4a1b12d2a 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1212,7 +1212,7 @@ private class GetCollectionsReq : RESTConnector.Request public string Data { get; set; } } - private void OnGetCollectionsRest(RESTConnector.Request req, RESTConnector.Response resp) + private void OnGetCollectionsResp(RESTConnector.Request req, RESTConnector.Response resp) { GetCollections collections = new GetCollections(); if(resp.Success) @@ -1241,8 +1241,86 @@ private void OnGetCollectionsRest(RESTConnector.Request req, RESTConnector.Respo #endregion #region Create collection - //Create a new collection of images to search. You can create a maximum of 5 collections. - + /// + /// 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. + /// + 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.Parameters["name"] = name; + req.Forms = new Dictionary(); + req.Forms["disregard"] = new RESTConnector.Form("empty"); + + req.Timeout = 20.0f * 60.0f; + req.OnResponse = OnGetClassifiersResp; + + 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 From 5c787b9b28b4761b52c0f88adbde374abddd46b3 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 16:06:11 -0500 Subject: [PATCH 07/18] Delete collection --- .../VisualRecognition/VisualRecognition.cs | 67 +++++++++++++++++-- 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 4a1b12d2a..867e48fa6 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1174,7 +1174,7 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res /// /// The callback. /// Custom data. - /// + /// Returns true if succeess, false if failure. public bool GetCollections(OnGetCollections callback, string customData = default(string)) { if (callback == null) @@ -1195,7 +1195,7 @@ private void OnDeleteClassifierResp(RESTConnector.Request req, RESTConnector.Res req.Parameters["api_key"] = mp_ApiKey; req.Parameters["version"] = VisualRecognitionVersion.Version; req.Timeout = 20.0f * 60.0f; - req.OnResponse = OnGetClassifiersResp; + req.OnResponse = OnGetCollectionsResp; return connector.Send(req); } @@ -1247,7 +1247,7 @@ private void OnGetCollectionsResp(RESTConnector.Request req, RESTConnector.Respo /// 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) @@ -1269,12 +1269,12 @@ public bool CreateCollection(OnCreateCollection callback, string name, string cu req.Data = customData; req.Parameters["api_key"] = mp_ApiKey; req.Parameters["version"] = VisualRecognitionVersion.Version; - req.Parameters["name"] = name; req.Forms = new Dictionary(); + req.Forms["name"] = new RESTConnector.Form(name); req.Forms["disregard"] = new RESTConnector.Form("empty"); req.Timeout = 20.0f * 60.0f; - req.OnResponse = OnGetClassifiersResp; + req.OnResponse = OnCreateCollectionResp; return connector.Send(req); } @@ -1324,7 +1324,62 @@ private void OnCreateCollectionResp(RESTConnector.Request req, RESTConnector.Res #endregion #region Delete Collection - //Deletes a 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.Timeout = 20.0f * 60.0f; + req.OnResponse = OnDeleteCollectionResp; + req.Delete = true; + 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 From 81ba79bf164507b468f4e41f699039aff032941b Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Wed, 14 Sep 2016 16:26:57 -0500 Subject: [PATCH 08/18] Get Collection --- .../VisualRecognition/VisualRecognition.cs | 81 ++++++++++++++++++- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 867e48fa6..4304e7e0c 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1352,10 +1352,10 @@ public bool DeleteCollection(OnDeleteCollection callback, string collectionID, s 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; - req.Delete = true; + return connector.Send(req); } @@ -1383,7 +1383,82 @@ private void OnDeleteCollectionResp(RESTConnector.Request req, RESTConnector.Res #endregion #region Get Collection - //Retrieve information about a specific collection. Only user-created collections can be specified. + /// + /// 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 From 9f755cfa7034037082f24ba83ba735c6227c6138 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 10:10:31 -0500 Subject: [PATCH 09/18] GetCollectionImages and AddCollectionImages --- .../VisualRecognition/VisualRecognition.cs | 285 +++++++++++++++++- 1 file changed, 282 insertions(+), 3 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 4304e7e0c..50753f164 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -120,7 +120,7 @@ public class VisualRecognition : IWatsonService /// /// The collection config. /// Optional data - public delegate void OnAddCollectionimages(CollectionsConfig config, string data); + public delegate void OnAddCollectionImage(CollectionsConfig config, string data); /// /// This callback is used by the DeleteCollectionImage() method. /// @@ -1462,11 +1462,275 @@ private void OnGetCollectionResp(RESTConnector.Request req, RESTConnector.Respon #endregion #region Get Collection Images - //List 100 images in a collection + /// + /// 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 images to a collection + /// + /// 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, 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, 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 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); + req.Forms["metadata"] = new RESTConnector.Form(metadata); + + 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 @@ -1514,6 +1778,21 @@ private string GetMimeType(string imagePath) return mimeType; } + + private string GetMetadataJson(Dictionary metadata) + { + string json = "{"; + string metadataItem = "\n\t\"{0}\":\"{1}\""; + + foreach(KeyValuePair kv in metadata) + { + json += string.Format(metadataItem, kv.Key, kv.Value); + } + + json += "\n}"; + + return json; + } #endregion #region IWatsonService implementation From f09d706d41751cfea14a1f6c8321921e6b3fda8d Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 10:18:25 -0500 Subject: [PATCH 10/18] delete collection image --- .../VisualRecognition/VisualRecognition.cs | 65 ++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 50753f164..f1b27aff1 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1734,7 +1734,70 @@ private void OnAddCollectionImageResp(RESTConnector.Request req, RESTConnector.R #endregion #region Delete Image - //Delete an 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 From 8852a349317064df84223df09f7e840913c940fb Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 10:53:32 -0500 Subject: [PATCH 11/18] delete image metadata --- .../VisualRecognition/VisualRecognition.cs | 149 +++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index f1b27aff1..6b3f79545 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1801,11 +1801,156 @@ private void OnDeleteCollectionImageResp(RESTConnector.Request req, RESTConnecto #endregion #region Get Image - //List image details + /// + /// 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_IMAGES, collectionID)); + 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 - //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 DeleteCollectionImage(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 From 14779d0cb4d19cdab74f8b583b3995f2296dc5ef Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 11:16:20 -0500 Subject: [PATCH 12/18] GetImageMetadata --- .../VisualRecognition/VisualRecognition.cs | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 6b3f79545..b6babe57b 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1821,7 +1821,7 @@ private void OnDeleteCollectionImageResp(RESTConnector.Request req, RESTConnecto 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)); + RESTConnector connector = RESTConnector.GetConnector(SERVICE_ID, string.Format(SERVICE_COLLECTION_IMAGE, collectionID, imageID)); if (connector == null) return false; @@ -1954,7 +1954,90 @@ private void OnDeleteCollectionImageMetadataResp(RESTConnector.Request req, REST #endregion #region List Image Metadata - //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 (((GetCollectionImageReq)req).Callback != null) + ((GetCollectionImageReq)req).Callback(resp.Success ? image : null, ((GetCollectionImageReq)req).Data); + } #endregion #region Find Similar Images From 9d039417d9bdc4aeb992a9b993d6c3668597ce48 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 11:33:05 -0500 Subject: [PATCH 13/18] find similar --- .../VisualRecognition/VisualRecognition.cs | 138 +++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index b6babe57b..646d3a04d 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -2041,7 +2041,143 @@ private void OnGetCollectionImageMetadataResp(RESTConnector.Request req, RESTCon #endregion #region Find Similar Images - //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 From f196f49f63abdf523c246ee79d6f9e5c95263a8e Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 17:12:20 -0500 Subject: [PATCH 14/18] start unit test framework --- .../VisualRecognition/VisualRecognition.cs | 2 +- Scripts/UnitTests/TestVisualRecognition.cs | 282 +++++++++++++----- 2 files changed, 213 insertions(+), 71 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index 646d3a04d..e9693d605 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1895,7 +1895,7 @@ private void OnGetCollectionImageResp(RESTConnector.Request req, RESTConnector.R /// The identifier of the image metadata to delete. /// Optional custom data. /// Returns true if succeess, false if failure. - public bool DeleteCollectionImage(OnDeleteImageMetadata callback, string collectionID, string imageID, string customData = null) + public bool DeleteCollectionImageMetadata(OnDeleteImageMetadata callback, string collectionID, string imageID, string customData = null) { if (callback == null) throw new ArgumentNullException("callback"); diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognition.cs index 650bc5de9..8da9889f9 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,6 +69,9 @@ 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 @@ -63,14 +79,14 @@ public override IEnumerator RunTest() 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) + while (!m_FindClassifierTested) yield return null; - - if(m_TrainClassifier) + + if (m_TrainClassifier) { // test train classifier Log.Debug("TestVisualRecognition", "Training classifier!"); @@ -79,25 +95,25 @@ public override IEnumerator RunTest() Dictionary positiveExamples = new Dictionary(); positiveExamples.Add(m_ClassName_Giraffe, m_positiveExamplesPath); Test(m_VisualRecognition.TrainClassifier(OnTrainClassifier, m_ClassifierName, positiveExamples, m_negativeExamplesPath)); - while(!m_TrainClasifierTested) + while (!m_TrainClasifierTested) yield return null; } // Wait until classifier is ready - if(!m_IsClassifierReady) + 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)) + + 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) + while (!m_GetClassifierTested) yield return null; // Update classifier @@ -115,64 +131,134 @@ public override IEnumerator RunTest() while (!m_IsUpdatedClassifierReady) yield return null; - string[] m_owners = {"IBM", "me"}; - string[] m_classifierIds = {"default", m_ClassifierId}; - + 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) + 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) + 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) + 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) + 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) + 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) + 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_DeleteTested) + 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 create collection + Log.Debug("TestVisualRecognition", "Attempting to create collection!"); + m_VisualRecognition.CreateCollection(OnCreateCollection, "unity-integration-test-collection"); + while (!m_CreateCollectionTested) + 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 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 list images + Log.Debug("TestVisualRecognition", "Attempting to list images!"); + m_VisualRecognition.GetCollections(OnGetCollections); + while (!m_ListImagesTested) yield return null; + // 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 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 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,18 +494,18 @@ 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!"); } @@ -427,19 +513,19 @@ private void OnCheckClassifierStatus(GetClassifiersPerClassifierVerbose classifi { 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 +548,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 +557,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!"); } @@ -480,5 +566,61 @@ private void OnDeleteClassifierFinal(GetClassifiersPerClassifierVerbose classifi Log.Debug("TestVisualRecognition", "Classifier {0} found! Delete failed!", classifier.name); } } + + private void OnGetCollections(GetCollections collections, string customData) + { + + } + + private void OnCreateCollection(CreateCollection collection, string customData) + { + m_CreatedCollectionID = collection.collection_id; + + } + + private void OnDeleteCollection(bool success, string customData) + { + + } + + private void OnGetCollection(CreateCollection collection, string customData) + { + + } + + private void OnGetCollections(GetCollectionImages collections, string customData) + { + + } + + private void OnAddImageToCollection(CollectionsConfig images, string customData) + { + m_CreatedCollectionImage = images.images[0].image_id; + } + + private void OnDeleteCollectionImage(bool success, string customData) + { + + } + + private void OnGetImage(GetCollectionsBrief image, string customData) + { + + } + + private void OnDeleteMetadata(bool success, string customData) + { + + } + + private void OnGetMetadata(object responseObject, string customData) + { + Log.Debug("TestVisualRecognition", "ResponseObject: {0}", responseObject); + } + + private void OnFindSimilar(SimilarImagesConfig images, string customData) + { + + } } } From f506a803500339ba194837d833489b45051d2c9f Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 18:21:47 -0500 Subject: [PATCH 15/18] integration tests --- Scripts/UnitTests/TestVisualRecognition.cs | 78 +++++++++++++++++++--- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognition.cs index 8da9889f9..9d59d8b33 100755 --- a/Scripts/UnitTests/TestVisualRecognition.cs +++ b/Scripts/UnitTests/TestVisualRecognition.cs @@ -512,7 +512,6 @@ private void OnDeleteClassifier(bool success, string customData) 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") { Log.Debug("TestVisualRecognition", "Deleting classifier!"); @@ -565,38 +564,101 @@ 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!"); + } + + Test(collections != null); } private void OnCreateCollection(CreateCollection collection, string customData) { - m_CreatedCollectionID = collection.collection_id; - + 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!"); + } + + 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!"); + 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!"); + + } + + Test(collection != null); } private void OnGetCollections(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); } private void OnAddImageToCollection(CollectionsConfig images, string customData) { - m_CreatedCollectionImage = images.images[0].image_id; - } + 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!"); + } + } private void OnDeleteCollectionImage(bool success, string customData) { From c470075ecd051b5c09504b98f1d2befceb176035 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 18:41:13 -0500 Subject: [PATCH 16/18] WIP - integration tests --- Scripts/UnitTests/TestVisualRecognition.cs | 48 ++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognition.cs index 9d59d8b33..9c987f177 100755 --- a/Scripts/UnitTests/TestVisualRecognition.cs +++ b/Scripts/UnitTests/TestVisualRecognition.cs @@ -582,6 +582,7 @@ private void OnGetCollections(GetCollections collections, string customData) Log.Debug("TestVisualRecognition", "Get Collections failed!"); } + m_ListCollectionsTested = true; Test(collections != null); } @@ -599,6 +600,7 @@ private void OnCreateCollection(CreateCollection collection, string customData) Log.Debug("TestVisualRecognition", "Create Collection failed!"); } + m_CreateCollectionTested = true; Test(collection != null); } @@ -609,6 +611,7 @@ private void OnDeleteCollection(bool success, string customData) else Log.Debug("TestVisualRecognition", "Delete Collection failed!"); + m_DeleteCollectionTested = true; Test(success); } @@ -625,6 +628,7 @@ private void OnGetCollection(CreateCollection collection, string customData) } + m_RetrieveCollectionDetailsTested = true; Test(collection != null); } @@ -641,6 +645,7 @@ private void OnGetCollections(GetCollectionImages collections, string customData Log.Debug("TestVisualRecognition", "Get Collections failed!"); } + m_ListCollectionsTested = true; Test(collections != null); } @@ -658,31 +663,68 @@ private void OnAddImageToCollection(CollectionsConfig images, string customData) { Log.Debug("TestVisualRecognition", "Add image to collection failed!"); } + + Test(images != null); } 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); + } 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); } 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); + } private void OnGetMetadata(object responseObject, string customData) { - Log.Debug("TestVisualRecognition", "ResponseObject: {0}", responseObject); + if(responseObject != null) + Log.Debug("TestVisualRecognition", "ResponseObject: {0}", responseObject); + + Test(responseObject != null); } 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); } } } From 5773aee93e5a1af537a814f370fc9af93eea644b Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Thu, 15 Sep 2016 22:33:43 -0500 Subject: [PATCH 17/18] complete integration tests --- .../VisualRecognition/VisualRecognition.cs | 40 +-- Scripts/UnitTests/TestVisualRecognition.cs | 227 +++++++++--------- 2 files changed, 142 insertions(+), 125 deletions(-) diff --git a/Scripts/Services/VisualRecognition/VisualRecognition.cs b/Scripts/Services/VisualRecognition/VisualRecognition.cs index e9693d605..50f82b643 100755 --- a/Scripts/Services/VisualRecognition/VisualRecognition.cs +++ b/Scripts/Services/VisualRecognition/VisualRecognition.cs @@ -1271,7 +1271,7 @@ public bool CreateCollection(OnCreateCollection callback, string name, string cu req.Parameters["version"] = VisualRecognitionVersion.Version; req.Forms = new Dictionary(); req.Forms["name"] = new RESTConnector.Form(name); - req.Forms["disregard"] = new RESTConnector.Form("empty"); + req.Forms["disregard"] = new RESTConnector.Form(new byte[4]); req.Timeout = 20.0f * 60.0f; req.OnResponse = OnCreateCollectionResp; @@ -1581,7 +1581,7 @@ public bool AddCollectionImage(OnAddCollectionImage callback, string collectionI Log.Error("VisualRecognition", "Failed to upload {0}!", imagePath); } - return AddCollectionImage(callback, collectionID, imageData, GetMetadataJson(metadata), customData); + return AddCollectionImage(callback, collectionID, imageData, Path.GetFileName(imagePath), GetMetadataJson(metadata), customData); } /// @@ -1633,7 +1633,7 @@ public bool AddCollectionImage(OnAddCollectionImage callback, string collectionI Log.Error("VisualRecognition", "Failed to read {0}!", imagePath); } - return AddCollectionImage(callback, collectionID, imageData, metadata, customData); + return AddCollectionImage(callback, collectionID, imageData, Path.GetFileName(imagePath), metadata, customData); } /// @@ -1645,7 +1645,7 @@ public bool AddCollectionImage(OnAddCollectionImage callback, string collectionI /// Optional json metadata associated with the specified image. /// Optional custom data. /// - public bool AddCollectionImage(OnAddCollectionImage callback, string collectionID, byte[] imageData, string metadata = null, string customData = null) + public bool AddCollectionImage(OnAddCollectionImage callback, string collectionID, byte[] imageData, string filename, string metadata = null, string customData = null) { if (callback == null) throw new ArgumentNullException("callback"); @@ -1672,14 +1672,14 @@ public bool AddCollectionImage(OnAddCollectionImage callback, string collectionI req.Parameters["api_key"] = mp_ApiKey; req.Parameters["version"] = VisualRecognitionVersion.Version; req.Forms = new Dictionary(); - req.Forms["image_file"] = new RESTConnector.Form(imageData); - req.Forms["metadata"] = new RESTConnector.Form(metadata); + 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 { @@ -2035,8 +2035,8 @@ private void OnGetCollectionImageMetadataResp(RESTConnector.Request req, RESTCon } } - if (((GetCollectionImageReq)req).Callback != null) - ((GetCollectionImageReq)req).Callback(resp.Success ? image : null, ((GetCollectionImageReq)req).Data); + if (((GetCollectionImageMetadataReq)req).Callback != null) + ((GetCollectionImageMetadataReq)req).Callback(resp.Success ? image : null, ((GetCollectionImageMetadataReq)req).Data); } #endregion @@ -2211,12 +2211,22 @@ private string GetMetadataJson(Dictionary metadata) string json = "{"; string metadataItem = "\n\t\"{0}\":\"{1}\""; - foreach(KeyValuePair kv in metadata) - { - json += string.Format(metadataItem, kv.Key, kv.Value); - } - - json += "\n}"; + 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; } diff --git a/Scripts/UnitTests/TestVisualRecognition.cs b/Scripts/UnitTests/TestVisualRecognition.cs index 9c987f177..864edf964 100755 --- a/Scripts/UnitTests/TestVisualRecognition.cs +++ b/Scripts/UnitTests/TestVisualRecognition.cs @@ -74,114 +74,114 @@ public class TestVisualRecognition : UnitTest public override IEnumerator RunTest() { - // 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 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; + } - // 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; + // 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; + } - // test delete classifier - Log.Debug("TestVisualRecognition", "Deleting classifier {0}!", m_ClassifierId); - m_VisualRecognition.DeleteClassifier(OnDeleteClassifier, m_ClassifierId); - while (!m_DeleteClassifierTested) - 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 list collections - Log.Debug("TestVisualRecognition", "Attempting to list collections!"); + // 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; @@ -211,7 +211,7 @@ public override IEnumerator RunTest() // test list images Log.Debug("TestVisualRecognition", "Attempting to list images!"); - m_VisualRecognition.GetCollections(OnGetCollections); + m_VisualRecognition.GetCollectionImages(OnGetCollectionImages, m_CreatedCollectionID); while (!m_ListImagesTested) yield return null; @@ -632,7 +632,7 @@ private void OnGetCollection(CreateCollection collection, string customData) Test(collection != null); } - private void OnGetCollections(GetCollectionImages collections, string customData) + private void OnGetCollectionImages(GetCollectionImages collections, string customData) { if(collections != null) { @@ -645,8 +645,8 @@ private void OnGetCollections(GetCollectionImages collections, string customData Log.Debug("TestVisualRecognition", "Get Collections failed!"); } - m_ListCollectionsTested = true; Test(collections != null); + m_ListImagesTested = true; } private void OnAddImageToCollection(CollectionsConfig images, string customData) @@ -665,6 +665,7 @@ private void OnAddImageToCollection(CollectionsConfig images, string customData) } Test(images != null); + m_AddImagesToCollectionTested = true; } private void OnDeleteCollectionImage(bool success, string customData) @@ -675,6 +676,7 @@ private void OnDeleteCollectionImage(bool success, string customData) Log.Debug("TestVisualRecognition", "Delete collection image failed!"); Test(success); + m_DeleteImageFromCollectionTested = true; } private void OnGetImage(GetCollectionsBrief image, string customData) @@ -690,7 +692,9 @@ private void OnGetImage(GetCollectionsBrief image, string customData) } Test(image != null); - } + m_ListImageDetailsTested = true; + + } private void OnDeleteMetadata(bool success, string customData) { @@ -700,6 +704,7 @@ private void OnDeleteMetadata(bool success, string customData) Log.Debug("TestVisualRecognition", "Delete image metadata failed!"); Test(success); + m_DeleteImageMetadataTested = true; } private void OnGetMetadata(object responseObject, string customData) @@ -708,7 +713,8 @@ private void OnGetMetadata(object responseObject, string customData) Log.Debug("TestVisualRecognition", "ResponseObject: {0}", responseObject); Test(responseObject != null); - } + m_ListImageMetadataTested = true; + } private void OnFindSimilar(SimilarImagesConfig images, string customData) { @@ -725,6 +731,7 @@ private void OnFindSimilar(SimilarImagesConfig images, string customData) } Test(images != null); + m_FindSimilarTested = true; } } } From c6c2a50e9a771a005c114a03ab830bd50959c160 Mon Sep 17 00:00:00 2001 From: Ajiemar Santiago Date: Fri, 23 Sep 2016 13:21:01 -0500 Subject: [PATCH 18/18] Updated changelog and readme to include similarity search documentation --- CHANGELOG.md | 9 ++ README.md | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 254 insertions(+) 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.