예제 #1
0
        static void Main(string[] args)
        {
            // You can either add your training key here, pass it on the command line, or type it in when the program runs
            string trainingKey = GetTrainingKey("<your key here>", args);

            // Create the Api, passing in a credentials object that contains the training key
            TrainingApiCredentials trainingCredentials = new TrainingApiCredentials(trainingKey);
            TrainingApi            trainingApi         = new TrainingApi(trainingCredentials);

            // Create a new project
            Console.WriteLine("Creating new project:");
            var project = trainingApi.CreateProject("Bike Type");

            // Make two tags in the new project
            var MbikesTag = trainingApi.CreateTag(project.Id, "Mountain");
            var RbikesTag = trainingApi.CreateTag(project.Id, "Racing");

            // Add some images to the tags
            Console.WriteLine("\\tUploading images");
            LoadImagesFromDisk();

            // Images can be uploaded one at a time
            foreach (var image in MbikesImages)
            {
                trainingApi.CreateImagesFromData(project.Id, image, new List <string> ()
                {
                    MbikesTag.Id.ToString()
                });
            }

            // Or uploaded in a single batch
            trainingApi.CreateImagesFromData(project.Id, RbikesImages, new List <Guid> ()
            {
                RbikesTag.Id
            });

            // Now there are images with tags start training the project
            Console.WriteLine("\\tTraining");
            var iteration = trainingApi.TrainProject(project.Id);

            // The returned iteration will be in progress, and can be queried periodically to see when it has completed
            while (iteration.Status == "Training")
            {
                Thread.Sleep(1000);

                // Re-query the iteration to get it's updated status
                iteration = trainingApi.GetIteration(project.Id, iteration.Id);
            }

            // The iteration is now trained. Make it the default project endpoint
            iteration.IsDefault = true;
            trainingApi.UpdateIteration(project.Id, iteration.Id, iteration);
            Console.WriteLine("Done!\\n");

            // Now there is a trained endpoint, it can be used to make a prediction

            // Get the prediction key, which is used in place of the training key when making predictions
            var account       = trainingApi.GetAccountInfo();
            var predictionKey = account.Keys.PredictionKeys.PrimaryKey;

            // Create a prediction endpoint, passing in a prediction credentials object that contains the obtained prediction key
            PredictionEndpointCredentials predictionEndpointCredentials = new PredictionEndpointCredentials(predictionKey);
            PredictionEndpoint            endpoint = new PredictionEndpoint(predictionEndpointCredentials);

            // Make a prediction against the new project
            Console.WriteLine("Making a prediction:");
            var result = endpoint.PredictImage(project.Id, testImage);

            // Loop over each prediction and write out the results
            foreach (var c in result.Predictions)
            {
                Console.WriteLine($"\\t{c.Tag}: {c.Probability:P1}");
            }
            Console.ReadKey();
        }
