/// <summary> /// Implementation of <see cref="ChestXRayAIClient.Analyze(SKBitmap, CancellationToken)"/> using a single model. /// </summary> public override Task <(ScoreOutput[], CAM[])> Analyze(SKBitmap inputImage, CancellationToken cancellationToken) { ValidateImageDimensions(inputImage); return(Task.Factory.StartNew(() => { // We have to check for cancellation before each of the following steps // Pass the image to the model and run an inference on it cancellationToken.ThrowIfCancellationRequested(); float[][] modelOutputs = model.Predict(inputImage); // Extract the score data and package it up into a convenient object array (ScoreOutput[]) cancellationToken.ThrowIfCancellationRequested(); float[] scoreData = modelOutputs[0]; ScoreOutput[] scores = GenerateScoreArray(scoreData); // Extract the CAM data and post-process it to generate the CAM objects cancellationToken.ThrowIfCancellationRequested(); float[] camData = modelOutputs[1]; CAM[] cams = GenerateCAMArray(camData); // Final cancellation check cancellationToken.ThrowIfCancellationRequested(); return (scores, cams); }, cancellationToken)); }
private Task <ScoreOutput[]> GetScores(SKBitmap inputImage, CancellationToken cancellationToken) { return(Task.Factory.StartNew(() => { cancellationToken.ThrowIfCancellationRequested(); float[] scoreModelOutput = scoreModel.Predict(inputImage); cancellationToken.ThrowIfCancellationRequested(); ScoreOutput[] scores = GenerateScoreArray(scoreModelOutput); cancellationToken.ThrowIfCancellationRequested(); return scores; }, cancellationToken)); }
private Task <CAM[]> GetCAMs(SKBitmap inputImage, CancellationToken cancellationToken) { return(Task.Factory.StartNew(() => { cancellationToken.ThrowIfCancellationRequested(); float[] camModelOutput = camModel.Predict(inputImage); cancellationToken.ThrowIfCancellationRequested(); CAM[] cams = GenerateCAMArray(camModelOutput); cancellationToken.ThrowIfCancellationRequested(); return cams; }, cancellationToken)); }