我测试的时候上传了很多图片进行测试,但是出现内存不足的情况,
我猜测应该是数据流的问题,请教大神们可以帮我看一下么?
using Google.Cloud.Vision.V1;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction;
using Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Threading.Tasks;
using System.Web;
namespace MealAnalysis
{
public class MealAnalysis
{
//------------------------------
// 固定値
//------------------------------
// 文字列解析用(QRコードを採用したため、今回は利用しない)
const string cstrsubscriptionkey = "8f59b9dcca164bada9935a0ecb71e843"; // 富士フイルム様用に作成したAPI
const string cstrUri = "https://japaneast.api.cognitive.microsoft.com/vision/v1.0/recognizeText?"; // 文字解析呼び出しUri
const string cstrHeaderKey = "Ocp-Apim-Subscription-Key"; // API呼び出し時必ず指定するHeaderKey
const string cstrQuantityUri = "https://japaneast.api.cognitive.microsoft.com/vision/v1.0/recognizeText?"; // 文字解析呼び出しUri
// CustomVision
const string cstrEndPoint = "https://japaneast.api.cognitive.microsoft.com/";
// Azure Custom Vision Prediction Key
const string cstrMealPredictionId = "XXXXXXXXXXX";
const string cstrAmountOfStapleFoodPredictionId = "XXXXXXXXXXX";
const string cstrAmountOfMainDishPredictionId = "XXXXXXXXXXX";
const string cstrAmountOfSideDishPredictionId = "XXXXXXXXXXX";
const string cstrAmountOfSteapleMainPredictionId = "XXXXXXXXXXX";
// Azure Custom Vision Project Key
//const string cstrMealProjectId = "XXXXX";
const string cstrMealProjectId = "XXXXXd";
const string cstrAmountOfStapleFoodProjectId = "XXXXXdd";
const string cstrAmountOfMainDishProjectId = "";
const string cstrAmountOfSideDishProjectId = "";
const string cstrAmountOfSteapleMainProjectId = "";
// Azure Custom Vision PublishedName
const string cstrMeal = "Iteration5";
const string cstrAmountOfStapleFood = "Iteration5";
const string cstrAmountOfMainDish = "Iteration4";
const string cstrAmountOfSideDish = "Iteration3";
const string cstrAmountOfSteapleMain = "Iteration2";
//============================================================
// 【説明】
// 画像を読み込んで、オブジェクトの位置を特定し、返却する関数
//
// 【引数】
// JSON
// 画像ファイルパス
// 【戻り値】
// JSON
// result:true/false
// true:正常
// false:異常
// errorMessage:string
// エラーの内容
// code:#から始まる取得した結果
//============================================================
public static string GetTableWare(string strImageJsonData)
{
//------------------------------
// 変数宣言
//------------------------------
string strResultData = "";
string strFilePath = "";
//------------------------------
// 通常処理
//------------------------------
try
{
// パラメータで渡されたJSONデータからデータの取得
var objImageJsonData = JObject.Parse(strImageJsonData);
// 判定処理
strFilePath = objImageJsonData.GetValue("filename").ToString();
// 秘密鍵のファイルパス(必ず登録されている必要がある。)
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", @"C:\key\FCompany2babd1355150.json", EnvironmentVariableTarget.Process);
// イメージファイルをメモリに読み込む
var image = Image.FromFile(strFilePath);
// Google Vision Ai 呼び出し
ImageAnnotatorClient client = ImageAnnotatorClient.Create();
IReadOnlyList<LocalizedObjectAnnotation> DetectLocalizedObjects = client.DetectLocalizedObjects(image);
// 戻り値の返却
strResultData = DetectLocalizedObjects.ToString();
// JSON形式にして、取得できたオブジェクトの数をカウントする
var jsonData = JArray.Parse(strResultData);
int MealCount = jsonData.Count;
// 戻り値のデータ作成
strResultData = "{\"Result\":\"true\",\"NumberOfObject\":\""+ MealCount.ToString() +"\",\"DataOfObject\":" + strResultData + ",\"ErrorMessage\":\"\"}";
return strResultData;
}
//------------------------------
// エラー処理
//------------------------------
catch (Exception ex)
{
strResultData = "{\"Result\":\"false\",\"NumberOfObject\":\"0\",\"DataOfObject\":{},\"ErrorMessage\":\"" + ex.Message + "\"}";
}
//------------------------------
// 後処理
//------------------------------
finally
{
}
// 戻り値を返却
return strResultData;
}
//============================================================
// 【説明】
// オブジェクトを解析して、解析結果を返却する関数
//
// 【引数】
// JSON
// (正面データ)画像ファイルパス
// (正面データ)GetTabelWareで取得したDataOfObject Jsonの値(解析結果)
// (斜めデータ)画像ファイルパス
// (斜めデータ)GetTabelWareで取得したDataOfObject Jsonの値(解析結果)
// 【戻り値】
// JSON
// result:true/false
// true:正常
// false:異常
// Staplefood :double(割合の値)
// MainDish :double(割合の値)
// SideDish :double(割合の値)
// errorMessage:string(エラーの内容)
//============================================================
public static string QuantityAnalysis(string strImageJsonData)
{
//------------------------------
// 変数宣言
//------------------------------
string strResultData = "";
string strFilePathA = "";
string strFilePathB = "";
string strJsonfileDataA = "";
string strJsonfileDataB = "";
//------------------------------
// 通常処理
//------------------------------
try
{
// パラメータで渡されたJSONデータからデータの取得
var objImageJsonData = JArray.Parse(strImageJsonData);
if (objImageJsonData.Count < 2){
// 2以下は、データがそろっていないため、エラー
strResultData = "{\"Result\":\"false\",\"Staplefood\":\"\",\"MainDish\":\"\",\"SideDish\":\"\",\"ErrorMessage\":\"該当データが見つかりませんでした。\"}";
}
else
{
// 判定処理
JToken objTokenA = objImageJsonData[0];
var objImageJsonDataA = objTokenA as JObject;
strFilePathA = objImageJsonDataA.GetValue("filename").ToString();
strJsonfileDataA = objImageJsonDataA.GetValue("DataOfObject").ToString();
JToken objTokenB = objImageJsonData[1];
var objImageJsonDataB = objTokenB as JObject;
strFilePathB = objImageJsonDataB.GetValue("filename").ToString();
strJsonfileDataB = objImageJsonDataB.GetValue("DataOfObject").ToString();
// ABの画像イメージを分解し、ローカルに切り抜いた画像をStreamで読み取り、解析を実行
// Aの画像を読み込ませ、解析結果を取得
QuantityAnalysisData objDataA = ImageAnalysis(strFilePathA, strJsonfileDataA);
//// ②の画像を読み込ませ、解析結果を取得
QuantityAnalysisData objDataB = ImageAnalysis(strFilePathB, strJsonfileDataB);
// 結果をマージする
// 足して2で割る
string Staplefood = "";
string MainDish = "";
string SideDish = "";
double returnA = 0;
double returnB = 0;
if( double.TryParse( objDataA.Staplefood,out returnA) == true){
if( double.TryParse( objDataB.Staplefood,out returnB) == true){
if( returnA < returnB ){
Staplefood = returnB.ToString();
}
else{
Staplefood = returnA.ToString();
}
}
else{
Staplefood = returnA.ToString();
}
}
else{
if( double.TryParse( objDataB.Staplefood,out returnB) == true){
Staplefood = returnB.ToString();
}
else{
Staplefood = "-";
}
}
if( double.TryParse( objDataA.MainDish,out returnA) == true){
if( double.TryParse( objDataB.MainDish,out returnB) == true){
if( returnA < returnB ){
MainDish = returnB.ToString();
}
else{
MainDish = returnA.ToString();
}
}
else{
MainDish = returnA.ToString();
}
}
else{
if( double.TryParse( objDataB.MainDish,out returnB) == true){
MainDish = returnB.ToString();
}
else{
MainDish = "-";
}
}
if( double.TryParse( objDataA.SideDish,out returnA) == true){
if( double.TryParse( objDataB.SideDish,out returnB) == true){
if( returnA < returnB ){
SideDish = returnB.ToString();
}
else{
SideDish = returnA.ToString();
}
}
else{
SideDish = returnA.ToString();
}
}
else{
if( double.TryParse( objDataB.SideDish,out returnB) == true){
SideDish = returnB.ToString();
}
else{
SideDish = "-";
}
}
// 結果を返却
strResultData = "{\"Result\":\"true\",\"Staplefood\":\"" + Staplefood + "\",\"MainDish\":\"" + MainDish + "\",\"SideDish\":\"" + SideDish + "\",\"ErrorMessage\":\"\"}";
}
}
//------------------------------
// エラー処理
//------------------------------
catch (Exception ex)
{
strResultData = "{\"Result\":\"false\",\"Staplefood\":\"\",\"MainDish\":\"\",\"SideDish\":\"\",\"ErrorMessage\":\"" + ex.Message + "\"}";
}
//------------------------------
// 後処理
//------------------------------
finally
{
}
// 戻り値を返却
return strResultData;
}
//============================================================
// 【説明】
// 文字列を解析して、解析結果を返却する関数
//
// 【引数】
// JSON
// 読み込む画像のPath
// 【戻り値】
// JSON
// result:true/false
// true:正常
// false:異常
// errorCode:string
// 01:文字列解析不能(#の文字列が取得できなかった)
// 02:上記以外
// errorMessage:string
// エラーの内容
// code:#から始まる取得した結果
//============================================================
public string CodeAuth(string strfilePath){
//------------------------------
// 変数宣言
//------------------------------
string strResultData ="";
//------------------------------
// 通常処理
//------------------------------
try
{
// 文字解析用API関数を実行
var task = CodeAuthAsync(strfilePath);
// APIからの実行結果を返却
task.Wait();
// 7.取得した結果contextをJson文字列に変換
var serializer = new DataContractJsonSerializer(typeof(PersonCodeAuth));
using (MemoryStream returnData = new MemoryStream(Encoding.UTF8.GetBytes(task.Result)))
{
returnData.Position = 0;
PersonCodeAuth deserialized = (PersonCodeAuth)serializer.ReadObject(returnData);
// 8.Json文字列のうちrecognitionResult.lines.text[]を取得
string recognitionStatus = deserialized.Status;
string[] recognitionResult = deserialized.recognitionResult;
string strNumber = "";
// 9.⑧で取得した文字列をトリム(間もすべて)
char[] checkChar = new char[' '];
foreach (string data in recognitionResult)
{
string trimRecognitionResult = data.Trim(checkChar);
// 10.先頭が[#]の文字列を取得
if (trimRecognitionResult.StartsWith("#") == true)
{
// ①⑩が取得できたら、以降は取得しない
strNumber = trimRecognitionResult.Replace("#", "");
break;
}
else
{
// ②⑩が取得できるまで処理を繰り返す
}
}
if (strNumber == "")
{
// 取得できなかった
strResultData = "{\"Result\":\"false\" ,\"Number\":\"\",\"ErrorMessage\":\"#を含む値が取得できませんでした。\"}";
}
else
{
// 取得できた
// 11.#付きの番号を返却(取得できなかった場合は、エラーで戻す)
strResultData = "{\"Result\":\"" + recognitionStatus + "\" ,\"Number\":\"" + strNumber + "\",\"ErrorMessage\":\"\"}";
}
}
strResultData = "{\"Result\":\"true\" ,\"Number\":\"#01\",\"ErrorMessage\":\"\"}";
}
//------------------------------
// エラー処理
//------------------------------
catch (Exception ex)
{
strResultData = "{\"Result\":\"false\" ,\"Number\":\"\",\"ErrorMessage\":\"" + ex.Message + "\"}";
}
//------------------------------
// 後処理
//------------------------------
finally
{
}
// 戻り値を返却
return strResultData;
}
//============================================================
// 【説明】
// Computer Vision AI呼び出し、解析結果を返却する関数
//
// 【引数】
// 読み込む画像のPath
// 【戻り値】
// JSON
// result:true/false
// true:正常
// false:異常
// errorCode:string
// 01:文字列解析不能(#の文字列が取得できなかった)
// 02:上記以外
// errorMessage:string
// エラーの内容
// code:#から始まる取得した結果
//============================================================
public async Task<string> CodeAuthAsync(string strFilePath)
{
//------------------------------
// 変数宣言
//------------------------------
var client = new HttpClient(); // API呼び出し用オブジェクト
var queryString = HttpUtility.ParseQueryString(string.Empty); // URLパラメータ
// 初期化
var strResult = "";
// Request headers
client.DefaultRequestHeaders.Add(cstrHeaderKey, cstrsubscriptionkey);
// Request parameters
queryString["handwriting"] = "true";
var Uri = cstrUri + queryString;
HttpResponseMessage response;
//ファイルを開く
System.IO.FileStream fs = new System.IO.FileStream(strFilePath,System.IO.FileMode.Open,System.IO.FileAccess.Read);
//ファイルを読み込むバイト型配列を作成する
byte[] byteData = new byte[fs.Length];
//ファイルの内容をすべて読み込む
fs.Read(byteData, 0, byteData.Length);
//閉じる
fs.Close();
using (var content = new ByteArrayContent(byteData))
{
content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
response = await client.PostAsync(Uri, content);
if (response.Headers.Contains("Operation-Location") == true)
{
var contentString = "";
string Operation = response.Headers.GetValues("Operation-Location").FirstOrDefault();
var clientdata = new HttpClient();
clientdata.DefaultRequestHeaders.Add(cstrHeaderKey, cstrsubscriptionkey);
bool getresult = true;
while (getresult)
{
HttpResponseMessage responsedata = await clientdata.GetAsync(Operation);
contentString = await responsedata.Content.ReadAsStringAsync();
if (contentString.ToLower().Contains("succeeded") == true)
{
// 正常
getresult = false;
}
else if (contentString.ToLower().Contains("running") == true)
{
// 待機
}
else
{
// エラー
// 該当メッセージを出力して終了
getresult = false;
}
// 無限ループにならないように気を付ける
}
strResult = contentString;
}
}
return strResult;
}
//============================================================
// 【説明】
// 画像を解析する関数
//
// 【引数】
// 読み込む画像のPath
// Googleから取得したJSONデータ
// 【戻り値】
// JSON
//
//
//============================================================
private static QuantityAnalysisData ImageAnalysis(string strFilePath,string strJsonData)
{
//========================================
// 変数
//========================================
QuantityAnalysisData objResult = new QuantityAnalysisData();
// ファイル単位で使用する、オブジェクトの初期化
List<QuantityData> listData = new List<QuantityData>(); // 取得したオブジェクトの各割合を保存
//========================================
// 処理
//========================================
try
{
//----------------------------------------
// ファイルを開き、Gogole Vision AIから取得したJSONデータをもとに、画像を取得する。
//----------------------------------------
// ファイルを開く
var image = Google.Cloud.Vision.V1.Image.FromFile(strFilePath);
ImageAnnotatorClient client = ImageAnnotatorClient.Create();
IReadOnlyList<LocalizedObjectAnnotation> DetectLocalizedObjects = client.DetectLocalizedObjects(image);
int imagew;
int imageh;
//image size 読み込む
using (FileStream fs = new FileStream(strFilePath, FileMode.Open, FileAccess.Read))
{
imagew = System.Drawing.Image.FromStream(fs).Width; //幅さ
imageh = System.Drawing.Image.FromStream(fs).Height; //高さ
}
foreach (LocalizedObjectAnnotation text in DetectLocalizedObjects)
{
//JSONを取得
string jsonstr = text.ToString();
JObject normalizedVertices = JObject.Parse(jsonstr);
var Zahyo = normalizedVertices["boundingPoly"]["normalizedVertices"];
//vertex 座標
var x0 = Convert.ToDouble(Zahyo[0]["x"]) * imagew;
var y0 = Convert.ToDouble(Zahyo[0]["y"]) * imageh;
var xW = (Convert.ToDouble(Zahyo[1]["x"]) - Convert.ToDouble(Zahyo[0]["x"])) * imagew;
var xH = (Convert.ToDouble(Zahyo[3]["y"]) - Convert.ToDouble(Zahyo[0]["y"])) * imageh;
float Fx0 = (float)Math.Round((double)x0, 15)-10;
float Fy0 = (float)Math.Round((double)y0, 15)-10;
float FxW = (float)Math.Round((double)xW, 15)+50;
float FxH = (float)Math.Round((double)xH, 15)+50;
//画像を分解します
string baseFilePath = strFilePath;
System.Drawing.Bitmap bmpBase = new System.Drawing.Bitmap(baseFilePath);
// 画像を切り抜く
System.Drawing.RectangleF rect = new System.Drawing.RectangleF(Fx0, Fy0, FxW, FxH);
System.Drawing.Bitmap bmpNew = bmpBase.Clone(rect, bmpBase.PixelFormat);
bmpNew.Save("C:\\temp\\test.Jpeg", ImageFormat.Jpeg);
bmpNew.Dispose();
//Stream streamS = new MemoryStream();
//bmpNew.Save(streamS, ImageFormat.Jpeg);
using (FileStream streamS = new FileStream("C:\\temp\\test.Jpeg", FileMode.Open, FileAccess.Read))
{
//----------------------------------------
// 変数宣言
//----------------------------------------
string strType = ""; // オブジェクトの種類(AmountOfStapleFood / AmountOfMainDish / AmountOfSiteDish / AmountOfSteaple&Main)
double objDouble = 0; // 選択されたオブジェクトの割合
double ProbalilitySum = 0; // 解析結果の合計値(オブジェクトの種類)
double objAmountDouble = 0; // 解析結果の量の判定
//----------------------------------------
// ①オブジェクトの判定
//----------------------------------------
// 分割したオブジェクトを渡して、何のオブジェクトか判断する(MealVision)
var listMailVisions = QuantityAnalysisyAsync(cstrMealPredictionId, cstrMealProjectId, cstrMeal, streamS);
foreach (PredictionModel objItem in listMailVisions)
{
// 0.001以下は無視する
if (0.001 < objItem.Probability)
{
// 合計を足す
ProbalilitySum += objItem.Probability;
// 戻り値によって、分析データをもとに、次の呼び出し関数を変更する
// 割合が一番大きいものを採用(でも判定結果は大きいもの順のようなので、チェックする必要はないかも。)
if (objDouble < objItem.Probability)
{
strType = objItem.TagName;
objDouble = objItem.Probability;
}
}
}
QuantityData objData = new QuantityData();
//----------------------------------------
// ②分量の判定
//----------------------------------------
// 解析した結果が、80%以上150未満の場合は分量を測定する処理を実行(それ以外はその他のオブジェクトとして処理を行わない)
// ハンさんのサンプルから実際データを取得し、この割合を考える
if (0.8 <= ProbalilitySum && ProbalilitySum <= 1.5)
{
string strPredictionId = "";
string strProjectId = "";
string strPublishedName = "";
// 分割したオブジェクトを渡して、分量を判断する(AmountOfStapleFood / AmountOfMainDish / AmountOfSideDish / AmountOfSteaple&Main)
switch (strType)
{
case "StapleBowl":
strPredictionId = cstrAmountOfStapleFoodPredictionId;
strProjectId = cstrAmountOfStapleFoodProjectId;
strPublishedName = cstrAmountOfStapleFood;
break;
case "MainDishPlate":
strPredictionId = cstrAmountOfMainDishPredictionId;
strProjectId = cstrAmountOfMainDishProjectId;
strPublishedName = cstrAmountOfMainDish;
break;
case "SubFoodPlate":
strPredictionId = cstrAmountOfSideDishPredictionId;
strProjectId = cstrAmountOfSideDishProjectId;
strPublishedName = cstrAmountOfSideDish;
break;
case "Bowl":
strPredictionId = cstrAmountOfSteapleMainPredictionId;
strProjectId = cstrAmountOfSteapleMainProjectId;
strPublishedName = cstrAmountOfSteapleMain;
break;
default:
break;
}
if(string.IsNullOrEmpty(strPredictionId) == false)
{
objData.Type = strType;
var listItem = QuantityAnalysisyAsync(strPredictionId, strProjectId, strPublishedName, new FileStream("C:\\temp\\test.Jpeg", FileMode.Open, FileAccess.Read));
// 初期化
double ProbalilityItemSum = 0;
foreach (PredictionModel objItem in listItem)
{
// 0.001以下は無視する
if (0.01 < objItem.Probability)
{
// 合計を足す
ProbalilityItemSum += objItem.Probability;
// 割合が一番大きいものを採用
if (objAmountDouble < objItem.Probability)
{
switch (objItem.TagName)
{
case "0段階":
objAmountDouble += 0 * objItem.Probability;
break;
case "1段階":
case "2段階":
objAmountDouble += 25 * objItem.Probability;
break;
case "3段階":
objAmountDouble += 50 * objItem.Probability;
break;
case "4段階":
objAmountDouble += 75 * objItem.Probability;
break;
case "5段階":
objAmountDouble += 100 * objItem.Probability;
break;
}
}
}
}
// 食事の種類と、食事量を配列に格納する。
objData.Quantity = objAmountDouble.ToString();
listData.Add(objData);
}
}
else
{
// 主食、主菜、副菜以外のオブジェクトと見直し、判断材料としない。
}
}
}
//--------------------------------------------------------------------------------
// ③すべての分類が完了したら、主食、副食(主菜)、副食(副菜)単位で割合を計算する
//--------------------------------------------------------------------------------
// 初期化
objResult.Staplefood = "-";
objResult.MainDish = "-";
objResult.SideDish = "-";
foreach (QuantityData objData in listData)
{
double dblResult = 0;
if (objData.Quantity == "-")
{
//何もしない
}
else
{
switch (objData.Type)
{
case "StapleBowl":
if (double.TryParse(objResult.Staplefood, out dblResult) == false)
{
objResult.Staplefood = objData.Quantity;
}
else
{
// 結果のほうが大きい時だけ値を設定する
if (dblResult < double.Parse(objData.Quantity))
{
objResult.Staplefood = objData.Quantity;
}
}
break;
case "MainDishPlate":
if (double.TryParse(objResult.MainDish, out dblResult) == false)
{
objResult.MainDish = objData.Quantity;
}
else
{
// 結果のほうが大きい時だけ値を設定する
if (dblResult < double.Parse(objData.Quantity))
{
objResult.MainDish = objData.Quantity;
}
}
break;
case "SubFoodPlate":
if (double.TryParse(objResult.SideDish, out dblResult) == false)
{
objResult.SideDish = objData.Quantity;
}
else
{
// 結果のほうが大きい時だけ値を設定する
if (dblResult < double.Parse(objData.Quantity))
{
objResult.SideDish = objData.Quantity;
}
}
break;
case "Bowl":
if (double.TryParse(objResult.Staplefood, out dblResult) == false)
{
objResult.Staplefood = objData.Quantity;
}
else
{
// 結果のほうが大きい時だけ値を設定する
if (dblResult < double.Parse(objData.Quantity))
{
objResult.Staplefood = objData.Quantity;
}
}
if (double.TryParse(objResult.MainDish, out dblResult) == false)
{
objResult.MainDish = objData.Quantity;
}
else
{
// 結果のほうが大きい時だけ値を設定する
if (dblResult < double.Parse(objData.Quantity))
{
objResult.MainDish = objData.Quantity;
}
}
break;
default:
break;
}
}
}
// 戻り値を返却する
return objResult;
}
//========================================
// エラー処理
//========================================
catch (Exception ex){
throw new Exception("ImageAnalysis Error." + ex.Message,ex);
}
finally
{
}
}
//============================================================
// 【説明】
// Custom Vision AI呼び出し、解析結果を返却する関数
//
// 【引数】
// 読み込む画像のPath
// 【戻り値】
// JSON
// List<PredictionModel> Cognitiveの戻り値
//
//============================================================
private static IList<PredictionModel> QuantityAnalysisyAsync(string strApiKey, string strProjectId,string strPublishedName, Stream filestream)
{
//------------------------------
// 変数宣言
//------------------------------
try{
// izumozaki ok st
CustomVisionPredictionClient endpoint = new CustomVisionPredictionClient()
{
ApiKey = strApiKey, // PredictionKey
Endpoint = cstrEndPoint // EndPoint
};
// 分析開始
var objImagePrediction = endpoint.ClassifyImage(Guid.Parse(strProjectId), strPublishedName, filestream); // Project Id,PublishedName
return objImagePrediction.Predictions;
// izumozaki ed
}
catch(Exception ex){
throw new Exception("QuantityAnalysisAsync" + ex.Message,ex);
}
finally
{
}
}
public class PersonCodeAuth {
public string Status { get; set; }
public string[] recognitionResult { get; set; }
}
public class GoogleAIVisionJson
{
public string Result { get; set; }
public string NumberObObject { get; set; }
public string[] DataOfObject { get; set; }
}
// CustomVisionから取得したオブジェクトの種類ごとのデータ
public class QuantityAnalysisData
{
public string Staplefood { get; set; }
public string MainDish { get; set; }
public string SideDish { get; set; }
}
// CustomVisionから取得した個々のデータ
public class QuantityData
{
public string Type { get; set; }
public string Quantity { get; set; }
}
}
}