예제 #2
0
        private static void CreateTheModel(string trainingSetPath, Project project)
        {
            var trainingKey = ConfigurationManager.AppSettings["CustomVision_TrainingKey"];
            var trainingApi = new TrainingApi()
            {
                ApiKey = trainingKey
            };

            var trainingModel = new List <Model>();

            bool performImageAugmentation = true;

            try
            {
                performImageAugmentation = Convert.ToBoolean(ConfigurationManager.AppSettings["PerformImageAugmentation"]);
            }
            catch { }

            int widthHeight = 299;

            try
            {
                widthHeight = Convert.ToInt32(ConfigurationManager.AppSettings["WidthHeight"]);
            }
            catch { }

            int padImages = 10;

            try
            {
                padImages = Convert.ToInt32(ConfigurationManager.AppSettings["PadImages"]);
            }
            catch { }

            var trainingSet = Directory.GetDirectories(trainingSetPath);

            foreach (var subdirectory in trainingSet)
            {
                var dir  = new DirectoryInfo(subdirectory);
                var name = dir.Name;

                Console.WriteLine($"\tAdding Tag - {name}");

                var tag = trainingApi.CreateTag(project.Id, name);

                var images = Directory.GetFiles($"{subdirectory}").Select(f =>
                {
                    trainingModel.Add(new Model()
                    {
                        Label = name, Path = f
                    });
                    return(new MemoryStream(File.ReadAllBytes(f)));
                }).ToList();

                foreach (var image in images)
                {
                    try
                    {
                        Console.WriteLine($"\tUploading image with tag: {tag.Name}");

                        if (performImageAugmentation)
                        {
                            // flip from RGB to BGR
                            System.Drawing.Bitmap img   = new System.Drawing.Bitmap(image);
                            Image <Bgr, byte>     ogImg = new Image <Bgr, byte>(img);

                            // perform Intensity Image Equalization
                            Image <Ycc, byte> ycrcb = ogImg.Convert <Ycc, byte>();
                            ycrcb._EqualizeHist();
                            ogImg = ycrcb.Convert <Bgr, byte>(); //replace original image with equalized image

                            int top    = 0;
                            int bottom = 0;
                            int left   = 0;
                            int right  = 0;

                            if (img.Width != img.Height)
                            {
                                // we need to pad our image if the width and height aren't set already in a previous smart crop step

                                if (img.Width < img.Height)
                                {
                                    int dif = img.Height - img.Width;
                                    left  = dif / 2;
                                    right = dif - left;
                                }

                                if (img.Height < img.Width)
                                {
                                    int dif = img.Width - img.Height;
                                    top    = dif / 2;
                                    bottom = dif - top;
                                }
                            }

                            if (padImages > 0)
                            {
                                top    += padImages;
                                bottom += padImages;
                                left   += padImages;
                                right  += padImages;
                            }

                            if ((top > 0) || (bottom > 0) || (left > 0) || (right > 0))
                            {
                                Image <Bgr, byte> padImg = new Image <Bgr, byte>(img.Width + left + right, img.Height + top + bottom);
                                CvInvoke.CopyMakeBorder(ogImg, padImg, top, bottom, left, right, Emgu.CV.CvEnum.BorderType.Constant, new MCvScalar(255, 255, 255)); // pad the image with a white background
                                ogImg = padImg;
                            }

                            if (ogImg.Width != widthHeight)
                            {
                                // resize the padded image
                                ogImg = ogImg.Resize(widthHeight, widthHeight, Emgu.CV.CvEnum.Inter.Linear);
                            }

                            trainStream(ogImg.ToBitmap(), trainingApi, project.Id, tag.Id.ToString());

                            for (var i = 0; i < 3; i++)
                            {
                                if ((new Random().Next(1, 11)) <= 5)
                                {
                                    // 50% of the time flip the image horizontally before rotation
                                    ogImg = ogImg.Flip(Emgu.CV.CvEnum.FlipType.Horizontal);
                                }
                                trainStream(ogImg.Rotate(new Random().Next(-45, 45), new Bgr(255, 255, 255)).ToBitmap(), trainingApi, project.Id, tag.Id.ToString()); // rotate with a white background
                            }
                        }
                        else
                        {
                            trainingApi.CreateImagesFromData(project.Id, image, new List <string>()
                            {
                                tag.Id.ToString()
                            });
                        }
                    }
                    catch (Exception e)
                    {
                        //kill exception and carry on
                        Console.WriteLine(e);
                    }
                }
            }

            try
            {
                using (TextWriter writer = new StreamWriter($"{trainingSetPath}\\trainingModel.csv"))
                {
                    var csv = new CsvWriter(writer);

                    csv.WriteRecords(trainingModel);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }
예제 #3
0
        static void Main(string[] args)

        {
            // Add your training & prediction key from the settings page of the portal

            string trainingKey   = "<enter your training key here>";
            string predictionKey = "<enter your prediction key here>";


            // Create the Api, passing in the training key

            TrainingApi trainingApi = new TrainingApi()
            {
                ApiKey = trainingKey
            };


            // Find the object detection domain

            var domains            = trainingApi.GetDomains();
            var objDetectionDomain = domains.FirstOrDefault(d => d.Type == "ObjectDetection");


            // Create a new project

            Console.WriteLine("Creating new project:");
            var project = trainingApi.CreateProject("My New Project", null, objDetectionDomain.Id);


            // Make two tags in the new project

            var forkTag     = trainingApi.CreateTag(project.Id, "fork");
            var scissorsTag = trainingApi.CreateTag(project.Id, "scissors");

            Dictionary <string, double[]> fileToRegionMap = new Dictionary <string, double[]>()
            {
                // A bounding box is specified in normalized coordinates using pixels of the object in the image.
                //  Normalized Left = Left / Width (in Pixels)
                //  Normalized Top = Top / Height (in Pixels)
                //  Normalized Bounding Box Width = (Right - Left) / Width (in Pixels)
                //  Normalized Bounding Box Height = (Bottom - Top) / Height (in Pixels)
                // FileName, Left, Top, Width, Height
                { "scissors_1", new double[] { 0.4007353, 0.194068655, 0.259803921, 0.6617647 } },
                { "scissors_2", new double[] { 0.426470578, 0.185898721, 0.172794119, 0.5539216 } },
                { "scissors_3", new double[] { 0.289215684, 0.259428144, 0.403186262, 0.421568632 } },
                { "scissors_4", new double[] { 0.343137264, 0.105833367, 0.332107842, 0.8055556 } },
                { "scissors_5", new double[] { 0.3125, 0.09766343, 0.435049027, 0.71405226 } },
                { "scissors_6", new double[] { 0.379901975, 0.24308826, 0.32107842, 0.5718954 } },
                { "scissors_7", new double[] { 0.341911763, 0.20714055, 0.3137255, 0.6356209 } },
                { "scissors_8", new double[] { 0.231617644, 0.08459154, 0.504901946, 0.8480392 } },
                { "scissors_9", new double[] { 0.170343131, 0.332957536, 0.767156839, 0.403594762 } },
                { "scissors_10", new double[] { 0.204656869, 0.120539248, 0.5245098, 0.743464053 } },
                { "scissors_11", new double[] { 0.05514706, 0.159754932, 0.799019635, 0.730392158 } },
                { "scissors_12", new double[] { 0.265931368, 0.169558853, 0.5061275, 0.606209159 } },
                { "scissors_13", new double[] { 0.241421565, 0.184264734, 0.448529422, 0.6830065 } },
                { "scissors_14", new double[] { 0.05759804, 0.05027781, 0.75, 0.882352948 } },
                { "scissors_15", new double[] { 0.191176474, 0.169558853, 0.6936275, 0.6748366 } },
                { "scissors_16", new double[] { 0.1004902, 0.279036, 0.6911765, 0.477124184 } },
                { "scissors_17", new double[] { 0.2720588, 0.131977156, 0.4987745, 0.6911765 } },
                { "scissors_18", new double[] { 0.180147052, 0.112369314, 0.6262255, 0.6666667 } },
                { "scissors_19", new double[] { 0.333333343, 0.0274019931, 0.443627447, 0.852941155 } },
                { "scissors_20", new double[] { 0.158088237, 0.04047389, 0.6691176, 0.843137264 } },
                { "fork_1", new double[] { 0.145833328, 0.3509314, 0.5894608, 0.238562092 } },
                { "fork_2", new double[] { 0.294117659, 0.216944471, 0.534313738, 0.5980392 } },
                { "fork_3", new double[] { 0.09191177, 0.0682516545, 0.757352948, 0.6143791 } },
                { "fork_4", new double[] { 0.254901975, 0.185898721, 0.5232843, 0.594771266 } },
                { "fork_5", new double[] { 0.2365196, 0.128709182, 0.5845588, 0.71405226 } },
                { "fork_6", new double[] { 0.115196079, 0.133611143, 0.676470637, 0.6993464 } },
                { "fork_7", new double[] { 0.164215669, 0.31008172, 0.767156839, 0.410130739 } },
                { "fork_8", new double[] { 0.118872553, 0.318251669, 0.817401946, 0.225490168 } },
                { "fork_9", new double[] { 0.18259804, 0.2136765, 0.6335784, 0.643790841 } },
                { "fork_10", new double[] { 0.05269608, 0.282303959, 0.8088235, 0.452614367 } },
                { "fork_11", new double[] { 0.05759804, 0.0894935, 0.9007353, 0.3251634 } },
                { "fork_12", new double[] { 0.3345588, 0.07315363, 0.375, 0.9150327 } },
                { "fork_13", new double[] { 0.269607842, 0.194068655, 0.4093137, 0.6732026 } },
                { "fork_14", new double[] { 0.143382356, 0.218578458, 0.7977941, 0.295751631 } },
                { "fork_15", new double[] { 0.19240196, 0.0633497, 0.5710784, 0.8398692 } },
                { "fork_16", new double[] { 0.140931368, 0.480016381, 0.6838235, 0.240196079 } },
                { "fork_17", new double[] { 0.305147052, 0.2512582, 0.4791667, 0.5408496 } },
                { "fork_18", new double[] { 0.234068632, 0.445702642, 0.6127451, 0.344771236 } },
                { "fork_19", new double[] { 0.219362751, 0.141781077, 0.5919118, 0.6683006 } },
                { "fork_20", new double[] { 0.180147052, 0.239820287, 0.6887255, 0.235294119 } }
            };


            // Add all images for fork

            var imagePath        = Path.Combine("Images", "fork");
            var imageFileEntries = new List <ImageFileCreateEntry>();

            foreach (var fileName in Directory.EnumerateFiles(imagePath))
            {
                var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
                imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List <Region>(new Region[] { new Region(forkTag.Id, region[0], region[1], region[2], region[3]) })));
            }

            trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));


            // Add all images for scissors

            imagePath        = Path.Combine("Images", "scissors");
            imageFileEntries = new List <ImageFileCreateEntry>();
            foreach (var fileName in Directory.EnumerateFiles(imagePath))
            {
                var region = fileToRegionMap[Path.GetFileNameWithoutExtension(fileName)];
                imageFileEntries.Add(new ImageFileCreateEntry(fileName, File.ReadAllBytes(fileName), null, new List <Region>(new Region[] { new Region(scissorsTag.Id, region[0], region[1], region[2], region[3]) })));
            }

            trainingApi.CreateImagesFromFiles(project.Id, new ImageFileCreateBatch(imageFileEntries));

            // Now there are images with tags start training the project

            Console.WriteLine("\tTraining");
            var iteration = trainingApi.TrainProject(project.Id);


            // The returned iteration will be in progress, and can be queried periodically to see when it has completed

            while (iteration.Status == "Training")
            {
                Thread.Sleep(1000);

                // Re-query the iteration to get its updated status
                iteration = trainingApi.GetIteration(project.Id, iteration.Id);
            }


            // The iteration is now trained. Make it the default project endpoint

            iteration.IsDefault = true;
            trainingApi.UpdateIteration(project.Id, iteration.Id, iteration);
            Console.WriteLine("Done!\n");


            // Now there is a trained endpoint, it can be used to make a prediction
            // Create a prediction endpoint, passing in the obtained prediction key

            PredictionEndpoint endpoint = new PredictionEndpoint()
            {
                ApiKey = predictionKey
            };

            // Make a prediction against the new project

            Console.WriteLine("Making a prediction:");

            var imageFile = Path.Combine("Images", "test", "test_image.jpg");

            using (var stream = File.OpenRead(imageFile))

            {
                var result = endpoint.PredictImage(project.Id, File.OpenRead(imageFile));

                // Loop over each prediction and write out the results
                foreach (var c in result.Predictions)
                {
                    Console.WriteLine($"\t{c.TagName}: {c.Probability:P1} [ {c.BoundingBox.Left}, {c.BoundingBox.Top}, {c.BoundingBox.Width}, {c.BoundingBox.Height} ]");
                }
            }

            Console.ReadKey();
        }
