Exemplo n.º 1
0
        public static BattleUnit AnalyzeParameter(PredictedInfo image, IEnumerable <Tag> tags)
        {
            // TODO 重複排除とか色々再考する
            // TODO HPが低すぎてバトルがすぐ終わるので数値の重みづけを再考する
            var elements = image.Result.Predictions.Join(
                tags,
                x => x.TagName,
                y => y.TagName,
                (x, y) => new BattleElement()
            {
                Name     = x.TagName,
                HP       = (int)Math.Floor(y.HP * x.Probability),
                Attack   = (int)Math.Floor(y.Attack * x.Probability),
                Mobility = (int)Math.Floor(y.Mobility * x.Probability),
                Remark   = $"{x.TagName}: {x.Probability}"
            });

            return(new BattleUnit()
            {
                Id = Guid.NewGuid(),
                PredictedInfoKey = image.RowKey,
                Name = image.ModelName,
                HP = elements.Sum(x => x.HP),
                Attack = elements.Sum(x => x.Attack),
                Mobility = elements.Sum(x => x.Mobility),
                Attributes = elements.Select(x => x.Name).ToList(),
                Remark = string.Join(",", elements.Select(x => x.Remark))
            });
        }
Exemplo n.º 2
0
        public static async Task <HttpResponseMessage> ImageUpload(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "images/upload")] HttpRequestMessage req,
            [Table("Users")] IQueryable <User> users,
            [Table("CreateImageFromUrls")] IQueryable <CreateImageFromUrlsEntity> imageUrls,
            [Queue("create-image-from-urls")] ICollector <CreateImageFromUrlsRequest> queueItems,
            [Table("CreateImageFromUrls")] ICollector <CreateImageFromUrlsEntity> outImageUrlTable,
            [Table("PredictedInfo")] ICollector <PredictedInfo> outPredictedTable,
            TraceWriter log,
            Microsoft.Azure.WebJobs.ExecutionContext context)
        {
            log.Info("C# HTTP trigger function processed a request.");

            // collect input
            dynamic data = await req.Content.ReadAsAsync <object>();

            string imageData          = data.image;
            ICollection <string> tags = data.tags.ToObject <List <string> >();
            string modelName          = data.modelName;

            log.Info($"modelName={modelName}tags={string.Join(",", tags)}, image={imageData}");

            var dataUrlReg = Regex.Match(imageData, @"data:image/(?<type>.+?);base64,(?<data>.+)");
            var image      = Convert.FromBase64String(dataUrlReg.Groups["data"].Value);
            var extension  = dataUrlReg.Groups["type"].Value;

            // client
            var CV_ProjectId     = Environment.GetEnvironmentVariable("CV_ProjectId");
            var CV_TrainingKey   = Environment.GetEnvironmentVariable("CV_TrainingKey");
            var CV_PredictionKey = Environment.GetEnvironmentVariable("CV_PredictionKey");
            var trainingApi      = new TrainingApi()
            {
                ApiKey = CV_TrainingKey
            };
            var predictionEndpoint = new PredictionEndpoint()
            {
                ApiKey = CV_PredictionKey
            };
            var projectId = Guid.Parse(CV_ProjectId);

            // collect user
            var user  = User.FromRequest(users, req, Thread.CurrentPrincipal);
            var iuser = user as IUser;

            // 既存のタグのみを受け付ける
            var existTags = await trainingApi.GetTagsAsync(projectId);

            tags = tags.Intersect(existTags.Select(x => x.Name)).ToList();

            // setup blob
            // https://docs.microsoft.com/ja-jp/azure/cosmos-db/table-storage-design-guide#log-tail-pattern
            var invertedTicks = string.Format("{0:D19}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);
            var blobName      = invertedTicks + "-" + Guid.NewGuid().ToString();

            var blockBlob          = CommonHelper.PhotoBlobReference(blobName);
            var blockBlobThumbnail = CommonHelper.PhotoThumbnailBlobReference(blobName);

            blockBlob.Properties.ContentType          = "image/jpeg";
            blockBlobThumbnail.Properties.ContentType = "image/jpeg";

            var url    = blockBlob.Uri.ToString();
            var source = "Upload";
            var key    = blockBlob.Name;

            log.Info($"pre upload. blobUri={url}");

            // XXX この辺りの一連の手続きをいい感じに関数分割してフロー処理できると可用性と変更影響範囲が良くなりそう
            // ただ、この程度の規模のサービスで1関数で同期的に処理する平易さ以上のメリットを得られるかは疑問

            // normalize image
            MemoryStream   normalizedImage = NormalizeImage(image);
            AnchorLocation anchor          = DetectFocusAnchor(log, normalizedImage, context.FunctionAppDirectory);

            log.Info($"Anchor: {anchor.ToString()}");
            MemoryStream thumbnailImage = ToThumbnailImage(image, anchor);

            // upload image
            normalizedImage.Position = 0;
            thumbnailImage.Position  = 0;
            await blockBlob.UploadFromStreamAsync(normalizedImage);

            await blockBlobThumbnail.UploadFromStreamAsync(thumbnailImage);

            log.Info($"after upload.");

            // queue image for training
            // 使用しているAPIの都合上、BLOBがアップロード後である必要がある
            TrainingImageLogic.AddImage(
                imageUrls, queueItems, outImageUrlTable, log,
                source, url, key, tags, user, modelName
                );
            log.Info($"after queue image data.");

            // predict image
            // https://docs.microsoft.com/ja-jp/azure/cognitive-services/custom-vision-service/csharp-tutorial
            var imageUrl = new ImageUrl()
            {
                Url = url
            };
            // XXX Storage emurator で通すならNgrock等の工夫が必要。単にDevelop用のStorage Accountを取ってしまった方が楽かも。
            var predictResult = await predictionEndpoint.PredictImageUrlAsync(projectId, imageUrl);

            log.Info($"after prediction.");
            var predicted = new PredictedInfo()
            {
                PartitionKey = source,
                RowKey       = key,
                Result       = predictResult,
                User         = user,
                ModelName    = modelName
            };

            outPredictedTable.Add(predicted);

            return(req.CreateJsonResponse(HttpStatusCode.OK, new
            {
                name = blockBlob.Name,
                url,
                result = predictResult
            }));
        }