예제 #4
0
        public static async Task TrainAsync(ParsingOptions options)
        {
            // Create the Api, passing in the training key
            var trainingApi = new TrainingApi {
                ApiKey = options.TrainingKey
            };
            CognitiveServiceTrainerStorage storageImages = new CognitiveServiceTrainerStorage();

            if (options.Delete)
            {
                try
                {
                    await DeleteImagesAndTagsAsync(options, trainingApi);

                    storageImages.DeleteDB();
                    Console.WriteLine("Images and tags successfully deleted.");
                }
                catch
                {
                }
                if (string.IsNullOrEmpty(options.Folder))
                {
                    return;
                }
            }

            var fullFolder = Path.GetFullPath(options.Folder);

            if (!Directory.Exists(fullFolder))
            {
                Console.WriteLine($"Error: folder \"{fullFolder}\" does not exist.");
                Console.WriteLine(string.Empty);
                return;
            }

            try
            {
                //await DeleteImagesAndTagsAsync(options, trainingApi);
                foreach (var dir in Directory.EnumerateDirectories(fullFolder).Where(f => !Path.GetFileName(f).StartsWith("!")))
                {
                    var tagName = Path.GetFileName(dir).ToLower();
                    Console.WriteLine($"\nCheck latest images uploaded '{tagName}'...");
                    IList <Microsoft.Cognitive.CustomVision.Training.Models.Image> imagesAlreadyExists    = new List <Microsoft.Cognitive.CustomVision.Training.Models.Image>();
                    IList <Microsoft.Cognitive.CustomVision.Training.Models.Image> imagesAlreadyExistsTmp = new List <Microsoft.Cognitive.CustomVision.Training.Models.Image>();
                    int skip = 0;
                    while ((imagesAlreadyExistsTmp = await trainingApi.GetTaggedImagesAsync(options.ProjectId, tagIds: new[] { tagName }, take: 50, skip: skip)).Any())
                    {
                        skip += 50;
                        foreach (var item in imagesAlreadyExistsTmp)
                        {
                            imagesAlreadyExists.Add(item);
                        }
                    }

                    Console.WriteLine($"\nCreating tag '{tagName}'...");
                    var tagExist = storageImages.FindTag(tagName, options.ProjectId);
                    Tag tag      = null;
                    if (tagExist == null)
                    {
                        tag = await trainingApi.CreateTagAsync(options.ProjectId, tagName);

                        storageImages.InsertTag(new Storage.Collections.StorageTag {
                            IdCustomVision = tag.Id, TagName = tag.Name, ProjectId = options.ProjectId
                        });
                    }
                    else
                    {
                        if (trainingApi.GetTag(tagExist.ProjectId, tagExist.IdCustomVision) == null)
                        {
                            await trainingApi.DeleteTagAsync(options.ProjectId, tagExist.IdCustomVision);

                            tag = await trainingApi.CreateTagAsync(options.ProjectId, tagName);

                            storageImages.InsertTag(new Storage.Collections.StorageTag {
                                IdCustomVision = tag.Id, TagName = tag.Name, ProjectId = options.ProjectId
                            });
                        }
                        else
                        {
                            tag = new Tag(tagExist.IdCustomVision, tagName);
                        }
                    }

                    var images = Directory.EnumerateFiles(dir, "*.*", SearchOption.AllDirectories)
                                 .Where(s => s.EndsWith(".jpg", StringComparison.InvariantCultureIgnoreCase) ||
                                        s.EndsWith(".jpeg", StringComparison.InvariantCultureIgnoreCase) ||
                                        s.EndsWith(".png", StringComparison.InvariantCultureIgnoreCase) ||
                                        s.EndsWith(".bmp", StringComparison.InvariantCultureIgnoreCase)).ToList();

                    List <ImageDto> tempImages = new List <ImageDto>();
                    for (int i = 0; i < images.Count; i++)
                    {
                        Stream imageToUpload = null;
                        string image         = images.ElementAt(i);
                        var    imageName     = Path.GetFileName(image);
                        var    storageImage  = storageImages.FindImage(image, options.ProjectId);
                        if (storageImage == null || !imagesAlreadyExists.Any(x => x.Id == storageImage.IdCustomVision))
                        {
                            // Resizes the image before sending it to the service.
                            using (var input = new MemoryStream(File.ReadAllBytes(image)))
                            {
                                if (options.Width.GetValueOrDefault() > 0 || options.Height.GetValueOrDefault() > 0)
                                {
                                    imageToUpload = await ResizeImageAsync(input, options.Width.GetValueOrDefault(), options.Height.GetValueOrDefault());
                                }
                                else
                                {
                                    imageToUpload = input;
                                }

                                tempImages.Add(new ImageDto
                                {
                                    FullName = image,
                                    FileName = imageName,
                                    Content  = imageToUpload.ToByteArray(),
                                    Tag      = tag
                                });
                                imageToUpload.Dispose();
                            }
                        }
                        else
                        {
                            Console.WriteLine($"Image already exist {imageName}...");
                        }
                        //Persist batch images
                        if (tempImages.Count % 32 == 0 && tempImages.Any() || (i == images.Count - 1))
                        {
                            await UploadImagesAsync(tempImages);

                            tempImages.Clear();
                            tempImages.Capacity = 0;
                        }
                    }
                }

                // Now there are images with tags start training the project
                Console.WriteLine("\nTraining...");
                var iteration = await trainingApi.TrainProjectAsync(options.ProjectId);

                // The returned iteration will be in progress, and can be queried periodically to see when it has completed
                while (iteration.Status == "Training")
                {
                    await Task.Delay(1000);

                    // Re-query the iteration to get it's updated status
                    iteration = trainingApi.GetIteration(options.ProjectId, iteration.Id);
                }

                // The iteration is now trained. Make it the default project endpoint
                iteration.IsDefault = true;
                trainingApi.UpdateIteration(options.ProjectId, iteration.Id, iteration);

                Console.WriteLine("Training completed.\n");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"\nUnexpected error: {ex.GetBaseException()?.Message}.\n");
            }



            async Task UploadImagesAsync(List <ImageDto> images)
            {
                ImageFileCreateBatch imageFileCreateBatch = new ImageFileCreateBatch();

                imageFileCreateBatch.Images = new List <ImageFileCreateEntry>();
                foreach (var img in images)
                {
                    imageFileCreateBatch.Images.Add(new ImageFileCreateEntry
                    {
                        Name     = img.FullName,
                        TagIds   = new [] { img.Tag.Id },
                        Contents = img.Content
                    });
                    Console.WriteLine($"Uploading image {img.FileName}...");
                }
                await Policy
                .Handle <Exception>()
                .WaitAndRetryAsync(retries)
                .ExecuteAsync(async() =>
                {
                    ImageCreateSummary reponseCognitiveService = await trainingApi.CreateImagesFromFilesAsync(options.ProjectId, imageFileCreateBatch);
                    if (reponseCognitiveService.Images != null)
                    {
                        for (int i = 0; i < reponseCognitiveService.Images.Count; i++)
                        {
                            var img = reponseCognitiveService.Images.ElementAt(i);
                            // https://docs.microsoft.com/en-us/rest/api/cognitiveservices/customvisiontraining/createimagesfrompredictions/createimagesfrompredictions
                            if ((img.Status == "OK" || img.Status == "OKDuplicate") && img.Image != null)
                            {
                                var uploadedImage = img.Image;
                                var tagsToStore   = uploadedImage.Tags?
                                                    .Select(x => new Storage.Collections.StorageImageTag()
                                {
                                    Created = x.Created,
                                    TagId   = x.TagId
                                }).ToList();
                                storageImages.InsertImage(new Storage.Collections.StorageImage()
                                {
                                    ProjectId      = options.ProjectId,
                                    FullFileName   = imageFileCreateBatch.Images.ElementAt(i).Name,
                                    IdCustomVision = uploadedImage.Id,
                                    ImageUri       = uploadedImage.ImageUri,
                                    Created        = uploadedImage.Created,
                                    Height         = uploadedImage.Height,
                                    Tags           = tagsToStore,
                                    ThumbnailUri   = uploadedImage.ThumbnailUri,
                                    Width          = uploadedImage.Width
                                });
                            }
                            else
                            {
                                Console.WriteLine($"API bad response: {img.Status }");
                                throw new InvalidOperationException($"API bad response: {img.Status }");
                            }
                        }
                    }
                });

                await Task.Delay(500);
            }
        }
예제 #5
0
        protected override async Task <CreateImageSummaryModel> UploadImagesByTagsAsync(IEnumerable <Image> images, Guid projectId, ICollection <Guid> tagIds)
        {
            var imageArray = images.ToList();
            Func <Task <CreateImageSummaryModel> > createImagesFromUrls = async() => await TrainingApi.CreateImagesFromUrlsAsync(
                projectId,
                new ImageUrlCreateBatch(tagIds : tagIds.ToList(), urls : imageArray.Select(x => x.Path).ToList()));

            return(await RetryHelper.RetryFuncAsync(
                       createImagesFromUrls,
                       new[] { typeof(HttpOperationException), typeof(TaskCanceledException) },
                       RetryTimes));
        }
예제 #6
0
        public static async Task <HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestMessage req, TraceWriter log)
        {
            try
            {
                var allTags     = new List <string>();
                var json        = req.Content.ReadAsStringAsync().Result;
                var jobj        = JObject.Parse(json);
                var tags        = (JArray)jobj["tags"];
                var term        = jobj["term"].ToString();
                var projectId   = jobj["projectId"].ToString();
                var trainingKey = jobj["trainingKey"].ToString();
                var offset      = 0;

                if (jobj["offset"] != null)
                {
                    offset = (int)jobj["offset"];
                }

                var imageUrls = await SearchForImages(term, offset);

                var api     = new TrainingApi(new TrainingApiCredentials(trainingKey));
                var project = api.GetProject(Guid.Parse(projectId));

                var tagModels    = new List <ImageTagModel>();
                var existingTags = api.GetTags(project.Id);
                foreach (string tag in tags)
                {
                    ImageTagModel model = existingTags.Tags.SingleOrDefault(t => t.Name == tag);

                    if (model == null)
                    {
                        model = api.CreateTag(project.Id, tag.Trim());
                    }

                    tagModels.Add(model);
                }

                var batch   = new ImageUrlCreateBatch(tagModels.Select(m => m.Id).ToList(), imageUrls);
                var summary = api.CreateImagesFromUrls(project.Id, batch);

                //if(!summary.IsBatchSuccessful)
                //	return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Image batch was unsuccessful");

                //Traing the classifier and generate a new iteration, that we'll set as the default
                var iteration = api.TrainProject(project.Id);

                while (iteration.Status == "Training")
                {
                    Thread.Sleep(1000);
                    iteration = api.GetIteration(project.Id, iteration.Id);
                }

                iteration.IsDefault = true;
                api.UpdateIteration(project.Id, iteration.Id, iteration);

                return(req.CreateResponse(HttpStatusCode.OK, iteration.Id));
            }
            catch (Exception e)
            {
                var exception = e.GetBaseException();
                return(req.CreateErrorResponse(HttpStatusCode.BadRequest, exception.Message));
            }

            async Task <List <string> > SearchForImages(string term, int offset)
            {
                var client = new HttpClient();

                client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "c2adf0e5c057447ea9e0f50cc5202251");
                var uri = $"https://api.cognitive.microsoft.com/bing/v7.0/images/search?count=50&q={term}&offset={offset}";

                var json = await client.GetStringAsync(uri);

                var jobj = JObject.Parse(json);
                var arr  = (JArray)jobj["value"];

                var list = new List <string>();

                foreach (var result in arr)
                {
                    list.Add(result["contentUrl"].ToString());
                }

                return(list);
            }
        }